ユーザ用ツール

サイト用ツール


mae3xx_ope:awsiot:start

差分

この文書の現在のバージョンと選択したバージョンの差分を表示します。

この比較画面にリンクする

mae3xx_ope:awsiot:start [2016/10/19 18:48] (現在)
development 作成
ライン 1: ライン 1:
 +
 +====== AWS IoTを使用する ======
 +
 +MA-E3xx for IoTファームウェア(v2.6.10rc2以降)には、[[https://​aws.amazon.com/​jp/​iot/​|AWS IoT]]の機能を使用するためのソフトウェアが内蔵されています。
 +
 +以下の2つのソフトウェアからなります。
 +
 +* Fluentd用outputプラグイン:​ Fluentdのログ出力をAWS IoTに出力するためのプラグイン
 +* Device Shadowライブラリ:​ Device Shadowを使用するためのAPI
 +
 +===== Fluentd用outputプラグイン =====
 +
 +Fluentd用outputプラグインは、Fluentdのログ出力を、AWS IoTのメッセージとして出力します。
 +
 +プラグインは、/​usr/​lib/​ruby/​vendor\_ruby/​fluent/​plugin に out_awsiot.rb というファイル名で置かれています。
 +
 +==== 事前の準備 ====
 +
 +デバイス(MA-E3xx)用の「秘密鍵 (private key)」「証明書 (certificate)」を作成する必要があります。
 +
 +これらを作成するには、[[http://​docs.aws.amazon.com/​iot/​latest/​developerguide/​iot-device-sdk-c.html|AWSのWebコンソールから作成する方法]]や、
 +AWSのCLIツールで作成する方法があります。
 +
 +また、ルート証明書を[[https://​www.symantec.com/​content/​en/​us/​enterprise/​verisign/​roots/​VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem|Symantecのサイト]]からダウンロードします。
 +
 +作成・取得したファイルを、任意のディレクトリに以下のファイル名で置いてください。
 +
 +* 秘密鍵: privkey.pem
 +* 証明書: cert.pem
 +* ルート証明書:​ aws-iot-rootCA.pem
 +
 +==== プラグインの設定 ====
 +
 +プラグインの動作の設定は、Fluentdの設定ファイル(/​etc/​fluent/​fluent.conf)で行います。
 +
 +<file generic fluent.conf>​
 +<match *>
 +  @type awsiot
 +  certs_dir /​home/​user1/​certs
 +  host ABCDEFGHIJKLM.iot.ap-northeast-1.amazonaws.com
 +  mqtt_qos 1
 +  client_id hogeclient
 +</​match>​
 +</​file>​
 +
 +^ 項目 ​ ^  内容 ​ ^  Notes  |
 +|@type ​  | プラグイン使用宣言 | 「awsiot」固定。必須。|
 +|certs\_dir| 証明書・秘密鍵のディレクトリ | 必須 |
 +|host    | MQTTブローカーのホスト名 | AWS IoTのWebコンソールからThingを選択し、「Detail」の「REST API Endpoint」のホスト名部分。必須。|
 +|mqtt\_qos | MQTTのQoSレベル| 0 or 1。省略時1。|
 +|client\_id| クライアントID | 同じ秘密鍵・かつ同じクライアントIDで複数の同時接続はできない。省略時「centuryfluent」|
 +
 +また、BufferedOutput pluginで用いられる設定も指定できます。(([[http://​docs.fluentd.org/​articles/​output-plugin-overview#​buffered-output-parameters|Output Plugin Overview]])) (([[http://​qiita.com/​tatsu-yam/​items/​bd7006e483f3b3c64309|BufferedOutput pluginの代表的なoptionについて]]))
 +
 +==== 動作確認例 ====
 +
 +ここでは、dummyプラグインを使ってダミーデータを生成し、ダミーデータを標準出力に出力しつつ、10秒に1度ダミーデータをAWS IoTに出力する設定例を示します。
 +また、出力されたメッセージをAWS IoT Webコンソールで確認する方法を示します。
 +
 +まず、設定ファイルを作成します。
 +
 +<file generic sample.conf>​
 +<​source>​
 +  @type dummy
 +  tag dummy
 +  auto_increment_key foo_key
 +</​source>​
 +
 +<match dummy>
 +  @type copy
 +  <​store>​
 +    @type stdout
 +  </​store>​
 +  <​store>​
 +    @type awsiot
 +    certs_dir /​home/​user1/​certs
 +    host ABCDEFGHIJKLM.iot.ap-northeast-1.amazonaws.com
 +    mqtt_qos 1
 +    client_id hogeclient
 +    flush_interval 10s
 +    log_level debug
 +  </​store>​
 +</​match>​
 +</​file>​
 +
 +次に、AWS IoTのWebコンソールから、以下の操作を順に行います。
 +
 ++ 「MQTT Client」をクリックする。
 ++ 「Generate client ID」「Connect」を順にクリックする。
 ++ 「Subscribe to topic」をクリックする。
 ++ 「Subscription topic」に「#​」(全てのtopic)を入力し、「Subscribe」をクリックする。
 +
 +先ほど作成した設定ファイルを使って、Fluentdを起動します。
 +<​code>​
 +user1@plum:​~$ fluentd ​ -c test.conf
 +2016-10-18 14:59:20 +0900 [info]: reading config file path="​test.conf"​
 +2016-10-18 14:59:20 +0900 [info]: starting fluentd-0.12.17
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-mixin-config-placeholders'​ version '​0.3.0'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-mixin-rewrite-tag-name'​ version '​0.1.0'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-dstat'​ version '​0.3.1'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-filter-record-map'​ version '​0.1.4'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-filter_typecast'​ version '​0.0.2'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-flatten-hash'​ version '​0.2.0'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-forest'​ version '​0.3.0'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-influxdb'​ version '​0.2.2'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-mqtt-io'​ version '​0.0.4'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-named_pipe'​ version '​0.1.1'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-notifier'​ version '​0.2.4'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-record-modifier'​ version '​0.3.0'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-record-reformer'​ version '​0.7.0'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-rewrite-tag-filter'​ version '​1.5.1'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-secure-forward'​ version '​0.3.3dev2'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-stats'​ version '​0.3.6'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-td'​ version '​0.10.28'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-typecast'​ version '​0.2.0'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluent-plugin-udp-stream'​ version '​0.0.2'​
 +2016-10-18 14:59:22 +0900 [info]: gem '​fluentd'​ version '​0.12.17'​
 +2016-10-18 14:59:22 +0900 [info]: adding match pattern="​dummy"​ type="​copy"​
 +2016-10-18 14:59:22 +0900 [info]: adding source type="​dummy"​
 +2016-10-18 14:59:22 +0900 [info]: using configuration file: <​ROOT>​
 +  <​source>​
 +    @type dummy
 +    tag dummy
 +    auto_increment_key foo_key
 +  </​source>​
 +  <match dummy>
 +    @type copy
 +    <​store>​
 +      @type stdout
 +    </​store>​
 +    <​store>​
 +      @type awsiot
 +      certs_dir /​home/​user1/​certs
 +      host ABCDEFGHIJKLM.iot.ap-northeast-1.amazonaws.com
 +      mqtt_qos 1
 +      client_id hogeclient
 +      flush_interval 10s
 +      log_level debug
 +    </​store>​
 +  </​match>​
 +</​ROOT>​
 +2016-10-18 14:59:23 +0900 dummy: {"​message":"​dummy","​foo_key":​0}
 +2016-10-18 14:59:24 +0900 dummy: {"​message":"​dummy","​foo_key":​1}
 +2016-10-18 14:59:25 +0900 dummy: {"​message":"​dummy","​foo_key":​2}
 +2016-10-18 14:59:26 +0900 dummy: {"​message":"​dummy","​foo_key":​3}
 +2016-10-18 14:59:27 +0900 dummy: {"​message":"​dummy","​foo_key":​4}
 +2016-10-18 14:59:28 +0900 dummy: {"​message":"​dummy","​foo_key":​5}
 +2016-10-18 14:59:29 +0900 dummy: {"​message":"​dummy","​foo_key":​6}
 +2016-10-18 14:59:30 +0900 dummy: {"​message":"​dummy","​foo_key":​7}
 +2016-10-18 14:59:31 +0900 dummy: {"​message":"​dummy","​foo_key":​8}
 +2016-10-18 14:59:32 +0900 dummy: {"​message":"​dummy","​foo_key":​9}
 +2016-10-18 14:59:33 +0900 [debug]: begin reconnect.
 +2016-10-18 14:59:33 +0900 dummy: {"​message":"​dummy","​foo_key":​10}
 +2016-10-18 14:59:33 +0900 [debug]: reconnect finished.
 +2016-10-18 14:59:34 +0900 dummy: {"​message":"​dummy","​foo_key":​11}
 +</​code>​
 +
 +AWS IoT Webコンソールを見ると、10秒ごとに10個のメッセージが送られてきています。
 +
 +{{mae3xx_tips:​awsiot:​fluentoutput.png}}
 +
 +
 +===== Device Shadowライブラリ=====
 +
 +Device Shadowライブラリは、[[http://​docs.aws.amazon.com/​iot/​latest/​developerguide/​iot-thing-shadows.html|Device Shadow]]を簡単に使うことができるRubyのライブラリです。
 +
 +ライブラリは、/​usr/​lib/​ruby/​vendor\_ruby に awsiot_shadow.rb というファイル名で置かれています。
 +==== 事前の準備 ====
 +
 +Fluentd用outputプラグインと同じ要領で、証明書・秘密鍵とルート証明書を作成・取得してください。
 +
 +==== API一覧 ====
 +
 +Centurysys::​AWSIotShadowクラスに様々なAPIが用意されています。
 +
 +
 +**new(hash)**
 +
 +AWSIotShadowクラスのオブジェクトを生成します。
 +引数のhashには以下の要素を指定できます。
 +^key^value^note|
 +|host|MQTTブローカーのホスト名|必須|
 +|port|MQTTブローカーのポート番号|省略時 8883|
 +|ca\_file|ルート証明書のファイル名|必須|
 +|key\_file|秘密鍵のファイル名|必須|
 +|cert\_file|証明書のファイル名|必須|
 +|thing\_name|Device ShadowのThing名|必須|
 +|client\_id|クライアントID|実際にはこの値に「R」「G」「U」を後置した文字列が使われる|
 +|keep\_alive|MQTT Keep-Aliveを送る秒数|省略時 0(送らない)|
 +|enable\_auto\_reconnect|trueならMQTTブローカーとの接続が切れたとき再接続する|省略時 false(再接続しない)|
 +
 +**connect()**
 +
 +AWS IoTのMQTTブローカーに接続します。yield()を呼び出す前には必ず呼び出して下さい。
 +
 +メソッド内部で、2秒のsleep()が発生します。これは、MQTTブローカーにShadowの更新を知らせるTopicをSubscribeしてから、実際にそのTopicが受信できるまでの間に、2秒間必要なためです。
 +
 +オブジェクト生成時にkeep_aliveを有効にしていた場合で、MQTTブローカーと切断された時には、このメソッドを呼び出したスレッドに例外(MQTT::​ProtocolException)が発生します。
 +
 +**yield() -> hash **
 +
 +MQTTブローカーからShadowの更新(/​update/​delta)を受信し、更新された部分をHashとして返します。
 +
 +Shadowが更新されなければ永遠に受信待ちを行います。
 +タイムアウト処理を行いたい場合は、Timeoutモジュールを使って呼び出して下さい。
 +
 +**disconnect()**
 +
 +MQTTブローカーとの接続を切断します。
 +
 +**get() -> hash**
 +
 +AWS IoTからShadowの現在の状態(reported)を取得します。
 +デバイスの初期状態をAWS IoTから取得して、デバイスを初期設定する場合に使用します。
 +
 +状態を取得できるまで、永遠に送信処理を行います。
 +タイムアウト処理を行いたい場合は、Timeoutモジュールを使って呼び出して下さい。
 +
 +**update(hash)**
 +
 +AWS IoTに対してShadowの状態(reported)を更新する処理を行います。
 +
 +メソッド内部で、2秒のsleep()が発生する場合があります。
 +これは、updateするためのMQTTクライアントを接続するときに、updateの結果を取得するために、新たなTopicをSubscribeする必要があるためです。
 +
 +状態を更新できるまで、永遠に送信処理を行います。
 +タイムアウト処理を行いたい場合は、Timeoutモジュールを使って呼び出して下さい。
 +
 +==== サンプルアプリケーション ====
 +
 +サンプルアプリケーションのコードを以下に示します。
 +
 +ここでは、「TestThing」というThingのShadowを監視し、他からShadowが更新されたら、更新された状態を標準出力に表示し、MAに繋がったデバイスを制御したとみなして、制御後の状態でShadowを更新します。
 +
 +<code ruby shadow_sample.ruby>​
 +require '​awsiot_shadow'​
 +
 +@_host = '​ABCDEF.iot.ap-northeast-1.amazonaws.com'​
 +_certdir = '/​home/​user1/​certs'​
 +@_ca_file = _certdir + '/​aws-iot-rootCA.pem'​
 +@_key_file = _certdir + '/​privkey.pem'​
 +@_cert_file = _certdir + '/​cert.pem'​
 +
 +shadow_client = Centurysys::​AWSIotShadow.new(
 +  :host => @_host,
 +  :ca_file => @_ca_file,
 +  :key_file => @_key_file,
 +  :cert_file => @_cert_file,​
 +  :thing_name => '​TestThing',​
 +  :client_id => '​test',​
 +  :keep_alive => 15
 +)
 +
 +# AWS IoTのMQTTブローカーに接続する。
 +shadow_client.connect()
 +
 +now_state = nil
 +
 +# AWS IoTから、デバイスに設定すべきShadowの初期状態を取得する。
 +timeout(5) {
 +  now_state = shadow_client.get
 +}
 +
 +# 実際にはここでnow_stateに従ってデバイスの状態を変える
 +
 +# AWS IoT上にあるShadowの状態を、デバイスに設定した状態に更新する。
 +timeout(5) {
 +  shadow_client.update(now_state)
 +}
 +
 +p "start main loop"
 +
 +while true
 +  delta = nil
 +  begin
 +    # AWS IoTから、Shadowの更新を取得する。(ここでは5秒間でtimeoutするようにしている)
 +    timeout(5) {
 +      delta = shadow_client.yield
 +    }
 +    p delta
 +
 +    # デバイスの状態(now_state)をdeltaに従って変える。
 +    delta.each_key { |key|
 +      if (now_state[key] != delta[key]) then
 +        # changing device state to delta(desired) state
 +        now_state[key] = delta[key]
 +      end
 +    }
 +
 +    # AWS IoTのShadowの状態を、デバイスに設定した状態に更新する。
 +    timeout(5) {
 +      shadow_client.update(now_state)
 +    }
 +  rescue Timeout::​Error
 +    # タイムアウトした(ここではそのまま次のループへ)
 +    p "​Timeout occured. wait again"
 +  end
 +end
 +</​code>​
 +
 +AWS IoTのWebコンソールから、「TestThing」の「Update shadow」を選択し、「desired」以下にあるパラメータを書き換えると、書き換えられたパラメータが標準出力に表示された後、そのパラメータがAWS IoT Webコンソールの「reported」以下に反映されます。
  
mae3xx_ope/awsiot/start.txt · 最終更新: 2016/10/19 18:48 by development