Edited at

Raspberry Pi 3 とTypetalk HubotアダプターでシンプルIoT

More than 1 year has passed since last update.


Raspberry Pi 3 とTypetalk HubotアダプターでシンプルIoT


はじめに

"Raspberry Pi 3 で赤外線リモコン&温度センサーを試す" で接続した赤外線リモコン irMagician を使って、外出先から Typetalk でコマンドを送信するとエアコンや照明を操作するシンプルなIoTに挑戦します。


準備するもの



  • Typetalk で使用するヌーラボアカウント2つ。1つは自分用、もうひとつはコマンドに返事をする bot アカウント。


前提条件


  • "RaspberryPi 3 model B に CentOS7をインストール" が完了していること。

  • "Raspberry Pi 3 で赤外線リモコン&温度センサーを試す" でRaspberryPi 3 と irMagician のセットアップを終えていること。

  • rootユーザのほかに一般ユーザが存在し sudo コマンドが実行可能であること。

  • "まず、動くこと"を優先しているので、パラメータ調整は含まれていません。

  • Raspberry Pi 3 は、無線/有線LANに接続されていてインターネットに接続可能であること。(インターネットからRaspberry Pi 3に直接/間接的に接続する必要はありません。)


参考情報


Typetalk に bot アカウントを準備


Typetalk アカウントの作成

Typetalk のアカウントを持っていない場合は、ヌーラボアカウントの作成 からアカウントを作成できます。アカウント作成後、 Typetalk にログインします。


bot用アカウントの作成

いちどログアウトし、bot 用のアカウントを作成します。

このとき、bot用のアカウントのユニークIDは、 raspbotと登録したものとして進めます。

bot 用のアカウント作成後、自分用のアカウントで Typetalk にログインし、bot アカウントをトピックに招待します。


Typetalk bot の設定

bot 用アカウントをトピックに招待できたら、再び bot 用アカウントにログインしhubot 連携用の設定を行います。

設定画面で、連携用アプリケーションを登録します。


  1. 画面左下のアイコン(設定画面へのリンクボタン)をクリックし、設定画面に入ります。


  2. デベロッパーをクリックし、デベロッパー画面を開きます。

  3. 画面右上の新規アプリケーションをクリックしアプリケーション設定画面に入ります。


  4. アプリケーション名に任意の名称を入力します。ここでは、tbotと入力したものとして進めます。

  5. Grant TypeはClient Credentialsを選択します。


アプリケーションを登録すると、 Client IDClient Secretが表示されます。この2つはこの画面でいつでも確認可能です。後述の Raspberry Pi 3 で hubot を起動する際に使用します。


hubotのセットアップ

Raspberry Pi 3上で hubot をセットアップします。


node.jsをインストール

Raspberry Pi 3 のCPUモデル名を確認します。

# cat /proc/cpuinfo | grep 'model name'

model name : ARMv7 Processor rev 4 (v7l)
model name : ARMv7 Processor rev 4 (v7l)
model name : ARMv7 Processor rev 4 (v7l)
model name : ARMv7 Processor rev 4 (v7l)

https://nodejs.org/ja/download/ からARMv7用のバイナリをダウンロードし、/usr/local以下に配置します。

$ sudo curl --location https://nodejs.org/dist/v6.11.2/node-v6.11.2-linux-armv7l.tar.xz > ./node-v6.11.2-linux-armv7l.tar.xz

$ tar Jxfv node-v6.11.2-linux-armv7l.tar.xz
$ sudo mv node-v6.11.2-linux-armv7l /usr/local/node-v6.11.2-linux-armv7l
$ sudo ln -s /usr/local/node-v6.11.2-linux-armv7l /usr/local/nodejs

node.jsにパスを通します。

$ vi ~/.bash_profile

変更前

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin:

変更後

# User specific environment and startup programs

NODEJS_HOME="/usr/local/nodejs"
PATH=$PATH:$HOME/.local/bin:$HOME/bin:$NODEJS_HOME/bin:

バージョンを確認します。

$ node -v

v6.11.2
$ npm -v
3.10.10

npmをアップデートします。

$ npm update -g

$ npm -v
5.3.0


cofee scriptのインストール

Typetalk で入力したコマンドを受け取りRaspberry Pi 3 上で処理を行うための cofee script モジュールをインストールします。

$ npm install -g coffee-script

/usr/local/node-v6.11.2-linux-armv7l/bin/coffee -> /usr/local/node-v6.11.2-linux-armv7l/lib/node_modules/coffee-script/bin/coffee
/usr/local/node-v6.11.2-linux-armv7l/bin/cake -> /usr/local/node-v6.11.2-linux-armv7l/lib/node_modules/coffee-script/bin/cake
+ coffee-script@1.12.7


