MUDAなことをしよう。MUDAなことをしよう。IoTのMQTT双方向通信〜2020年1月17日プログライズライターが概ね好評を頂いてひと安心し、また現在、(ちょっとしたものはあれども)特段作りたいものもないので、自分のものづくりの幅を広げるために、しばらくお勉強フェーズに入ります。IoTとM5StickCをMQTTで繋いで双方向通信させてみました。ESP32(←M5StickCは正確にはESP32-picoですが)を使用しているということで、既に色々なところで情報が出ている話だとは思いますが、自分の勉強も兼ねて、改めて自分なりにまとめてみます。Services)の利用歴ですが、「仕事でとてもよく耳にするけれど、自分ではほぼ触ったことがないので、その場ではわかっている雰囲気で会話している」というレベルです。そこから自分の勉強のために色々調べながら書いていっておりますので、間違ったことを書いてしまっていたら大変申し訳ありません、ご了承ください。やりたいことのイメージイメージはこんな感じです。M5StickCとAWSのどちらからもメッセージの送信が可能な状態にします。トピックを一つにまとめても良いのですが、そうすると、どちらも自分がPublishしたものをSubscribeによって自分でReceiveすることになってしまい、それがあまり好きではないので、「デバイスからの送信用」と「クラウドからの送信用」でトピックを分けるようにしています。MQTTのことは正確には理解できていないので、何か定石から外れているようなら申し訳ありません。ユーザの作成からスタートしました。ルートユーザや管理者用IAMユーザで諸々の作業を進めていくのは、何でもやれ過ぎてお作法的に宜しくない、とのことなので。確かに、よくわからないサービスをよくわからないままに使い始めてものすごい費用請求がくる、とかはごめんこうむりたいですので、素直にお作法に従います。ルートユーザでログインしている状態から管理者用IAMユーザ&グループを作成する手順は、AWSの公式リファレンスの通りなので省略します。管理者用IAMユーザでログインし直してから、今度は開発者用IAMグループ&ユーザを作成します。開発者用グループを作成して、以下の2つのポリシーをアタッチしました。AWSIoTFullAccessCloudWatchFullAccessいきなり”FullAccess”にしてしまって良いのかは気になるところですが、今回は一旦これで。CoreでMQTT通信を行うだけなら、この2つのポリシーで十分です。Coreのコンソールのモニタリング画面で何も表示されなくなってしまうから設定したもので、気にならない人は設定しなくて良いと思います。CloudWatchはAWSを使っていくなら後で必ず使うことになると思うので、設定しておいて良いとも思います。以下の作業は、上記で作成した開発者用グループに所属させた新規ユーザでログインした状態で進めます。Coreの管理画面にいきます。後々「モノ」にアタッチすることになる「ポリシー」を先に作ってから、「モノ」を作っていきます。「モノ」の作成の中で、併せて「証明書」も作成していきます。ポリシー」からポリシーを作成します。許可と設定されていることが多い気がします。要するに全許可設定で、まずはこのポリシー設定で「確かに繋がるね」ということを確認することは(繋がらないときの問題切り分けのために)非常に重要なのですが、このまま進んでしまうと結局ポリシーとはなんだったのかというのがよくわからないままですし、最終的なプロダクトを作る際に全許可設定はありえないので、もう少し細かく設定してみます。ちなみに自分はこの記事の執筆時点で「ARNとは何ぞや?」とか言っているレベルです。Name、AWS上のリソースを一意に特定するための名前、ということですね。IoTのポリシーですが、「このアクションはどのリソースに対する許可か」を理解していないと設定が難しいです。このへんのことは、公式ドキュメントのこちらに正式な記載がありますが、とりあえず今回使用する範囲での自分の理解は以下になります。モノに対して、Subscribe(メッセージの監視)を許可するトピックフィルターを定めるConnectがモノに対する許可であるのは良いとして、まだよくわかっていないのは、PublishとReceiveがトピックの指定であるのに対し、Subscribeがトピックフィルターの指定になっている点です。このあたりの考え方は、いずれわかり次第追記できればと思っていますが、一旦こういうものとして進めていきます。上図の赤枠の範囲内でポリシーを考えていきます。これを踏まえて、とりあえず以下のようにポリシーを作成しました。ポリシーの作成はコンソール上でベーシックモードとアドバンストモードを選んで入力できますが、以下はベーシックモードでの入力を想定しています。ID]:client/replaceWithAClientId”までが自動入力されるので、”replaceWithAClientId”の部分を、任意の文字列に置き換えます。ここでは”myM5StickC”にしていますが、ここで設定したクライアントIDをデバイス側のソースコード内に記述するクライアントIDと一致させる必要があるので注意してください。ベーシックモードでは、「ステートメントを追加」を押すと、追加のステートメントを入力できるようになります。許可メッセージをPublishするのは、”fromDevice”の方のトピックだけです。許可メッセージをReceiveするのは、”fromCloud”のトピックからだけです。許可メッセージをSubscribeするのも、”fromCloud”のトピックからだけです。“topic”ではなく”topicfilter”として許可していることに注意です。入力できたら、「作成」を押してポリシーの作成を完了させます。このあたりのポリシーの設定サンプルは、こちらの公式ドキュメントに記載があります。続いて、「管理」→「モノ」からモノを作成します。今回は「単一のモノ」を作成します。Registryにデバイスを追加」では色々入力項目がありますが、とりあえず名前だけ入れておけばOKです。ここでは”myM5StickC”としましたが、先のポリシーのクライアントIDと特に一致させる必要はありません。「モノに証明書を追加」では、「1-Click証明書作成(推奨)」を選びます。これだけで、このモノの証明書(xxxxxxxxxx-certificate.pem.crt)パブリックキー(xxxxxxxxxx-public.pem.key)プライベートキー(xxxxxxxxxx-private.pem.key)の3つのファイルが作成されるので、ダウンロードして保存しておきます。このうち、「モノの証明書」と「プライベートキー」の内容は、デバイス側のソースコード内に記述する必要があります(パブリックキーは使用しません)。ダウンロードする必要があります。1」のリンク先の文字列を”AmazonRootCA1.pem”などの名前で保存しておきます。これも、後でデバイス側のソースコード内に記述する必要があります。ルートCAの保存済んだら「有効化」をクリックし、証明書が正常に有効化されたことが通知されたら、「ポリシーをアタッチ」に進みます。ここで、先ほど作成していたポリシー”MqttOnly”を選択して、モノの作成・登録は完了です。以上でAWS側の作業は一旦終了です。続いてデバイス側の作業に入ります。前提条件M5StickCの開発環境は構築済みとします。一応、自分の方でも過去に環境構築した記録がありましたので、必要に応じてご参照ください。〜開発環境を構築する〜それから、追加でMQTT実装のためのライブラリ”PubSubClient”が必要になります。こちらは、ダウンロード頂いたのち、ソースコードを一部修正する必要があります(MQTT_MAX_PACKET_SIZEの変更)。このあたりは以下を参照させて頂きました。IoTを動かそうとしてハマったメモソースコード作成M5StickCの機能要件としては以下になります:Aボタン(「M5」のボタン)を押すと、整数値をAWSに送信・カウントアップAWS側から受信したメッセージを表示(JSONはパースして表示)以下、ソースコードの全文です。一部(ボタン処理など)、M5StickCに特化した記述が含まれていますが、こういう記事を読む人なら、おそらく純粋なESP32開発ボードやM5Stack用に修正するのは容易かと思います。ディスプレイへ送信内容を表示。IoT設定情報のところです。ここと、冒頭の無線LAN情報だけ、環境に合わせて書き換える必要があります。IoTメニューの左下「設定」から参照できる「カスタムエンドポイント」の内容を記載してください。AWS_PORTは固定値です。PUB_TOPICとSUB_TOPICの名前は、AWSのポリシーで記載したトピック名と必ず一致させてください。CLIENT_IDは、AWSのポリシーで記載したクライアントIDと必ず一致させてください。ルートCA1の内容を転記してください。CERTIFICATEは、先で保存しておいた”xxxxxxxxxx-certificate.pem.crt”の内容を転記してください。PRIVATE_KEYは、先で保存しておいた”xxxxxxxxxx-private.pem.key”の内容を転記してください。ソースコードが作成できたらM5StickCにプログラムを書き込んで、デバイス側の準備も完了です。AWS.”とディスプレイに表示されれば、接続成功です。おめでとうございます。うまくいかない場合は、クライアントIDやトピック名がポリシーとソースコードの間で異なっていないか、エンドポイントや証明書、プライベートキーの転記にミスがないかなどを確認してみてください。IoTのコンソール画面の「テスト」をクリックし、「トピックのサブスクリプション」の入力欄に”myTopic/fromDevice”と入力し、「トピックへのサブスクライブ」をクリックしてください。ちなみにこのとき、画面右上に「iotconsole-xxxxxxxxxxxxx-xとして接続」のように表示されていると思いますが、これがMQTTコンソールのクライアントIDのようです。テスト画面に入り直すたびに異なるIDが発行されます(←クリックして切断した後、自分で指定することも可能)。画面が遷移したあと、M5StickCのAボタンを押してください。M5StickCのディスプレイの”TX”に表示されている整数と同じ値がメッセージとして表示されれば、M5StickC側からのメッセージ送信は成功です。続いて、AWS側からのメッセージ送信のテストです。「トピックへの発行」をクリックしてください。入力欄に”myTopic/fromCloud”と入力し、「トピックに発行」をクリックしてください。Console”と表示されれば、AWS側からのメッセージ送信は成功です。最後に、M5StickC側の動作検証の様子を動画で載せておきます。https://make-muda.net/wp-content/uploads/2020/01/IMG_3213.mp4というわけで、M5StickCとAWSの双方向通信のトライアルでした。実際やってみた感想ですが、「めっちゃ反応早いな!」というのが正直なところです。宅内でダイレクトに通信してるのかと思うぐらい早かったです。MQTTという通信プロトコルの特性もあるのでしょうが、とりあえず片道分だけの通信に限って見れば、ものすごく早いと感じました。ここで終わるとあまり実用的な感じではなさそうなので、次はデバイスから送ったメッセージをAWSのLambdaで処理する、ぐらいのことをやってみたいと思います。(1セット)以下、自分がAWSの勉強用に読んでいる本です。資格をとるつもりはありませんが、AWSのサービスの概要を知るのには便利です。コメントをキャンセルメールアドレスが公開されることはありません。hidaka_hirojiAmazonほしいものリストこちら自身の工作用に使いたいものがメインですが、必ずしも工作に使うわけではないのでご了承ください。MUDAなことをしよう。