AWS IoT Core Device Advisorをためしてみた

2021.08.25

いわさです。

数ヶ月前に、AWS IoT Coreに接続したデバイスを検証するための、マネージドなテスト機能であるDevice Advisorが一般提供されていました。
実は一般提供になった時からずっと試していたのですが、なかなか成功せず。

先日、ついに使うことが出来たのでブログを書きました。

まずは、IoT Core をセットアップし、デバイスを用意する

デバイスといっても、Device Advisorの利用には、実デバイスの必要はありません。
今回は、IoTテストクライアントは、IoT Core 初級ハンズオンのダミーデバイスを使います。
ローカルのBash環境でもいいですし、なければCloud9でも良いです。

IoT Coreのセットアップと接続確認は上記を参考に行います。
このハンズオンの手順に従うと驚くほど簡単にIoT Coreへ接続する検証環境が作成出来ます。

iwasa.takahito@hoge dummy_client % python3 device_main.py --device_name iwasa-thing-20210804 --endpoint hogebtns34ei8k-ats.iot.ap-northeast-1.amazonaws.com
device_name: iwasa-thing-20210804
endpoint: hogebtns34ei8k-ats.iot.ap-northeast-1.amazonaws.com
rootca cert: ./certs/AmazonRootCA1.pem
private key: ./certs/hoge38ef3340fa5997f5803ba2ab723fc3c039d9c00ed3ece4ae45cc8d399ac9-private.pem.key
certificate: ./certs/hoge38ef3340fa5997f5803ba2ab723fc3c039d9c00ed3ece4ae45cc8d399ac9-certificate.pem.crt
Check latest Shadow status
Subscribing to Shadow Delta events...
Thing has no shadow document. Creating with defaults...
un subscribe from get shadow events
Updating reported shadow to...
Subscribing to Shadow Update responses...
Update request published.
topic: data/iwasa-thing-20210804

もう接続出来ました。すごい。

さて、トピックやデバイスシャドウの動作確認くらいまで出来たらデバイス側の準備は概ねOKです。

IoT Core Device Advisor をセットアップする

Device Advisor利用にあたってのデバイス側の変更点は、IoT SDKによる接続時のエンドポイントをDevice Advisor用のエンドポイントに変更するだけで良いです。
なのでセットアップ手順に沿ってしっかり実施できれば大丈夫です。

デバイスロールを選択します。
ここのロールは正しくポリシーを設定するようにしてください。どういうエラーが出るか後述しますが、権限が不足しているとデバイスアドバイザーへ接続出来なかったりします。

テストスイートを作成します。
Device Advisorではいくつかのビルド済みテストが用意されています。
AWS Partner Device Catalogのデバイス認定を受けるためにはこの中のいくつかのテストケースを合格する必要があります。

AWSデバイス認定プログラムについては以下を参照してください。

今回ははじめの一歩である、MQTT Connectを試しました。

テストステップの確認が出来たら、実行します。

テストの実行が開始されたらIoTから接続操作をしましょう。
接続先エンドポイントが先程と変わっている点に注目してください。

後述しますが、実行直後は接続エラーとなりますので、何度かリトライが必要です。
ドキュメント上もリトライ処理を実装することが推奨されています。

iwasa.takahito@HL00780 dummy_client % python3 device_main.py --device_name iwasa-thing-20210822 --endpoint hogez79h4mpyfm.deviceadvisor.iot.ap-northeast-1.amazonaws.com
device_name: iwasa-thing-20210822
endpoint: hogez79h4mpyfm.deviceadvisor.iot.ap-northeast-1.amazonaws.com
rootca cert: ./certs/AmazonRootCA1.pem
private key: ./certs/hogee250396f67f18a02a88fd8ae4ea212559d6c9c24245522a367e406464cce-private.pem.key
certificate: ./certs/hogee250396f67f18a02a88fd8ae4ea212559d6c9c24245522a367e406464cce-certificate.pem.crt
Check latest Shadow status
Subscribing to Shadow Delta events...
Finished getting initial shadow state.
  Shadow contains reported wait_time: '5'
un subscribe from get shadow events
Subscribing to Shadow Update responses...
topic: data/iwasa-thing-20210822

テストに合格すると、マネジメントコンソール上のステータスに反映されます。

注意点

デバイスアドバイザーへの接続時はリトライする

テスト実行直後後は接続に失敗します。(AWS_IO_SOCKET_CLOSED)

