Top/Devel/電子工作/RaspberryPi/ホームオートメーションシステム

ホームオートメーションシステムはてなブックマーク

homeautomation.jpg

Raspberry Piで作った日本語音声認識システム赤外線学習リモコンシステムを組み合わせて、声で家電を操作できるようにします。

いわゆるホームオートメーションシステム、あるいはホームコントローラーと呼ばれるような仕組みです。

最近で言えば、鬼奴が帰らないことで有名なやつですね。

必要なもの

手順

赤外線リモコン信号の学習

ホームオートメーションシステムで操作したい機器の赤外線リモコン信号を学習させます。


方法は 赤外線学習リモコン をご覧ください。

Juliusの設定と起動

ホームオートメーションシステムに必要な最小限の単語辞書を作って、大語彙連続音声認識エンジン Juliusを起動します。


各手順の詳細は 日本語音声認識 をご覧ください。


  1. 単語辞書の元を作ります。単語と読みをタブ区切りで書きます。
    nano ~/homeautomation.yomi
    テレビ電源	てれびでんげん
    テレビ点けて	てれびつけて
    テレビ消して	てれびけして
    テレビ音量UP	てれびあっぷ
    テレビ音量DOWN	てれびだうん
    レコーダー点けて	れこーだーつけて
    レコーダー消して	れこーだーけして
    NHK総合	えぬえっちけー
    NHK総合	えぬえいちけー
    NHK総合	そーごー
    NHK教育	きょーいく
    日本テレビ	にほんてれび
    日本テレビ	にってれ
    テレビ朝日	てれびあさひ
    テレビ朝日	てれあさ
    TBS	てぃーびーえす
    テレビ東京	てれびとーきょー
    テレビ東京	てれとー
    フジテレビ	ふじてれび
    コンポ電源	こんぽでんげん
    コンポ点けて	こんぽつけて
    コンポ消して	こんぽけして
    コンポ音量UP	こんぽあっぷ
    コンポ音量DOWN	こんぽだうん
    コンポCD再生	しーでぃーさいせー
    コンポMD再生	えむでぃーさいせー
    コンポ停止	ていし
    電気点けて	でんきつけて
    電気消して	でんきけして
    エアコン点けて	えあこんつけて
    エアコン消して	えあこんけして
    鬼奴帰って	おにやっこかえって
  2. 次にこれを単語辞書形式に変換します。
    cd ~/julius-4.2.3/gramtools/yomi2voca
    iconv -f utf8 -t eucjp ~/homeautomation.yomi | ./yomi2voca.pl > ~/julius-kits/dictation-kit-v4.2.3/homeautomation.dic
  3. 変換した辞書を使用する設定ファイルを作成します。今回はJuliusの認識結果を外部から利用したいので、モジュールモードで起動するようにします。
    nano ~/julius-kits/dictation-kit-v4.2.3/homeautomation.jconf
    -w homeautomation.dic
    -v model/lang_m/web.60k.htkdic
    -h model/phone_m/hmmdefs_ptm_gid.binhmm
    -hlist model/phone_m/logicalTri
    -n 5
    -output 1
    -input mic
    -zmeanframe
    -rejectshort 800
    -charconv EUC-JP UTF-8
    -module
  4. この設定ファイルを使ってモジュールモードでjuliusを実行します。
    julius -C ~/julius-kits/dictation-kit-v4.2.3/homeautomation.jconf

制御スクリプトの作成

ホームオートメーションシステムを司る部分を作ります。


