Translate

2019年4月11日木曜日

AWS IoT Core にQoS=2でLast Willメッセージを設定したら例外が出た件

AWS IoT CoreへアクセスするPythonプログラムを書いた。
ライブラリはpahoではなくAWSIoTPythonSDKを使った。



ちなみにMQTTブローカへ接続するプログラムを書く場合、
ベンダ提供ライブラリを素直に使うのが生産性を上げるコツだ。
ベンダ固有の機能の有無を関数やメソッドのコード上ドキュメントで
確認できるし、
一番困るのがベンダ固有のpayloadやtopicフォーマットを持っている
場合だ。
ドキュメントをイチから読むより、関数やメソッドのドキュメントを
見るほうが圧倒的に速い..と私はおもっている。
..Eclipse Mosquitto、IBM Watson IoT PlatformとAWS IoT Coreしか
まだ触ったことがないのだけど..

話をもどすが、どうも AWS IoT に Will

つまりデバイスが死んだ際に
特定のメッセージを指定トピックへ送信してくれる
MQTTベースのメッセージブローカに標準搭載される機能

がないと思っている人が意外と多い。

AWS IoT に Will がないと書かれたブログ記事もすくなくなく
これを鵜呑みにした人がおおいのだろう。

ベータ版の頃はそうらしかったのだけど、
今のバージョンでは存在している。
#この先、消えるかはわからないけど ;-p

AWSIoTPythonSDK の AWSIoTMQTTClient クラスには

configureLastWill(topic, payload, QoS, retain=False)
というインスタンスメソッドが存在する。

なのでQoS=2にしてWillメッセージをセットすると..

Traceback (most recent call last):
  File "test_dev.py", line 45, in
    test_dev()
  File "test_dev.py", line 31, in test_dev
    client = Client('conf/aws/xxxx/xxxx.yml', 'xxxx_test')
  File "C:\Users\xxxxx\projects\xxxx\aws\broker.py", line 354, in __init__
    client.connect()
  File "C:\Users\xxxxx\AppData\Local\Continuum\anaconda3\envs\xxxx\lib\site-packages\AWSIoTPythonSDK\MQTTLib.py", line 486, in connect
    return self._mqtt_core.connect(keepAliveIntervalSecond)
  File "C:\Users\xxxxx\AppData\Local\Continuum\anaconda3\envs\xxxx\lib\site-packages\AWSIoTPythonSDK\core\protocol\mqtt_core.py", line 195, in connect
    raise connectTimeoutException()
AWSIoTPythonSDK.exception.AWSIoTExceptions.connectTimeoutException


というエラーになってconnectできない状態になってしまった。

どうも Will はサポートされたけど、
AWS IoT はあくまで QoS は 0 か 1 までで
QoS=2は未だにサポートしていないらしい..
というより、今サポートしてないなら、やる気なしでしょ..


ということでQoS=1にしたら正常に動作した


ちなみに引数にretainがあり、
AWSIoTPythonSDKのコードをおっていくとpahoのクライアントクラスに
そのまま値を渡しているので、
もしかしたら..とおもって retain=True で実行してみた。

..結果は、QoS=2のときと全く同じ例外が発生してしまった..

retain とは、
最後にpublishされたメッセージをブローカで保持し、
新規Subscriberにそのメッセージを渡す
MQTTベースのメッセージブローカに標準提供される機能のひとつ。

AWS IoTベータのころからサポートされておらず、
こちらもQoS=2同様
現時点でもサポートされていない
ということらしい..


そのかわりにシャドウを使えってことなのだろうけど..
この機能AWS IoT Coreにしか存在しない独自機能なんだよなあ..

..日本のSIerは、こういったベンダ依存をきらうからねえ..

2019年4月3日水曜日

AWS IoT Core へバイナリデータが送れない件(AWS IoT CoreをDonkey Carで使う)

Donkeycar のAI処理が重くなりすぎたので、サーバ側で処理させようとMQTTブローカ経由で画像データをおくっていたのだけど、AWS環境でもやってみたいということで試してみた。

AWS IoT Coreをセットアップして、paho-mqttを使って画像データを送信しようとしたのだけどうまくいかない..

AWS IoT Python SDK を使ってもうまく送れない..


Eclipse Mosquitto や IBM Watson IoT Platform だとうまくいったのに..



..と、いろいろ調べていると以下の記事


Python AWS IoT SDK - MQTT publish with binary payload fails
https://forums.aws.amazon.com/thread.jspa?threadID=237466


にこのような記述があった。

The AWS IoT Python SDK uses Eclipse Paho Python MQTT Client as the dependency underneath. It supports the following payload type in Python:
1. str
2. bytearray
3. unicode string

(日本語訳)
AWS IoT Python SDKは、その下の依存関係としてEclipse Paho Python MQTTクライアントを使用します。 Pythonでは次のペイロードタイプをサポートしています。
1. str
2. bytearray
3. Unicode文字列

..ん?
bytesがサポートされていない?!


仕様かよ!!






bytearray(message) したら..動いた..

マジかよ..subscribe側でbytesに戻さないと..


p.s.1

AWS IoT CoreはWatson IoT Platformより画面が整理されていて使いやすい。
..のだけど、パラメータが多いし、Raspberry Pi側にプライベートキーファイルとcertificateファイル、サーバ側のルートCAファイルをおいてやらないといけないのが面倒だ..

モノのシャドウはいわゆるMQTTブローカのWill機能。AWS IoTCore上でドキュメントを定義して、これをMQTT通信経由でget/delete/update/deltaイベントコールバックで操作する。
便利そうではあるのだけど、ドキュメントがJSONデータ1つなんだよなあ..

まあキューにすればMQの悪名高きデッドレターキュー管理シないといけなくなるしなあ..



p.s.2

にしても..各ベンダのMQTTブローカって独自色を出そうと付加機能つけすぎ..
正直 paho-mqtt ライブラリで疎通取るより各ベンダ独自のSDK使ったほうが、生産性がとっても高くなることがよくわかった..
#SDKで方言対応してくれるからね

このあたり、基盤屋が対応してくれればいいのだけど、堅モノから一歩たりとも出てくれない..

せめて..死んで^H^H^H python覚えてくれないかなあ..

既存アプリケーションをK8s上でコンテナ化して動かす場合の設計注意事項メモ

既存アプリをK8sなどのコンテナにして動かすには、どこを注意すればいいか..ちょっと調べたときの注意事項をメモにした。   1. The Twelve Factors (日本語訳からの転記) コードベース   バージョン管理されている1つのコードベースと複数のデプロイ 依存関係 ...