hubotのインストール

yoとgenerator-hubotをインストールします。

$ npm install -g yo generator-hubot

次に、hubot をインストールします。

$ mkdir -p hubot

$ cd hubot
$ yo hubot
_____________________________
/ \
//\ | Extracting input for |
////\ _____ | self-replication process |
//////\ /_____\ \ /
======= |[^_/\_]| /----------------------------
| | _|___@@__|__
+===+/ /// \_\
| |_\ /// HUBOT/\\
|___/\// / \\
\ / +---+
\____/ | |
| //| +===+
\// |xx|

? Owner User <user@example.com> (Enter)
? Bot name tbot (任意の名称。Typetalk上で作成したアプリケーション名 tbot とします。)
? Description A simple helpful robot for your Company (何も入力せずにEnter)
? Bot adapter typetalk (Typetalk アダプターを指定します。)
create bin/hubot
create bin/hubot.cmd
create Procfile
create README.md
create external-scripts.json
create hubot-scripts.json
create .gitignore
create package.json
create scripts/example.coffee
create .editorconfig
_____________________________
_____ / \
\ \ | Self-replication process |
| | _____ | complete... |
|__\\| /_____\ \ Good luck with that. /
|//+ |[^_/\_]| /----------------------------
| | _|___@@__|__
+===+/ /// \_\
| |_\ /// HUBOT/\\
|___/\// / \\
\ / +---+
\____/ | |
| //| +===+
\// |xx|

npm WARN deprecated connect@2.30.2: connect 2.x series is deprecated
npm WARN deprecated node-uuid@1.4.8: Use uuid module instead

> ws@0.4.32 install /home/tsuyoshi/hubot/node_modules/ws
> (node-gyp rebuild 2> builderror.log) || (exit 0)

make: Entering directory `/home/tsuyoshi/hubot/node_modules/ws/build'
CXX(target) Release/obj.target/bufferutil/src/bufferutil.o
make: Leaving directory `/home/tsuyoshi/hubot/node_modules/ws/build'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN hubot-help@0.2.2 requires a peer of coffee-script@^1.12.6 but none was installed.

+ hubot-google-images@0.2.7
+ hubot-heroku-keepalive@1.0.3
+ hubot-diagnostics@0.0.2
+ hubot-scripts@2.17.2
+ hubot@2.19.0
+ hubot-maps@0.0.3
+ hubot-google-translate@0.2.1
+ hubot-pugme@0.1.1
+ hubot-redis-brain@0.0.4
+ hubot-help@0.2.2
+ hubot-rules@0.1.2
+ hubot-shipit@0.2.1
+ hubot-typetalk@0.2.3

様々なモジュールがインストールされました。

$ ls

Procfile bin hubot-scripts.json package-lock.json scripts
README.md external-scripts.json node_modules package.json


coffee scriptを用意する。

Typetalk 上で、botに送ったコマンドに反応する処理を coffee script で実装します。

hello と送信すると、Hi!もしくはスマイルの絵文字:smile:で返事をするサンプルです。

$ vi ./script/example.coffee

module.exports = (robot) ->

hello = ['Hi!',':smile:']

robot.hear /hello/i, (res) ->
res.send res.random hello


hubotを起動してみる

hubotを起動して、さきほどの coffee script を試してみます。

$ ./bin/hubot

