概要
AWS IoT Device SDK v2でのpublishで、ackCallbackとpacket idについて旧版との違いがわかったのでメモした。
背景と目的
AWS IoT Device SDK v2を使う必要が出た。APIの仕様が旧バージョンから変わっているので、ちょっと動かして確認する。
詳細
0. 参考URL
1. インストール
pip install aws-iot-sdk
Windows PCでは、これだけでよかったが、他のあるLinux環境では、参考URLに書いてある通りwheelが取得できず、まず以下をやってからpipでのインストールが必要だった。
sudo apt-get update sudo apt-get install cmake sudo apt-get install libssl-dev
2. 動かして気づいたことをメモ
とりあえず、pubsubのサンプルを動かしてみた。
2.1 旧版のMQTTのClientオブジェクトに相当するもの
- 旧: AWSIoTPythonSDK.MQTTLib.AWSIoTMQTTClient
- v2: awscrt.mqtt.Connection
だいたい同じようなメソッドが並んでいる。
2.2 publishメソッドは非同期
- 旧版: publish=同期、publishAsync=非同期
- v2: publish=非同期、publishAsync=ない
awscrt.mqtt.Connectionのpublishメソッドには、旧版のpublishAsyncの引数ackCallbackに相当するものがない。旧版のackCallbackはどうやって実装すればいいのか?
2.3 ackCallbackに相当するもの
こちらにある通り、publishメソッドの戻り値タプルの1つ目concurrent.futures.Futureオブジェクトなので、concurrent.futures.Futureオブジェクトのadd_done_callbackメソッドで、ackCallbackを割り当てればよい。
def ackCallback(f): # PUBACK受信後の処理を記述 : # publish future, packetId = mqtt_connection.publish(...) # 戻り値futureにackCallbackを割り当て future.add_done_callback(ackCallback) :
2.4 packetIdは旧版と同じではない?
旧版では、publishAsyncの戻り値packetIdは、ackCallbackの引数midと対応していた。publishごとにpacketIdがインクリメントされるので、どのpublishのACKかということが、midで判断できた。
v2では、APIドキュメントを見る限りpublish戻り値タプル2個目packet_idに見えるので、サンプルコードに以下を追記して動かしてみたが、publishごとにpacket_idが変化してくれない。ずっと1のまま。
def ackCallback(f): # f.result()にpacket_idが入っている print(f.result()) future, packetId = mqtt_connection.publish(...) print(packetId) # publishのpacket_id future.add_done_callback(ackCallback)
旧版でできたのにv2でできないのは、おかしい気がする。何か考え方間違えているのか? 自分でpublish時に管理用のカウンタみたいなものを用意するしかないのか?
まとめと今後の課題
旧版とv2の違いがわかった。packet idがpublishごとにインクリメントされないのがいまいち解せない。