AWS IoTでMQTTプロトコルを使用したNode.js, iOS(Swift)の疎通サンプルがあります。
2016年11月現在動作確認済み。AWS IoT自体は昨年にリリースされて記事自体も昨年書いたものですが、備忘録として残しておきます。
2016年11月現在動作確認済み。AWS IoT自体は昨年にリリースされて記事自体も昨年書いたものですが、備忘録として残しておきます。
Amazon IoTってなに?
ハードウェアをサポートするバックエンドの仕組みをAWSに素早く、簡単に構築できるクラウドサービス。インターネットに接続されたデバイスとデバイスをつなぎ、安全な双方向性通信を提供。
- MQTT v3.1.1
- QoS 0, 1に対応(2には対応していない)
- Will, Retainに対応していない →Thing Shadowという状態を検知する仕組みがあるので不要ということ。
- Payloadサイズ128KB
- TLS対応
- WebSocket、WebSecureSocket対応あり(2016/1/28のアップデートにて)https://aws.amazon.com/jp/about-aws/whats-new/2016/01/aws-iot-now-supports-websockets-custom-keepalive-intervals-and-enhanced-console/
- 認証, AWSアカウントで
プロトコルはMQTT
- TCP/IP 上で動作するpublish/subscribeモデルに基づく軽量なメッセージプロトコル。
- 軽量メッセージ配信に特化しており、センサーデータなどに使用される(M2M)、
- Facebook MessengerもMQTT
- 256メガバイトが最大
- 固定長ヘッダーが最小2バイトとオーバーヘッドが少なく、またプロコトルも単純です。そのため、HTTPに比べるとネットワーク帯域および処理速度に優れています。また、処理が少ないということで、消費電力も少なくなっており、モバイル機器にも向いている
キーワード
Topic、QoS、Device gateway, Registry, Thing Shadow, Rules
Getting Started
まずはコンソール上でpub/sub
OSS,MQTT実装のmosquittoクライアントをインストール
npm install mqtt
AWS CLI のアップグレード
IoT Message Broker を操作するには AWS CLI 1.8.12 以上が必要
sudo pip install awscli --upgrade
認証関連
cert.json というファイル名で保存
aws iot create-keys-and-certificate --set-as-active > cert.json
jqコマンドがなければ
brew install jq
各情報を保存
cat cert.json | jq .keyPair.PublicKey -r > thing-public-key.pem
cat cert.json | jq .keyPair.PrivateKey -r > private-key.pem
cat cert.json | jq .certificatePem -r > cert.pem
ルートCAをシマンテックサイトから取得
curl -o rootCA.pem https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem
IAM Roleの設定
MQTT ブローカーに pub/sub するための IAM Role を Certification に設定
iot サービスを操作できる "PubSubToAnyTopic" という名前のポリシーを作成
iot サービスを操作できる "PubSubToAnyTopic" という名前のポリシーを作成
以下jsonファイルを作成
ポリシーをプリンシパルにひも付けます。 プリンシパルとなるのは aws iot create-keys-and-certificateコマンドを実行した時の certificateArn です
aws iot attach-principal-policy --principal "arn:aws:iot:ap-northeast-1:1111111:cert/SNIP" --policy-name "PubSubToAnyTopic"
準備完了
pub/sub通信が出来る状態となりました。
MQTT エンドポイントの確認
aws iot describe-endpoint
でAWSアカウントごとに異なるエンドポイントの確認Subscribe
Publish
確認
Subscribe側でHello, Worldの確認
とpublishした後、メッセージが
Hello, World
と表示されていればOKです。Node.jsでやってみる
AWS IoT SDK for JavaScriptのインストール
npm install aws-iot-device-sdk
先ほどのmqtt.jsのラッパーでクライアントインスタンスを経由して、
デバイスとAWS IoTをセキュアに接続します。mqttを意識することなく使えます。
deviceクラスとthingShadowクラスがあります。
デバイスとAWS IoTをセキュアに接続します。mqttを意識することなく使えます。
deviceクラスとthingShadowクラスがあります。
Subscribe
Publish
node deviceSub.js
を立ち上げて、別画面で
node devicePub.js
を打つと、
Sub側で
とmessegeが表示されていればOK
iOSでやってみる
流れとしては、先ほど作成した証明書3つのプロジェクト内にコピーし、
クライアントを利用して指定したトピックにpublishするものです。
今回の例は、GPS情報(json)を送信と、ボタンアクションで文字列の送信を行います。
クライアントを利用して指定したトピックにpublishするものです。
今回の例は、GPS情報(json)を送信と、ボタンアクションで文字列の送信を行います。
iOS向けMQTTクライアント
Swiftで書かれたMQTTクライアントMoscapsule
https://github.com/flightonary/Moscapsule
こちらを使うと X.509 形式の証明書を利用した MQTT 通信が行えます。OpenSSL-Universalも依存しているので、こちらも一緒にインポート。
https://github.com/flightonary/Moscapsule
こちらを使うと X.509 形式の証明書を利用した MQTT 通信が行えます。OpenSSL-Universalも依存しているので、こちらも一緒にインポート。
証明書のインポート
Xcodeプロジェクトに先ほど用意した証明書、Privateキーファイル、ルートCAファイルをインポートします。
iOSからTopicに向けてPublish
位置情報を利用するため、
Info.plist
にNSLocationWhenInUseUsageDescription
を追加することを忘れずに。Subscribe
こちらはさきほどの
node deviceSub.js
で待ち受けていればOK
結果
iOSアプリから位置情報が更新されたら
pushPublishボタンアクションで
上記それぞれ表示されればOK
ここまではただのPub/Sub
ここまではただのMQTTブローカーです。
ここからが真骨頂 Thing Shadows
デバイスのことをThingと呼びます。
Thing Shadow(デバイスの影像)はThingの状態がAWS上に存在するもの
デバイスはオフラインになったり、状態が変更されるケースがあるので、アプリから管理するためにThing Shadowが存在する。永続的な仮想バージョンを作成できる。
retainが不要なのは、Thing Shadowがあるから。
retainというのは最後にPublishされたメッセージをMQTTサーバーが保持しておき、新しいSubscriberにそのメッセージを渡す機能
ThingとThing Shadowは一対一で。Thingに変化があれば、Thing Shadowにも変更が通知される。
reportedがThings、desiredがThing Shadowsの状態を示す
Thing Shadow(デバイスの影像)はThingの状態がAWS上に存在するもの
デバイスはオフラインになったり、状態が変更されるケースがあるので、アプリから管理するためにThing Shadowが存在する。永続的な仮想バージョンを作成できる。
retainが不要なのは、Thing Shadowがあるから。
retainというのは最後にPublishされたメッセージをMQTTサーバーが保持しておき、新しいSubscriberにそのメッセージを渡す機能
ThingとThing Shadowは一対一で。Thingに変化があれば、Thing Shadowにも変更が通知される。
reportedがThings、desiredがThing Shadowsの状態を示す
Thing作成
AWS CLIからも可能ですが、
①AWSコンソールからAWS IoTを開きます
②Resources横の Create a Resource を選択
③パネルが展開されてCreate Thingを選択、Nameを入力後、Create
④下のthings一覧から先ほど作成したthingを選択,右サイドパネルが展開されて、
Connect a deviceを選択
⑤Connect a deviceの画面でサポートするSDKの一覧から NodeJS を選択
⑥ Generate certificate and policy を選択
②Resources横の Create a Resource を選択
③パネルが展開されてCreate Thingを選択、Nameを入力後、Create
④下のthings一覧から先ほど作成したthingを選択,右サイドパネルが展開されて、
Connect a deviceを選択
⑤Connect a deviceの画面でサポートするSDKの一覧から NodeJS を選択
⑥ Generate certificate and policy を選択
- Download public key
- Download private key
- Download certificate
上記3つのファイルをダウンロード
⑦ Confirm & Start Connecting を選択
⑧以下のようなJSONが表示されるので。コピー
⑦ Confirm & Start Connecting を選択
⑧以下のようなJSONが表示されるので。コピー
⑨root-CA.crtというファイルをこちらのSymantecのページから取得
https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem
https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem
⑩ダウンロードした3つのファイル、JSON、root-CA.crtを同階層に置きます。
これで準備で完了
AWS CLIでThing Shadow
更新
デバイス iPhone-6 の状態を初期登録
ルート階層のstateは固定で、その下のreported以下に自由に要素を定義することができる。
aws iot-data update-thing-shadow
コマンドで状態の更新ルート階層のstateは固定で、その下のreported以下に自由に要素を定義することができる。
レスポンスにはstateに加えてリクエストのバージョンとリクエストのタイムスタンプなどが付与されます。
パワーオンで更新
desiredがpower onになっています。
状態情報の確認
aws iot-data get-thing-shadow
コマンドにて
desired(thing shadow), reported(device)の状態で、
deltaはstate.deltaにはデバイスの状態と望ましい状態の差分が抽出される。
デバイス側でのパワーオン処理をしたと仮定して、パワーオンにしてみる。
deltaはstate.deltaにはデバイスの状態と望ましい状態の差分が抽出される。
デバイス側でのパワーオン処理をしたと仮定して、パワーオンにしてみる。
再度状態情報を確認
deltaが無くなり、差分が無くなっていることがわかる。
versionは3となっているが、更新リクエストによってAWS側で自動でインクリメントされる。
これは古いバージョンへ先祖還りを防いだり、他のpublisherによる更新を検知する手段となりうる。
versionは3となっているが、更新リクエストによってAWS側で自動でインクリメントされる。
これは古いバージョンへ先祖還りを防いだり、他のpublisherによる更新を検知する手段となりうる。
更新リクエストに"version" : 2の指定を入れたところ、既にバージョン3になっているため更新が拒否される
現在のバージョンの確認 jqで抜き出し
3が出力される。
ルールの作成
①Create a rule、ルールの登録
Rules Engineを通して必要なデータのみをフィルタリングしてデータのやり取りが可能
queryをこのように
SELECT * FROM 'topic_1'
記述して
Rules Engineを通して必要なデータのみをフィルタリングしてデータのやり取りが可能
queryをこのように
SELECT * FROM 'topic_1'
記述して
②
topic_1にトピックを送信→S3にストアという流れを作ります。
今回はS3にデータを送りたいので「Store the message in a file and store in the cloud (S3)」を選択して、Bucket等の設定を行います。
iphone6-location-${timestamp()}
で保存して、順次GPSデータが保存されていきます。
${timestamp()}なしであれば、上書き保存します。
topic_1にトピックを送信→S3にストアという流れを作ります。
今回はS3にデータを送りたいので「Store the message in a file and store in the cloud (S3)」を選択して、Bucket等の設定を行います。
iphone6-location-${timestamp()}
で保存して、順次GPSデータが保存されていきます。
${timestamp()}なしであれば、上書き保存します。
正しくデータが送信されれば「iphone6」というファイルができているはず
AWS IoTを接続してS3にデータを送る一連の流れの説明
おわりに
AWS IoTでM2Mことはじめはこれで終わりです。
実装のポイントとしては
・ひとまず疎通確認のためにはS3への登録を選んでおいて、疎通確認後に本当に渡したいサービスを登録する
・AWS IoTはQoS(Quality of Service)レベルの2が選択できないので複数投げられてもデータが重複しないような冪等性を確保した設計にするとよい
・連続したデータはTopicにMQTTデータを投げる形で実装し、単発データや選択データ(ランプがつく/消える、や電話をかける、等)はSHADOWSで管理したほうがよい
となります。入力部、出力部のデバイスの実装はなるべくシンプルにし、難しい処理はAWS内で片付けたほうが変更に強い実装ができます。例えばデータの丸め等はデバイス部では行わず、AWS IoTからLambda等を繋いでそこで行ったほうがよいです
(http://dev.classmethod.jp/cloud/aws/cm-advent-calendar-2015-getting-started-again-iot/)
things shadowの状態を監視して、他のデバイスを動かすという展開が考えられます。
http://dev.classmethod.jp/cloud/update-device-shadow-by-lambda/
http://dev.classmethod.jp/cloud/update-device-shadow-by-lambda/
参考
MQTTについてのまとめ
http://tdoc.info/blog/2014/01/27/mqtt.html
http://tdoc.info/blog/2014/01/27/mqtt.html
AWS IoT Message BrokerのMQTTでpub/subをやってみた #reinvent
http://dev.classmethod.jp/cloud/aws/pub-sub-with-aws-iot-over-mqtt/
http://dev.classmethod.jp/cloud/aws/pub-sub-with-aws-iot-over-mqtt/
AWS IoTとRuby製MQTTクライアントでPub/Subしてみた
http://qiita.com/hiroeorz@github/items/f933ad1158a08506922a
http://qiita.com/hiroeorz@github/items/f933ad1158a08506922a
Message Broker for AWS IoT (Beta)
http://docs.aws.amazon.com/iot/latest/developerguide/iot-message-broker.html
http://docs.aws.amazon.com/iot/latest/developerguide/iot-message-broker.html
AWS IoT SDK for JavaScript
https://github.com/aws/aws-iot-device-sdk-js
https://github.com/aws/aws-iot-device-sdk-js
The MQTT client for Node.js and the browser
https://github.com/mqttjs/MQTT.js
https://github.com/mqttjs/MQTT.js
AWS IoT の Device Shadow を iOS アプリから MQTT で使ってみた #reinvent
http://dev.classmethod.jp/cloud/aws/aws-iot-mqtt/
http://dev.classmethod.jp/cloud/aws/aws-iot-mqtt/
AWS IoTおよびThing Shadowsに関する雑感
http://tdoc.info/blog/2015/10/09/thing_shadows.html
http://tdoc.info/blog/2015/10/09/thing_shadows.html
AWS IoTのThing Shadowsを図と実行例で理解する #reinvent
http://dev.classmethod.jp/cloud/aws-iot-things-shadow/
http://dev.classmethod.jp/cloud/aws-iot-things-shadow/
これからAWSを使ってIoTをやってみたい人が抑えておくべき10のキーサービス & 7つのキーワード #reinvent
http://dev.classmethod.jp/cloud/aws/aws-key-service-people-wanted-to-do-iot-should-study/
http://dev.classmethod.jp/cloud/aws/aws-key-service-people-wanted-to-do-iot-should-study/
AWS IoTのいろいろなルールを見てみる&ちょっと試してみる #reinvent
http://dev.classmethod.jp/cloud/aws-iot-rules/
http://dev.classmethod.jp/cloud/aws-iot-rules/
【新機能】AWS IoT のRules EngineがAmazon machine Learningをサポート。IoTと機械学習が一体に
http://dev.classmethod.jp/cloud/aws/aws-iot-supports-integration-with-amazon-machine-learning/
http://dev.classmethod.jp/cloud/aws/aws-iot-supports-integration-with-amazon-machine-learning/