irsendコマンドの詳細は 赤外線学習リモコン をご覧ください。


  1. 下記の内容のスクリプトを作成する。
    (ネタ元は KURO-RSとJuliusで家電をコントロールしてみた : アシアルブログ です。)
    caseに書く文字列は単語辞書と合わせましょう。
    nano ~/homeautomation.pl
    #!/usr/bin/perl
    use Switch;
    use Socket;
    socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die;
    connect(SOCK, sockaddr_in(10500, inet_aton('localhost'))) || die;
    $str = '';
    while(1) {
        recv(SOCK, $message, 30, MSG_WAITALL);
        $str .= $message;
        if ($str =~ /\./) {
            print $str;
            switch($str) {
                case /テレビ電源|テレビ点けて|テレビ消して/ {
                    system("irsend SEND_ONCE EUR511451 power");
                }
                case /テレビ音量UP/ {
                    system("irsend SEND_ONCE EUR511451 volup");
                }
                case /テレビ音量DOWN/ {
                    system("irsend SEND_ONCE EUR511451 voldown");
                }
                case /レコーダー点けて|レコーダー消して/ {
                    system("irsend SEND_ONCE RMT-B007J power");
                }
                case /NHK総合/ {
                    system("irsend SEND_ONCE RMT-B007J 1");
                }
                case /NHK教育/ {
                    system("irsend SEND_ONCE RMT-B007J 2");
                }
                case /日本テレビ/ {
                    system("irsend SEND_ONCE RMT-B007J 4");
                }
                case /テレビ朝日/ {
                    system("irsend SEND_ONCE RMT-B007J 5");
                }
                case /TBS/ {
                    system("irsend SEND_ONCE RMT-B007J 6");
                }
                case /テレビ東京/ {
                    system("irsend SEND_ONCE RMT-B007J 7");
                }
                case /フジテレビ/ {
                    system("irsend SEND_ONCE RMT-B007J 8");
                }
                case /コンポ電源|コンポ点けて|コンポ消して/ {
                    system("irsend SEND_ONCE RAK-SC972WK power");
                }
                case /コンポ音量UP/ {
                    system("irsend SEND_ONCE RAK-SC972WK volup");
                }
                case /コンポ音量DOWN/ {
                    system("irsend SEND_ONCE RAK-SC972WK voldown");
                }
                case /CD再生/ {
                    system("irsend SEND_ONCE RAK-SC972WK playcd");
                }
                case /MD再生/ {
                    system("irsend SEND_ONCE RAK-SC972WK playmd");
                }
                case /停止/ {
                    system("irsend SEND_ONCE RAK-SC972WK stop");
                }
                case /電気点けて/ {
                    # まだ学習できてない
                }
                case /電気消して/ {
                    # まだ学習できてない
                }
                case /エアコン点けて/ {
                    # まだ学習できてない
                }
                case /エアコン消して/ {
                    # まだ学習できてない
                }
                case /鬼奴帰って/ {
                    # 帰らない
                }
            }
            $str = '';
        }
    }
    # SOCKET切断
    close(SOCK);
  2. 作成したスクリプトを起動します。
    ~/homeautomation.pl
  3. マイクに向かってhomeautomation.dicに登録した単語を言うと、単語がターミナルに表示された後、homeautomation.plに記述した赤外線送信コマンドが実行され、機器が操作されます。

Raspberry Pi起動時にJuliusと制御スクリプトが起動するようにする

  1. 起動スクリプトを作成する。
    nano homeautomation
    #!/bin/sh
     
    ### BEGIN INIT INFO
    # Provides: homeautomation
    # Required-Start: $local_fs $network
    # Required-Stop:
    # Default-Start: 2 3 4 5
    # Default-Stop: 0 1 6
    # Description: Start or stop homeautomation.pl
    ### END INIT INFO
     
    /usr/local/bin/julius -C /home/pi/julius-kits/dictation-kit-v4.2.3/homeautomation.jconf &
    sleep 2
    /usr/bin/perl /home/pi/homeautomation.pl &
  2. 登録する。
    chmod a+x homeautomation
    sudo mv homeautomation /etc/init.d/
    sudo insserv homeautomation

関連

トラブルシューティング

誤認識率が高い

以下を試してみましょう。

  • amixerでマイク感度を調整する
  • homeautomation.jconfのlvオプションでマイク感度を調整する
  • 単語辞書の単語量を減らす
  • 単語辞書の単語の読みが被らないようにする
  • 音声コマンドにプレフィックスをつける。(「R2-D2!」とか。)

そもそもRaspberry Piとか持ってないんだけど…

そんなあなたのために既製品があります。

参考

Amazon

差分 一覧