iwasa.takahito@hoge dummy_client % python3 device_main.py --device_name iwasa-thing-20210822 --endpoint hogez79h4mpyfm.deviceadvisor.iot.ap-northeast-1.amazonaws.com
device_name: iwasa-thing-20210822
endpoint: hogez79h4mpyfm.deviceadvisor.iot.ap-northeast-1.amazonaws.com
rootca cert: ./certs/AmazonRootCA1.pem
private key: ./certs/hogee250396f67f18a02a88fd8ae4ea212559d6c9c24245522a367e406464cce-private.pem.key
certificate: ./certs/hogee250396f67f18a02a88fd8ae4ea212559d6c9c24245522a367e406464cce-certificate.pem.crt
Traceback (most recent call last):
  File "/Users/iwasa.takahito/environment/dummy_client/device_main.py", line 437, in <module>
    device_main()
  File "/Users/iwasa.takahito/environment/dummy_client/device_main.py", line 341, in device_main
    connected_future.result()
  File "/Users/iwasa.takahito/.pyenv/versions/3.9.4/lib/python3.9/concurrent/futures/_base.py", line 445, in result
    return self.__get_result()
  File "/Users/iwasa.takahito/.pyenv/versions/3.9.4/lib/python3.9/concurrent/futures/_base.py", line 390, in __get_result
    raise self._exception
awscrt.exceptions.AwsCrtError: AWS_IO_SOCKET_CLOSED: socket is closed.

デバイスアドバイザー側が接続できるようになるまでリトライを実行してください。

テスト名は日本語デフォルトだとエラーになる

これはそのうち修正されそうな気がしますが、テストスイートの名称は自動で作成日時が組み込まれます。
しかし「月」などがエラーになります。デフォルトなのに・・・。

Invalid Request: suiteDefinitionName can only be A-Z, a-z, 0-9, space or the following characters (),:_+-

まぁ、素直に変更しましょう。

ロールとポリシーの設定をしっかりしないとMQTT接続時に失敗する

だいたい以下の2パターンのエラーが発生します。

  • AWS_ERROR_MQTT_UNEXPECTED_HANGUP
  • AWS_IO_TLS_NEGOTIATION_TIMEOUT
iwasa.takahito@hoge dummy_client % python3 device_main.py --device_name iwasa-thing-20210822 --endpoint hogez79h4mpyfm.deviceadvisor.iot.ap-northeast-1.amazonaws.com
device_name: iwasa-thing-20210822
endpoint: hogez79h4mpyfm.deviceadvisor.iot.ap-northeast-1.amazonaws.com
rootca cert: ./certs/AmazonRootCA1.pem
private key: ./certs/hogee250396f67f18a02a88fd8ae4ea212559d6c9c24245522a367e406464cce-private.pem.key
certificate: ./certs/hogee250396f67f18a02a88fd8ae4ea212559d6c9c24245522a367e406464cce-certificate.pem.crt
Traceback (most recent call last):
  File "/Users/iwasa.takahito/environment/dummy_client/device_main.py", line 437, in <module>
    device_main()
  File "/Users/iwasa.takahito/environment/dummy_client/device_main.py", line 341, in device_main
    connected_future.result()
  File "/Users/iwasa.takahito/.pyenv/versions/3.9.4/lib/python3.9/concurrent/futures/_base.py", line 445, in result
    return self.__get_result()
  File "/Users/iwasa.takahito/.pyenv/versions/3.9.4/lib/python3.9/concurrent/futures/_base.py", line 390, in __get_result
    raise self._exception
awscrt.exceptions.AwsCrtError: AWS_ERROR_MQTT_UNEXPECTED_HANGUP: The connection was closed unexpectedly.
iwasa.takahito@hoge dummy_client % python3 device_main.py --device_name iwasa-thing-20210822 --endpoint hogez79h4mpyfm.deviceadvisor.iot.ap-northeast-1.amazonaws.com
device_name: iwasa-thing-20210822
endpoint: hogez79h4mpyfm.deviceadvisor.iot.ap-northeast-1.amazonaws.com
rootca cert: ./certs/AmazonRootCA1.pem
private key: ./certs/hogee250396f67f18a02a88fd8ae4ea212559d6c9c24245522a367e406464cce-private.pem.key
certificate: ./certs/hogee250396f67f18a02a88fd8ae4ea212559d6c9c24245522a367e406464cce-certificate.pem.crt
Traceback (most recent call last):
  File "/Users/iwasa.takahito/environment/dummy_client/device_main.py", line 437, in <module>
    device_main()
  File "/Users/iwasa.takahito/environment/dummy_client/device_main.py", line 341, in device_main
    connected_future.result()
  File "/Users/iwasa.takahito/.pyenv/versions/3.9.4/lib/python3.9/concurrent/futures/_base.py", line 445, in result
    return self.__get_result()
  File "/Users/iwasa.takahito/.pyenv/versions/3.9.4/lib/python3.9/concurrent/futures/_base.py", line 390, in __get_result
    raise self._exception
awscrt.exceptions.AwsCrtError: AWS_IO_TLS_NEGOTIATION_TIMEOUT: Channel shutdown due to tls negotiation timeout

ドキュメントを見直して、ポリシーやアクションやリソースに誤りがないか再確認してください。

自戒

ドキュメントにはしっかり従う。