概要
- ラズパイにOSインストール
- ラズパイ各種設定
- Slackからラズパイにメッセージ送信
- ラズパイにhubotインストール
- ラズパイで家電操作
- 赤外線モジュール設定
※インターネットへの接続環境が必要です
ラズパイ設定
まずネットからラズパイ用OSのイメージファイルをダウンロードします。公式からRaspbianのオールインワンみたいなのをダウンロードしました。市販のSD 32GBを「SD Card Formatter」でフォーマットして、「rufus-3.1」でダウンロードしたイメージを書込みます。あとは電源入れればOSのインストールが始まります。
※インストールはかなり長いです。
続いて必要なパッケージをインストールしていきます。
パッケージリスト更新
$ sudo apt-get update
Node.jsインストール
$ sudo apt-get install -y nodejs
$ node -v
v10.15.2
$ npm -v
5.8.0
nはバージョン管理をするためのもの
$ sudo npm install npm n -g
公式の最新バージョンをインストール
$ sudo n stable
最新バージョンにスイッチ
$ sudo n
再起動後
$ node -v
v12.16.2
ヨーマンインストール。Webアプリの雛形作成するやつ
$ sudo npm install yo -g
Hubotのためのヨーマンジェネレータ
$ sudo npm install generator-hubot -g
JavaScriptをrubyライクに記述出来る言語
$ sudo npm install coffee-script -g
hubot設定
$ pwd
/home/pi
$ mkdir hubot
$ cd hubot
$ mkdir remocon
$ cd remocon
hubotの作成
$ yo hubot
- Owner
- メールアドレス
- Bot name
- hubotの名前。「remoconbot」(任意)
- Description
- 説明文
- Bot adapter
- hubotのアダプタ。今回はSlack連携なので「slack」
終わったら動作確認をします。
hubot起動
$ bin/hubot
プロンプトが変わったらhubotにPINGを打ちます
remoconbot> remoconbot ping
remoconbot> PONG
Slack設定
Slack App ディレクトリから「Hubot」を追加します。Slackで表示させたい名前をユーザ名に入力、APIトークンが発行されるのでラズパイに接続して以下のように設定ファイルにコピペします。
$ vi /home/pi/hubot/bin/hubot
#!/bin/sh
set -e
npm install
export HUBOT_SLACK_TOKEN=【APIトークン】
export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH"
exec node_modules/.bin/hubot --name "remoconbot" "$@"
bin/hubot -a slack
を実行してSlackからさっき追加したユーザ宛てにPINGを打ってみてPONGと帰ってくれば成功です。 これでSlackとラズパイの連携が取れました。
赤外線モジュール設定
今回は赤外線リモコンアドバンスを使用します。ラズパイとUSBケーブルで繋ぎます。赤い四角で囲った部分が赤外線受信部です。ここに光を当てて学習させていきます。
販売サイトでは対応OSがWindowsとなっておりますが、Linux用のライブラリがGitHubに公開されています。
$ sudo apt install libusb-1.0.0
$ git clone https://github.com/Drunkar/bto_ir_advanced_cmd.git
$ cd bto_ir_advanced_cmd
$ make
$ sudo make install
$ bto_advanced_USBIR_cmd --help
※ヘルプが出れば成功
赤外線リモコンアドバンスは下記のコマンドで制御出来ます。自分は取り敢えず、YAMAHAのオーディオアンプの出力をAUDIO2に切り替えるボタンを覚えさせました。エアコンのリモコンとか大体何でも認識すると思います。
受信を開始。学習させたいリモコンのボタンを押下して赤外線をラズパイに覚えさせる
$ bto_advanced_USBIR_cmd -r
受信を停止
$ bto_advanced_USBIR_cmd -s
信号をファイルに書き出す
$ bto_advanced_USBIR_cmd -g | tee audio2.txt
信号を送信
$ bto_advanced_USBIR_cmd -d `cat audio2.txt`
Shellスクリプトを実行させる
scripts
ディレクトリにシェルスクリプト用のサブディレクトリを作り、その中にシェルスクリプト作成していきます。
$ cd /home/pi/hubot/remocon/scripts
$ mkdir shell
$ cat shell/audio2.sh
#!/bin/sh
bto_advanced_USBIR_cmd -d `cat audio2.txt`
Slackのチャットから上記のスクリプトを実行するためのHubotを作成します。
$ pwd
/home/pi/hubot/remocon/scripts
$ cat exec_shell.coffee
module.exports = (robot) ->
robot.respond /audio2/, (msg) ->
@exec = require('child_process').exec
cmd = "sh /home/pi/hubot/remocon/scripts/shell/audio2.sh"
msg.send "#{cmd} を実行しました。"
@exec cmd, (error, stdout, stderr) ->
if error
msg.send error
msg.send stderr
else
msg.send stdout
再度remoconbotの階層に移動しbin/hubot -a slack
を実行してから、Slackからボットにメッセージを送信します。
成功しました。アンプの出力が切り替わったり、エアコンが起動したりする筈です。以上です。
後日談
やりたかった事が実現出来てウキウキで色々なリモコンボタンを記憶させていたのは良かったのですが、数時間後remoconボットが死んでいることに気がつきました。どういう訳か一定時間操作がないとhubotがタイムアウトしてしまう事が原因なようです。
調べたところhubotをアップデートしたり、色々と方法があるようですが今回はpm2
というアプリケーション用プロセスマネージャーを使って落ちたら再読み込みする方法を実践したいと思います。pm2
はアプリケーションをダウン時間を発生させずに再起動し常駐させる事が出来ます。
pm2概要
今からする事はまずNode.jsの環境を準備する必要があるので、hubotを常駐させる方法だけが知りたいかたはpm2
のインストールだけ行ったら次のセクションを実践してください。
まずはpm2
のインストールからです。
$ sudo npm install pm2 -g
例としてわざとエラーになるサイトを作ってみます。
$ cat index.js
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n' + str);
}).listen(3000, '127.0.0.1');
これをnode index.js
で起動してアクセスするとページにはアクセス出来ず、コンソールにはReferenceError: str is not defined
というエラーになるかと思います。
ここでpm2を使ってみたいと思います。
$ pm2 start index.js --watch
何やらいかつい表が出てくるかと思います。その後ログを流してみます。
$ pm2 logs
恐らく先ほどと同様に変数strが定義されていませんという様なエラーが出るかと思います。そのままの状態で今一度ページを再読込みしてみて下さい。するとコンソールにエラ〜メッセージが繰り返し吐かれるかと思います。つまりエラーが発生すると勝手に再起動を行ってくれるのです。これを利用してhubotを起動すれば常駐させる事が出来ます。--watch
オプションをつける事でソース変更時にも再読込みが行われます。
pm2
のその他の操作は以下の通りです。
実行中のプロセス表示
$ pm2 list
アプリ停止
$ pm2 stop 0
アプリ再起動
$ pm2 restart 0
詳細情報取得
$ pm2 show 0
pm2レジストリからアプリ削除
$ pm2 delete 0
hubot改修
$ mv bin/hubot bin/hubot.sh
$ pm2 start -f bin/hubot.sh -x -- -a slack
- ファイル名を変える理由はよく分かりません。
- Node(js)ファイルじゃないから拡張子がいるのかもしれません。
-f 【ファイル名】 -x
- Node(js)以外を実行する場合
--
- 移行引数を記述
以上です。