工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

AWS IoT Device SDK v2でpublishするときのackCallbackとpacket idについて

概要

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ごとにインクリメントされないのがいまいち解せない。