Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What is going on with this article?
@kgbu

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

More than 5 years have passed since last update.

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月下旬時点)

4
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
4
Help us understand the problem. What is going on with this article?