AWS IoTを使った自作もの第二弾です。
第一弾のIoT Buttonを自作してみたと同様にRaspberry Pi上で使用するユーザは全権限を持ったrootユーザを想定してます。
また、IoT Buttonを自作してみたではshellを使用しましたが今回はSDKが用意されているJavaScriptを使用します。
ところで、AWS IoT Thing Shadowってなんだっけ?
なんだか長い名前だし、名前からは全くイメージがつかない。。。
AWS IoT Thing Shadowというのは、AWS IoTの中の一つの機能と思うとよいです。なぜShadow(影)なのかというと、モノの状態をココに格納しておけるからなのです。
具体的に言うと、例えば、モノにLEDがついていて、それを点灯するという指示をプログラミングするとすると、クラウドとモノを直接つないで指示をだすという流れになりますよね?
でも、モノとクラウドの間は必ずしも安定的なネットワークでつながれているとは限りません。なので、例えばネットワークが切れている状態で、クラウドから指示を出そうとすると失敗する。
その後、ネットワークが回復してモノとクラウドがつながったとする。
クラウドからすれば、指示はだした後なので、切れていた時の指示を実行しようと思うと、つながったことを認識して再度指示をだすという流れになります。
これを実際にやるには、一定期間ごとにモノとクラウドがつながったかどうかを確認して、つながったら再度指示を出す・・・と、かなりめんどくさいですよね。
しかも、IoTだとこの「モノ」が数百、数千、数万だったりするので、全部の接続状態を確認して、エラー処理を実行するなんてとんでもなくめんどくさいです。
そこで、このThing Shadowが登場するのですが、Thing Shadowは、最後のデバイスから来た状況(例えば、今の温度は19℃です)と、最後のクラウドから来た指示(例えば、10℃を切ったら暖房をいれてね)という状態をモノ単位で維持してくれるのです。しかも、バージョン付きで。なので、上に書いたようなめんどくさい処理がいらなくなります。
今回のつくるものの例だと、AWS IoTのコンソールから、LEDをつけろという指示をします。そうすると、指示はThing Shadowにたまります。モノ側には、Thing Shadowが指示をリレーするのだけど、もし、ネットワークが切れいている場合、復旧したら自動的に指示を出してくれます。
もちろん、バージョンの番号や指示の内容、モノの状況に応じて処理をどうするかは、クラウド側にもモノ側にもプログラムできます。
どうですか?とっても便利ですよね。
今回実装したモノ
というわけで、今回はわざわざモノとクラウドの間のネットワークを切ったりはしていないのですが、Thing Shadowを使ってモノ側のLEDを点灯させるということを自作してみました。
処理の流れは下の図のようです。
実装の手順は、
Ⅰ.Raspberry Piのデバイスの作成
- 電子工作
- Raspberry Pi上コマンドラインでLEDが動作するかを確認します
Ⅱ.Node.jsのインストール
- nodebrewをインストール
- Node.jsをインストール
- Nodeコマンドの動作確認
Ⅲ.AWS IoT Device SDKのインストール
Ⅳ.AWSマネージメントコンソールでThing shadowの準備
- AWS IoTの管理画面にアクセスします
- Thingを作成します
- デバイスに割り当てたCertificateにLedFlashを紐付けます
Ⅴ.Raspberry Piの設定
- JavaScriptファイルを作成します
- LEDの動作準備
Ⅵ.動作確認
- 作成したiot_thing_led.jsを実行します
- LEDライトを点灯させる
- LEDライトを消灯させる
- 動作確認が終了したら、GPIOを開放します
Ⅰ.Raspberry Piのデバイス作成
IoT Buttonを目標としているため、IoT Buttonを自作してみた-①から拡張する形でLEDを付けております。
用意したもの
- 赤色LED
- ジャンパーワイヤー(オス-メス) × 2
電子工作の手順
- LEDはカソード(足が短い)をブレッドボード: – (マイナス)/アノード(足が長い)をブレッドボード:a列の20
- ジャンパーワイヤー黒はRaspberry:GPIO5/ブレッドボード:c列の20
- ジャンパーワイヤー黄色はGND/ブレッドボード: – (マイナス)
1.Raspberry Pi上コマンドラインでLEDが動作するかを確認します
①LEDライトを使うGPIO05ピンを宣言します
# echo 5 > /sys/class/gpio/export
②ディレクトリの移動します
# cd /sys/class/gpio/gpio5
③Outputとして使用することを宣言します
# echo out > direction
④valueを1にして光ることを確認します
# echo 1 > value
⑤valueを2にして消えることを確認します
# echo 0 > value
⑥GPIO05ピンを解放します
# echo 5 > /sys/class/gpio/unexport
これで動作確認は終了です。
Ⅱ.Node.jsのインストール
1.nodebrewをインストール
①curlを使ってインストールします
# curl -L git.io/nodebrew | perl – setup
②環境変数ファイルをテキストエディタ(本記事ではviを使用しています)で開く
# vi ~/.bashrc
③環境変数PATH設定を追加します
export PATH=$HOME/.nodebrew/current/bin:$PATH
④設定ファイルの再読み込み
# source ~/.bashrc
2.nodeをインストール
①node.js(バージョン0.12.7)をインストール
# nodebrew install v0.12.7
②使用するnodeのバージョンを指定
# nodebrew use v0.12.7
3.nodeコマンドの動作確認
動作することを確認します。
# node -v
v0.12.7
と返ってくれば完了です。
Ⅲ.AWS IoT Device SDKのインストール
Raspberry Pi にaws Iot devise SDK をインストールします。
インストール方法は https://github.com/aws/aws-iot-device-sdk-js を参照してください。
今回は、npm install aws-iot-device-sdk はうまく動作しなかったため、下記コマンドでのインストールを行いました。
# git clone https://github.com/aws/aws-iot-device-sdk-js.git # cd aws-iot-device-sdk-js # npm install mqtt # npm install blessed # npm install blessed-contrib
aws-iot-device-sdk-js を node_modules/ 内に移動しておきます。
# mv aws-iot-device-sdk-js node_modules/
Ⅳ.AWSマネージメントコンソールでThing shadowの準備
1. AWS IoTの管理画面にアクセスします
Amazon Web ServiceマネージメントコンソールのIoTをクリックします。
2. Thingを作成します
”Create a thing”ボタンをクリックし、Nameを入力し、”Create” をクリックします。
ここでは、以下の設定を入力します。
- Name: LedFlash
3.デバイスに割り当てたCertificateにLedFlashを紐付けます
IoT Buttonを自作してみた-①のⅡ-4-2で作成したデバイス認証のためのCertificateを選択し(チェックを入れる)、Actionsの “Attach a thing” をクリックします。
今回作成した「LedFlash」を入力し、”Attach” をクリックすると、CertificateとThingの紐付けが完了します。
“LedFlash” が追加されていることを確認してください。
※リロードしないと表示されない場合がありますのでご注意ください。
thing「LedFlash」の初期状態を設定します。まず、thingのLedFlashの名前をクリックすると、右ペインにLedFlashの詳細情報が表示されます。
“Update State”をクリックすると初期状態が以下のように表示されます。
今回使用する変数(flash)と値(0: OFF)をdesiredとreportedに設定します。
desired, reportedは文字通りの意味で、desiredはデバイスに対し期待される値、reportedがデバイスから知らせられた値を意味します。
{ "desired": { "flash": 0 }, "reported": { "flash": 0 } }
下記の画面のように入力し、右下にある “Update State”ボタンをクリックします。
設定が成功すると、以下のようにstateが更新されます。
これでAWS IoT側の設定は完了です。
※このあと、Update State はまた使用しますのでこのままにしておきます。
Ⅴ.Raspberry Piの設定
1.JavaScriptファイルを作成します。
IoT Buttonを自作してみた-①にて iot_button.sh を作成したフォルダに今回は iot_thing_led.js を作成します。
内容は以下のようになっています。
var awsIot = require('aws-iot-device-sdk'); var fs = require('fs'); var thingShadows = awsIot.thingShadow({ keyPath: 'keys/***********-private.pem.key', certPath: 'keys/**********-certificate.pem.crt', caPath: 'keys/aws-iot-rootCA.crt', clientId: 'LedFlash', region: 'us-west-2' }); var clientTokenGet, clientTokenUpdate; thingShadows.on('connect', function() { thingShadows.register( 'LedFlash' ); setTimeout( function() { clientTokenGet = thingShadows.get('LedFlash'); }, 2000 ); }); thingShadows.on('status', function(thingName, stat, clientToken, stateObject) { console.log('received '+stat+' on '+thingName+': '+ JSON.stringify(stateObject)); }); thingShadows.on('delta', function(thingName, stateObject) { // LED ON/Off var state = stateObject.state.flash; fs.writeFileSync('/sys/class/gpio/gpio5/value', state); console.log('received delta '+' on '+thingName+': '+ JSON.stringify(stateObject)); clientTokenUpdate = thingShadows.update('LedFlash', {"state":{"reported": {"flash": state}}}); }); thingShadows.on('timeout', function(thingName, clientToken) { console.log('received timeout '+' on '+operation+': '+ clientToken); });
2.LEDの動作準備
①LEDライトを使うGPIO05ピンを宣言します
# echo 5 > /sys/class/gpio/export
②Outputとして使用することを宣言します
# echo out >/sys/class/gpio/gpio5/direction
Ⅵ.動作確認
1.作成したiot_thing_led.jsを実行します
# node iot_thing_led.js
以下のように表示されれば、接続成功です。
received accepted on LedFlash: {"state":{"desired":{"flash":1},"reported":{"flash":1}},"metadata":{"desired":{"flash":{"timestamp":1446014478}},"reported":{"flash":{"timestamp":1446014478}}},"timestamp":1446015500}
2.LEDライトを点灯させる
Ⅳ.AWSマネージメントコンソールで Thing shadow の準備で使用していたブラウザーに戻り、Update State で desired の flash を以下のように書き換え、”Update State”ボタンをクリックします。
Detail 画面が表示され、stateが以下のように表示され、Raspberry Pi のLEDライトが点灯します。
ターミナルには、
received delta on LedFlash: {"timestamp":1446015997,"state":{"flash":1},"metadata":{"flash":{"timestamp":1446015997}}} received accepted on LedFlash: {"state":{"reported":{"flash":1}},"metadata":{"reported":{"flash":{"timestamp":1446015997}}},"timestamp":1446015997}
が出力されます。
3.LEDライトを消灯させる
Update State でdesiredのflashを以下のように書き換え、”Update State”ボタンをクリックします。
Detail 画面が表示され、stateが以下のように表示され、Raspberry Pi のLEDライトが消灯します。
ターミナルには、
received delta on LedFlash: {"timestamp":1446016135,"state":{"flash":0},"metadata":{"flash":{"timestamp":1446016135}}} received accepted on LedFlash: {"state":{"reported":{"flash":0}},"metadata":{"reported":{"flash":{"timestamp":1446016135}}},"timestamp":1446016135}
が出力されます。
4.動作確認が終了したら、GPIOを開放します
LEDライトで使用していたGPIO05ピンを解放します
# echo 5 > /sys/class/gpio/unexport
Ⅶ.感想
node.jsのlatest(最新)を入れて AWS IoT Device SDK のインストールが失敗してしまい、ハマりましたが、AWS IoTは簡単操作でとても便利です。
今回はAWS コンソールからの書き換えでのRaspberry Pi LEDの操作までになりましたが、パソコンから操作する方法も試してみたいと思っております。
無料メルマガ会員に登録しませんか?
IoTNEWS技術チームです。IoTを取り巻く技術を検証したり、いろいろ作ってみたりします。お仲間も募集しています!