LoginSignup
5
4

More than 5 years have passed since last update.

MQTTゲートウェイFujiでAWS IoTに繋いでみた

Last updated at Posted at 2016-01-10

MQTTゲートウェイ Fujiで証明書によるクライアント認証に対応したので、AWS IoTに繋いでみました。
<2016/2/16:追記:Fujiが1.0.0バージョンリリースとなり、この機能が正式に取り込まれていました>

以下の記事を大変参考にさせていただきました。ありがとうございます。

まずAWS IoT側でThingを作る

以下の情報が得られます

  • Thingのcertificate
  • 証明書のprivate_key
  • 証明書のprivate_keyに対応するpublick_key
  • MQTT topic

証明書の認証のルートCAはシマンテックサイトから取得します。

curl -o rootCA.pem  https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem

ところで、ThingsのshadowをupdateするにはどんなJSONを投げるのか?

API:http://docs.aws.amazon.com/iot/latest/developerguide//thing-shadow-mqtt.html

MQTTクライアントのmosquitto_sub, mosquitto_pubコマンドを使って動作確認してみます。

まず、結果をモニタするためのsubscribeをしておきます

 mosquitto_sub -t "\$aws/things/RoomTemp/#" -h XXX.amazonaws.com -p 8883 --cafile rootCA.pem --cert UNIQUEID-certificate.pem.crt --key UNIQUEID-private.pem.key -d


Client mosqsub/hostname. sending SUBSCRIBE (Mid: 1, Topic: $aws/things/RoomTemp/#, QoS: 0)

ではJSONデータをpublishしてみましょう。

値だけのJSONをpublishしてみた

Client mosqsub/hostname. received PUBLISH (d0, q0, r0, m0, '$aws/things/RoomTemp/shadow/update', ... (13 bytes))
{"value": 31}

すると、rejectを食らっていた

Client mosqsub/hostname. received PUBLISH (d0, q0, r0, m0, '$aws/things/RoomTemp/shadow/update/rejected', ... (53 bytes))
{"code":400,"message":"Missing required node: state"}

desiredreportedだけでもダメ。

Client mosqsub/hostname. received PUBLISH (d0, q0, r0, m0, '$aws/things/RoomTemp/shadow/update', ... (59 bytes))
{ "desired": { "value": 30 }, "reported": { "value": 30 } }
Client mosqsub/hostname. received PUBLISH (d0, q0, r0, m0, '$aws/things/RoomTemp/shadow/update/rejected', ... (53 bytes))
{"code":400,"message":"Missing required node: state"}

publishするJSONは以下の形式に従う必要があります。良い子はちゃんとドキュメントを読みましょう。

註:clientTokeとversionはオプション

{
    "state": {
        "desired": {
            "attribute1": integer2,
            "attribute2": "string2",
            ...
            "attributeN": boolean2
        },
        "reported": {
            "attribute1": integer1,
            "attribute2": "string1",
            ...
            "attributeN": boolean1
        }
    }
    "clientToken": "token",
    "version": version
}

成功例
desiredとreportedが異なる値にしてみました。

Client mosqsub/hostname. received PUBLISH (d0, q0, r0, m0, '$aws/things/RoomTemp/shadow/update', ... (69 bytes))
{"state":{ "desired": { "value": 30 }, "reported": { "value": 31 } }}

Client mosqsub/hostname. received PUBLISH (d0, q0, r0, m0, '$aws/things/RoomTemp/shadow/update/delta', ... (103 bytes))
{"version":4,"timestamp":1447815699,"state":{"value":30},"metadata":{"value":{"timestamp":1447815699}}}

Client mosqsub/hostname. received PUBLISH (d0, q0, r0, m0, '$aws/things/RoomTemp/shadow/update/accepted', ... (197 bytes))
{"state":{"desired":{"value":30},"reported":{"value":31}},"metadata":{"desired":{"value":{"timestamp":1447815699}},"reported":{"value":{"timestamp":1447815699}}},"version":4,"timestamp":1447815699}

この結果、out of syncの状態になります。

以下のようにdesiredreportedが一致するとAWSのコンソールにShadow Status In syncと表示されるようになります。

Client mosqsub/hostname. received PUBLISH (d0, q0, r0, m0, '$aws/things/RoomTemp/shadow/update', ... (69 bytes))
{"state":{ "desired": { "value": 30 }, "reported": { "value": 30 } }}

Client mosqsub/hostname. received PUBLISH (d0, q0, r0, m0, '$aws/things/RoomTemp/shadow/update/accepted', ... (197 bytes))
{"state":{"desired":{"value":30},"reported":{"value":30}},"metadata":{"desired":{"value":{"timestamp":1447815776}},"reported":{"value":{"timestamp":1447815776}}},"version":5,"timestamp":1447815776}

fujiで繋げてみます

設定ファイル

awsthing.toml
[gateway]
name = "RoomTemp"

[[broker."aws/1"]]

host = "ABCDEFG.iot.ap-northeast-1.amazonaws.com"
port = 8883
topic_prefix = "aws"

tls = true

cacert = "/AWSThing/rootCA.pem"
client_cert = "/AWSThing/XXXXX-certificate.pem.crt"
client_key = "AWSThing/XXXXX-private.pem.key"

[device."RoomTemp"]
type = "dummy"
broker = "aws"
interval = 30
qos = 0
payload = "30"

実行結果

$ ./fuji -c awsthing.toml -d

INFO[0000] start fuji gateway
WARN[0000] status create error, no status found
INFO[0000] broker connecting to: tcp://ABCDEF.iot.ap-northeast-1.amazonaws.com:8883
INFO[0000] start dummy device
INFO[0000] client connected
DEBU[0030] message got: {aws/RoomTemp/RoomTemp/dummy/publish}
DEBU[0030] message published: {aws/RoomTemp/RoomTemp/dummy/publish}

知見、のような物

証明書が無効な場合、以下のようなエラーが出るらしい

ERRO[0000] Failed to start MQTT client: Network Error : remote error: unknown certificate 

ERRO[0000] Failed to start MQTT client: Network Error : remote error: unknown certificate authority 

どうやらwillの設定があるとうまく繋がらないらしい

もともとAWS IoTのシステムはWillをサポートせず、Shadowの状態として表現できるようなので特に問題では無いと思いますが、設定でwill_messageを指定したらつながらず、ちょっと悩みました(2015年12月下旬時点)

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4