ESP32でAWS IoTに繋いでThing Shadowを弄る(2) トラブルシューティング編


前回の記事「ESP32でAWS IoTに繋いでThing Shadowを弄る」で楽しい楽しいインターネット・オブ・シングス体験ができるはずなのだが、人生、いきなりうまくいくなんてことは少ない。うまくいかない時のチェックリストを書いておく。「AWS IoTでハマった場合の問題の切り分け」のコツでもあるので、ESP32以外を使っている場合でも役に立つかも。

  • AWS IoTに繋がらない!
    • エンドポイントは合ってる? AWS IoTダッシュボードの左下の “Settings” でチェックできる。”xxxxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com” という感じの文字列が出て来るはず。
    • ポートは合ってる? 8883が正解。
    • Policyをチェック。
      • Policyでiot:Connectを許可しているか?
                {
                    "Effect": "Allow",
                    "Action": [
                        "iot:Connect"
                    ],
                    "Resource": [
                        "*"
                    ]
                }
      • 後述の「全部盛りPolicy」を作って証明書にアタッチしてみる。それでうまくいくかどうかでPolicyの問題かそれ以外の問題か切り分ける。
    • 証明書をチェック
      • 証明書はActivateされている? “Security” > “Certificates” で、使っているはずの証明書に “ACTIVE” と表示されていることを確認。
      • 証明書のフォーマットが崩れていないか?
        • 各行の末尾の改行はちゃんと入っている?
        • ファイル末尾にも改行が必要。
        • “—–BEGIN CERTIFICATE—–” のようなヘッダとフッタもちゃんと含めておく。
        • Serial.print()して見た目がなんかおかしかったりしないかチェック。
      • なんだか色々混乱して頭がいっぱいになってしまったら、証明書を生成するところから順を追ってもう一度。
    • ドキュメントを読んで何かとんでもない勘違いをしていないかチェック。Protocols – AWS IoT
  • Publishできていないかもしれない……
    • 本当にPublishできていないかどうかチェック。AWS IoTコンソール上で、Publishされるはずのトピック名を入れてSubscribeしてみる。Publishしたはずのメッセージが表示されなければ多分本当にPublishされていない。
  • Publishできていない!
    • Policyの問題である可能性が高い。
      • 作ったPolicyはアタッチしてある?
      • とりあえず切り分けのために後述の「全部盛りPolicy」でうまくいくか試す。うまくいけばPolicyの問題、うまくいかなければ他の問題。
      • ドキュメント読もう。このへんに例が載っているので比べてみる。Publish/Subscribe Policy Examples
    • 「実は別の証明書を使っていた!」ということがたまにある。複数の証明書やデバイスで試していると、たまにね。
  • Subscribeできていないかもしれない……
    • Subscribeした直後に接続が切れているかどうかをチェック。AWS IoTでは、Subscribeに失敗すると接続を切られてしまう。
    • Policyをチェック
      • Policyが怪しければ後述の「全部盛りPolicy」で試してみる。
      • Resourceではトピックそのものを指定するのではなくトピックフィルタ (topicfilterがつく) を指定する必要があるので注意。
      • ドキュメントを読む。例と比べてみる。Publish/Subscribe Policy Examples
  • Subscribeできたけれど届くはずのメッセージが届かない
    • まずはAWS IoTテストコンソールで同一のTopicをSubscribeしてみる。それで届くかどうかチェック。実は間違ったTopicをSubscribeしていましたなんてことがあるかも。
    • qosは0か1を指定しないと駄目。
    • Policyにiot:Subscribeだけでなくiot:Receiveも許可する必要あり。これが抜けていると、Subscribeはできるけれどメッセージが一向に届かないという状態になる。
    • (Arduino向けのMQTTクライアントの多くでありがちだが) 回すべきループを回していない。例えば前回紹介したPubSubClientならPubSubClient::loop()を呼び続けることが想定されている。
    • クライアント側のデータサイズオーバーの可能性。AWS IoTテストコンソールから短いメッセージと長〜いメッセージを送ってみる。受け取れるかどうか。
    • (MQTTクライアントとしてPubSubClientを使っている場合) メッセージサイズ制限を再確認。Serial.println(MQTT_MAX_PACKET_SIZE) で出力してみる。
  • Shadowの更新ができない!
    • AWS IoTコンソールでThingを選択し、”Shadow” タブを開く。”Shadow Document” のセクションで本当に更新できているのか、いないのかチェック。
    •  Policyの問題
      • iot:PublishでThing Shadowアップデート用のトピックへのPublishを許可していてもiot:UpdateShadowを許可していなければ駄目。
      • 証明書にThingをアタッチしてある?
      • iot:UpdateShadowを許可する場合、ResourceにはThingのARNを指定する。ここで指定するのは更新用トピックではないので注意!
      • ドキュメントを読もう。ここに例が色々載っている。Thing Policy Examples
    • Topicが間違っている?
      • AWS IoTコンソールでThingを選択し、”Interact” タブを開く。そこで各種Topicをチェック。
      • 頭の “$” が抜けてるとか……
    • (AWS IoTのテストコンソール上でもいいので)  “$aws/things/DEVICE_NAME/shadow/update/#” をSubscribeしてみる。shadow/update/rejectedに何か飛んできていない?
    • データサイズ・JSONの階層数など色々制限があるのでチェック。AWS Service Limits
  • Shadowの更新後にdeltaが飛んでこない (その他、特殊トピックに対してPublishされるはずのメッセージが飛んでこない)
    • AWS IoTのテストコンソールで Subscribeしてみる。
    • Topicは正しいものを指定してある? AWS IoTコンソールでThingを選択し、”Interact” タブを開く。そこで各種Topicをチェック。
    • update/deltaの場合、 “reportedにはあるけれどdesiredにはない項目” はdeltaの対象にならないという仕様があるので注意。
    • getの後にget/acceptedに何も飛んでこない……という現象の場合 、Policyでiot:GetThingShadowを許可し、”Resource” でちゃんと対象のThingを指定しているかチェック。

Policyの問題っぽいと思ったら、とりあえず、何やってもオッケーな「全部盛りPolicy」、たとえば

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

という具合のものを作って証明書にアタッチしてみると良い。それでうまくいけば、今まで使っていたPolicyのどこかに問題がある。駄目ならPolicy以外の問題。AWS IoTはけっこうPolicy関係でハマりやすいので、まずは全部盛りPolicyで動作を確認、その後でPolicyを必要最小限まで狭めていくという手順で試すのも良い。