tbot> [Sun Aug 13 2017 03:24:14 GMT+0900 (JST)] WARNING Loading scripts from hubot-scripts.json is deprecated and will be removed in 3.0 (https://github.com/github/hubot-scripts/issues/1113) in favor of packages for each script.

Your hubot-scripts.json is empty, so you just need to remove it.
[Sun Aug 13 2017 03:24:15 GMT+0900 (JST)] ERROR hubot-heroku-keepalive included, but missing HUBOT_HEROKU_KEEPALIVE_URL. `heroku config:set HUBOT_HEROKU_KEEPALIVE_URL=$(heroku apps:info -s | grep web.url | cut -d= -f2)`
[Sun Aug 13 2017 03:24:17 GMT+0900 (JST)] INFO hubot-redis-brain: Using default redis on localhost:6379
(ここでEnterを押さないとプロンプトが表示されないので注意)
tbot>

tbotに hello と話しかけてみると、Hi! もしくは :smile:と返事をしてくれます。

2種類の返事はランダムに返されるので、何度か helloを繰り返すと両方出力されるはずです。

この画面では、絵文字は表示できないので文字で:smile:と返されます。

終了するときは exit と入力する。

tbot> hello

tbot> Hi!

tbot> hello
tbot> :smile:

tbot> exit


redis-serverのインストール

redis-serverをインストールします。

$ sudo yum -y install gcc make tcl

$ wget http://download.redis.io/releases/redis-3.2.9.tar.gz
$ tar xzvf redis-3.2.9.tar.gz
$ cd redis-3.2.9
$ make
$ make install

redis-serverを起動します。

$ redis-server & 


Typetalk と連携する

いよいよ  Typetalk  との連携設定を行います。

Typetalkアプリケーションの環境変数を設定し hubot を起動します。

変数名

HUBOT_TYPETALK_CLIENT_ID
Typetalk アプリケーションの Client ID

HUBOT_TYPETALK_CLIENT_SECRET
Typetalk アプリケーションの Client Secret

HUBOT_TYPETALK_ROOMS
hubotを使用するTypetalk上のトピックID

Client ID と Client Secretは、 https://typetalk.in/my/develop/applications にアクセスし、作成したTypetalkアプリケーション名をクリックすることで表示されます。

HUBOT_TYPETALK_ROOMS は、

https://typetalk.in/topics/xxxxx の xxxxx部分です。 bot 用のTypetalkアカウントを招待したトピックを開いた際のURLに該当します。

これらの環境変数を export し、Typetalk アダプターを使用して hubot を起動します。

実際に運用する場合は、hubot を起動するユーザの .bash_profile などに環境変数を定義しておきます。

$ export HUBOT_TYPETALK_CLIENT_ID='xxxxxxxxxxxxxxxxxxxxx'

$ export HUBOT_TYPETALK_CLIENT_SECRET='xxxxxxxxxxxxxxxxxxxxx'
$ export HUBOT_TYPETALK_ROOMS='xxxxxx'
$ ./bin/hubot -a typetalk

[Sun Aug 13 2017 05:24:11 GMT+0900 (JST)] INFO Typetalk WebSocket connected


Typetalk bot から hubot を呼び出す

@raspbot hello

Hi! もしくは スマイルの絵文字で返事が返ってきました。


irMagician と連携してリモコンを操作する。

ターミナルで以下のようになっているので、Ctlr + C で終了させます。

[Sun Aug 13 2017 05:24:11 GMT+0900 (JST)] INFO Typetalk WebSocket connected

学習させたリモコン操作の呼び出しや温度計測を実行するように、example.coffeeを以下のように変更し、保存します。詳細は、 "Raspberry Pi 3 で赤外線リモコン&温度センサーを試す" を参照。

air_on.jsonair_off.json はそれぞれエアコンをON/OFFにする操作を学習した結果を出力したJSONファイルです。

/PATH/TO/irmcli/irmcli.py は irmcli.py がある場所を絶対パスで指定します。

$ vi ./script/example.coffee

example.coffeeの内容

module.exports = (robot) ->

robot.hear /temperature/i, (msg) ->
@exec = require('child_process').exec
command = "sudo python /PATH/TO/irmcli/irmcli.py -t"

@exec command, (error,stdout, stderr) ->
msg.send stdout

robot.hear /aircon on/i,(msg) ->
@exec = require('child_process').exec
command = "sudo python /PATH/TO/irmcli/irmcli.py -p -f /PATH/TO/irmcli/air_on.json"

@exec command, (error,stdout, stderr) ->
msg.send stdout

robot.hear /aircon off/i,(msg) ->
@exec = require('child_process').exec
command = "sudo python /PATH/TO/irmcli/irmcli.py -p -f /PATH/TO/irmcli/air_off.json"

@exec command, (error,stdout, stderr) ->
msg.send stdout

hubot を起動します。

$ ./bin/hubot -a typetalk

以下のコマンドを hubot に送ります。

@raspbot temperature

@raspbot aircon on

@raspbot aircon off

実行結果を得ることができました。


テレビを操作するサンプル

上記はエアコンの例ですが、テレビも操作することができました。


実行結果

ここで得られるirMagicianからの結果は、あくまでもコマンド自体の実行結果であり、その先のエアコン等が意図したとおりに動作したかはわかりません。

赤外線が届いたかどうかもわかりません。

エアコンは結果を返してくれないし、返ってきたところで受け取る仕組みがありません。

そういう意味では、シンプルIoTということになります。

Typetalkはインターネット上のサービスなので、hubot 連携することで外出先からでもRaspberry Pi 3 上で上記のようなコマンドを実行することが可能です。

相手の状態を得られるような実装を行えば、より現実的なIoTが楽しめそうです。