赤外線LEDを積んだRaspberry Piでスマートルームをつくる(chatbot実装編)

この記事は赤外線LEDを積んだRaspberry Piでスマートルームをつくる(実装編)の続きです。

ハードウェアを実装してソフトウェアの世界に持ち込めばこっちのもの。
というわけでこの記事では製作した赤外線リモコンを操作したり環境情報を取得できるようにしていきたいと思います。

エアコンのリモコン信号をつくる

まずは赤外線リモコンの信号を解析する記事で得られた結果をもとにエアコン用の信号を作っていきます。

解析に利用したirrp.pyがPython製なのでPythonでスクリプトを作成します。

解析した内容に対するパラメータからデータを生成し、それをパルスの継続時間のシーケンスに変換して再生してもらう形で実装したソースが以下になります。

クラス内ではカスタマーコードを[17, 218, 7]と記述していますが最後の7はパリティ(4bits)です。結局固定値なのでサボりました。codeメソッド内での変数dataは0番目以外は8ビット整数としてデータを入れています。

今回エアコンの制御をするために以下のパラメータを用意しました。

  • 運転ON/OFF
  • 運転モード(自動/冷房/暖房/ドライ/送風)
  • 設定温度(自動: -5~+5度, 冷房: 18~32度, 暖房: 14~30度, ドライ: -2~+2度)
  • 送風強さ(0~5, ただし-1ならば自動)
  • スイングON/OFF

これを上記スクリプトのcodeメソッドで指定することでデータ部分のパルス列を生成します。実際に利用する際にはAEHAフォーマットに合わせるためにpackメソッドを経由してフレームとして変換したものを送出します。このpackメソッドでは、先行している固定フレームも合わせて符号化しています。

APIの作成

Raspberry Pi上でリクエストを待ち受けるAPIを作ります。

サーバ用フレームワークにはbottleを採用しています。赤外線LEDの方はirrp.pyを参考にしながら信号を生成するように、温度センサはスイッチサイエンスさんのサンプルを参考に値を取得するように改変して組み込んだ上でAPIへのアクセスに応じて呼び出す形で実装しました。

エアコン操作用のエンドポイントではリクエストフォームにworkが定義されているか否かで運転のON/OFFを指定します。
このときの赤外線信号の送出に使うGPIOピンの番号はIR_WRITE_PIN環境変数で指定します。

APIのソース一式は以下のリポジトリにアップロードしています。

https://github.com/paralleltree/myroom

動作確認

スクリプトを保存したら起動してみます。

 $ IR_WRITE_PIN=19 python3 server.py

実際に温度センサのエンドポイントを叩いてみた結果がこちらです。

file

温度、湿度、気圧の測定値が得られていることがわかります。
同様にエアコン操作用のエンドポイントを叩いた結果がこちらです。

file

このレスポンスでは赤外線信号を送出した事実しかわからないので外出時には正常にエアコンまで届いたか判別できませんが、温度センサを活用しつつ運用でカバーしていくことにしました。

botの作成

トークンの取得

APIができたので続いてSlack上で対話するbotを作成していきます。まずはSlackのCustom IntegrationsからBot用のアクセストークンを取得します。

file

file

スクリプトの作成

トークンを取得したらRubyでslack-ruby-clientを使ってbotを作っていきます。Gemfileはこんな感じ。

source "https://rubygems.org"

gem 'slack-ruby-client'
gem 'async-websocket'
gem 'eventmachine'
gem 'faye-websocket'

スクリプトではSlackサーバへの接続設定を行った後にDMへ流れてくるメッセージを順次処理していきます。
単純なパターンマッチングに引っかけて対応するイベントを発火させるだけの人工無能ですが以下のような感じになります。
API_BASE環境変数には先ほどbottleを使って建てたAPIのエンドポイントを指定します。
今回はRaspberry Pi上で動作させるのでhttp://localhost:8080になります。

動作テスト

スクリプトを保存したら動作を確認します。

 $ IR_WRITE_PIN=19 python3 server.py &
 $ bundle install --path vendor/bundle
 $ API_BASE="http://localhost:8080" SLACK_TOKEN="token" bundle exec ruby bot.rb

センサとLEDのAPIを先にバックグラウンドで立ち上げてからbotスクリプトを実行します。

Slackのサーバと接続が確立できたらチノちゃんに部屋の温度を聞いてみます。

続いてエアコンを入れてもらいます。

というわけで実際にチノちゃんから部屋の温度を聞いたりエアコンをつけてもらえるようになりました。エモい。

実際はsshのコネクションを張ったままにするわけにもいかないので、以下のようにcrontabでRaspberry Piの起動に合わせてサーバを立ち上げたりするといいでしょう。

@reboot sh -c 'cd repos/myroom && IR_WRITE_PIN=19 python3 server.py > /dev/null &'
@reboot sh -c 'cd repos/myroom && API_BASE="http://localhost:8080" SLACK_TOKEN="token" bundle exec ruby bot.rb > /dev/null &'

認証周り

今回はホームからSlackのサーバに接続したので自宅用のドメインやIPアドレスいらずで操作ができ、かつ「Slackにログインする」ことが実質的なユーザ認証となっています。特にAPIをパブリックに公開する場合はサーバ側でトークンなどを設定して認証を実装しないと第三者からエアコンをいじられかねないので注意が必要です。

まとめ

というわけでチノちゃんと同棲気分を味わえるようになりました!最高だな?

みなさんもぜひ嫁を錬成してみてください。

Leave a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です