HaloCodeのCloudMessageを自前のMQTTブローカー経由で外部へ投げる


要旨

HaloCodeのCloud MessageはMQTTプロトコルのメッセージ通信であると仮定し、Heroku上へ構築した自前のMQTTブローカー経由で、HaloCode-他のMQTTクライアント間におけるメッセージ送受信を試してみた、という実験メモです。

結論からいうと送受信できました。

経緯

Makeblock社のHaloCodeというデバイスはWi-Fiモジュールを内蔵しており、単独で無線通信できるところが魅力のひとつです。

しかしWi-Fiモジュールを使った通信は、公式の開発環境mBlockにてあらかじめ用途が限定1されており、例えばサードパーティーの外部システムのAPIを直接HTTP通信で叩くようなプログラムは書くことができません2

Wi-Fi経由のメッセージ通信については通常、PCまたは他のMakeblock社のWi-Fi対応デバイスとだけ通信できるようになっているHaloCodeですが、その他のデバイスやサービスとも直接つなげることができれば活用の幅が広がりそうだと考え、2019/6/23時点で実現できる手段を探してみることにしました。

手がかり

公式ドキュメント3のAPI仕様のうち、cloud_message.startメソッドの項目を参照していたところ、mBlock内でCloud Messageと呼ばれている通信は単なるMQTTプロトコルでのメッセージ通信なのではないかと推測しました。
(特にサブドメインがmq.*になっているところ、デフォルトのポート番号が1883であるところを見て)

cloud_message.start(topic_head, client_id=None, server="mq.makeblock.com", port=1883, user=None, password=None, keepalive=60, ssl=False)

上記のcloud_message.startメソッドは複数のパラメータを指定できる仕様になっているため、ここに手を加えるだけで、外部のMQTTブローカーを経由してHaloCodeとメッセージ通信できるようになる可能性を感じました。

実験の準備

MQTTブローカー(MQTT通信を媒介するサーバー)を作り、そのMQTTブローカーを利用するプログラムをHaloCodeへアップロードして確かめてみることにしました。

MQTTブローカーを用意する

今回は他の方の記事4を参考にクラウドサービスのHerokuを用いて構築しましたので、ここでは詳細を割愛します。

(構築後の画面。ここで表示されている情報を後で使用する)

HaloCodeのプログラムを作る

まず次のようにブロックエディタで実装しました。次の3点が要点です。

  1. 本体のタクトスイッチを押せば"fromHaloCode"というCloud Messageを送信する
  2. "fromHeroku"というCloud Messageを受信したら本体のLEDが光る
  3. 標準のサーバーではなく、自分で用意したMQTTブローカーへ接続する

前述の3.を実現するのはこのままではダメなので、次にこのプログラムのPythonコードを表示し、Pythonエディタへ(コピペなどで)貼り付けます。

(これを)

(こちらへ)

最後に、cloud_message.startメソッドのパラメータを、先ほど構築したMQTTブローカーの情報に合わせて書き換えました。

実験とその結果

次の順に実験しました。

HaloCodeの電源を入れてMQTTブローカーに接続させてみる

Wi-Fi通信が有効になると、MQTTブローカー側の管理画面にてMQTTクライアントからのコネクション数が 1 と表示されるようになりました。



タクトスイッチを押してCloud Messageを送信してみる

スイッチを押すことでHaloCodeが送信した fromHaloCode というメッセージを、他のMQTTクライアント(ここではMQTTブローカーの管理画面に内蔵されたWEBクライアント)で検出することができました。

メッセージに含まれる情報のうち、 Topic とはHaloCodeのプログラムのうちcloud_message.startメソッドで {TOPIC} と指定した部分のことです。

この {TOPIC} という文字列はPythonコードを自動生成された時点ですでに書き込まれているもので、このまま利用するとmBlock用のユーザー情報?を指す文字列へ勝手に変換されます。そのため下記画像ではその部分をマスクしてあります。

他のMQTTクライアントからHaloCode向けのメッセージを送信してみる

他のMQTTクライアント(ここではMQTTブローカーの管理画面に内蔵されたWEBクライアント)を使って fromHeroku というメッセージを送信したところ、HaloCodeにそのメッセージが届いたことを確認5できました。

(下図はメッセージを送信しようという場面。図左側の Send Message 欄へ送信したいメッセージ内容を指定して Send ボタンを押した。)

実験にあたっての注意点は2つあります。

まず Topic はcloud_message.startメソッドの第一パラメータで指定した文字列と同じにする必要があります。前述した {TOPIC} を使用した場合、変換後の文字列を指定しなければなりません。

もう一つは Message{"message":"", "value":""} というJSON形式で表現しなければならない点です。ここではHaloCodeのプログラムでfromHerokuメッセージであると認識してもらうためには、 {"message":"fromHeroku", "value":""} という文字列を送信する必要があります。

まとめ

以上の実験から、Cloud Messageの実態はMQTT通信であり、mBlockによって自動生成されたPythonコードを書き換えることによって、自分で用意したMQTTブローカーを通じて外部のMQTTクライアントとも通信できることを確認できました。

今回の通信手段を応用して何かシステムを作ってみることにも関心ありますが、機会を改めます。

こうして外部システムと通信する方法はいずれ公式にも用意される気がします6が、取り急ぎHaloCodeを既存のシステムと連携して利用したいときに、このメモが役立つかもしれません。


  1. 公式の開発環境mBlockにおいて、Makeblock社のサーバーを使ってインターネット経由でデバイス間メッセージ通信を行う「Cloud Message」と、スター型ネットワークをアドホックに構成して直接デバイス間メッセージ通信を行う「LAN」の2種類しか2019/6/23時点で用意されていないことを指しています。 

  2. Pythonが使えると聞いて、本当はrequestsモジュールまたはurllibモジュールをimportして直接http通信したかったのですが、mBlock v5.0.1のPythonエディタではそれぞれ ImportError: no module named requestsImportError: no module named urllib となり利用できませんでした。Pythonのモジュールを新たにインストールする方法は、本記事記載時点ではまだ見つけることができていません。 

  3. Python API Reference 

  4. 爆速でMQTTのパブリックBroker環境を作る方法、Raspberry Pi からアクセスできる各パブリッククラウドの比較 

  5. HaloCodeのLEDがアニメーション点滅したことによって目視で確認。実物の写真は割愛。 

  6. https://forum.makeblock.com/t/openness-of-the-makeblock-app-towards-3rd-party-cloud-platforms-and-or-apps/12551