在宅か不在かを家族に伝えるMQTTクライアントを作った話
Table of Contents
こんにちは、初めまして。鈴木孝宏と申します。 LTということで、細かなプロフィールは割愛しまして、本題に入っていきたいと思います。 (プロフィールはトップページで)
私には、妻と2人の子どもがおります。そんな我が家ですが、再来週から、2ヶ月かけて引越しをすることになっています。僕が先に、地元の札幌へ帰り、2ヶ月後、妻と子どもたちが合流します。
この間、やはり問題になるのは、コミュニケーションです。在宅の仕事中に電話がかかってくる可能性や、お風呂に入っている間に電話がかかってくる可能性が、ないとは言い切れません。
そこで、私が電話を取れる状態かどうかを伝えるデバイス(MQTTクライアント)を製作しました。
このように、会議中であることを表示されます。こうすることで、仮に僕が電話に出なくても、家族は不安にならずに済むことができます。
システムの全体像 #
それでは、システムの全体像の説明です。 登場人物は、札幌側の送信デバイス、MQTT1ブローカー、そして埼玉側の表示デバイスです。
MQTTブローカーとは何かと言いますと、これはいわゆるサーバーです。 札幌側のデバイスが発信した情報を、埼玉側の表示デバイスへと仲介するサーバーのことです。 今回は、HiveMQというプラットフォームを使用しました。
なお、札幌側のiPhoneでは「MQTTAnalyzer」を、埼玉側の表示デバイスは「ESP-WROOM-02」2を使用しました。
データの流れ #
まず、埼玉側の表示デバイスは、電源を入れた時に3つのことを行います。 Wi-Fiに接続し、MQTTブローカーに接続、そして「sapporo/status」というトピック3をSubscribeして待機します。これで終了です。 札幌側のスマホは、会議を開始する時刻になったら、「会議中」というメッセージを「sapporo/status」トピックでPublishします。これだけです。 あとは、MQTTブローカが、Publisherから受けたデータを、トピックのSubscriberに対して一斉配布します。埼玉側の表示デバイスでは、受け取ったメッセージをパースして、画面に表示します。 以上が、システムの全体像です。
仕様など(LTでは割愛) #
実際に送受信しているデータと、表示(クリック or タップで展開)
送受信するメッセージの仕様 #
先ほどの図では、わかりやすいようにJSONで描きましたが、今回製作したシステムでは改行区切りのデータを送受信しています。 その理由は、メッセージのテキストデータを少しでも小さくしたいこと、改行で区切るだけなのでパースのコストが低い、仕様は自分さえ分かっていれば良いということから、この仕様にしています。
用途 | 送信メッセージ | 仕様 | 表示 |
---|---|---|---|
解除(通話可能) | 0 ${MESSAGE} |
1行目に0 、2行目にメッセージ |
黒画面。メッセージ行があればそれを表示。 |
ねてる | 1 ${MESSAGE} |
1行目に1 、2行目にメッセージ |
青画面。「ねてる」の文字。メッセージ行があればそれを表示。 |
そと | 2 ${MESSAGE} |
1行目に2 、2行目にメッセージ |
青画面。「そと」の文字。メッセージ行があればそれを表示。 |
会議中 | 3 ${MESSAGE} |
1行目に3 、2行目にメッセージ |
赤画面。「会議中」の文字。メッセージ行があればそれを表示。 |
おふろ | 4 ${MESSAGE} |
1行目に4 、2行目にメッセージ |
青画面。「おふろ」の文字。メッセージ行があればそれを表示。 |
警告 | 5 ${TITLE} ${MESSAGE} |
1行目に5 、2行目にタイトル、3行目にメッセージ |
黄色画面。タイトルとメッセージはカスタム。緊急用。 |
スケジュール | 6 ${MESSAGE} ${MESSAGE} … |
1行目に6 、2行目以降にメッセージ。複数行可能。 |
青画面。2行目以降のテキストが、そのまま表示される。 |
送信側の設定 #
送信するiPhoneでは、あらかじめ「MQTTAnalyzer」をAppStoreからダウンロード・インストールしておきます。 「ショートカット」アプリを使用して、メッセージをPublishするワークフローを、あらかじめ準備しておきます。 ショートカットができたら、それを「コントロールセンター」に追加します。
ショートカットを設定 | 設定内容 | コントロールセンター |
---|---|---|
受信機 #
実装できた。
— 鈴木 孝宏 (@sussan0416) January 9, 2025
これでやっと、7年前に買ったESP-WROOM-02(のDIP化基板)に役目を与えられた。 pic.twitter.com/gcxgO4L1LC
得た教訓 #
ここからは、今回の製作を通して得た教訓を、2つ紹介したいと思います。
急ぐ時ほど、プリント基板に頼ろう #
当初、「時間もないし、ユニバーサル基盤でいっか!」と思っていました。その勢いで作り始めたところ失敗。一通りのはんだ付けが終わっても、電気が導通せず4、ついに諦めてKiCadで設計することにしました。急ぐ時ほど、実装が確実なプリント基板に頼るのが良さそうです。
夜更かしして基板を設計してはいけない #
夜更かししながら設計すると、基盤のパターンを間違えて描くんですね。3.3VからGNDへそのまま流れていく回路になっていました。 プリント基板は中国の深圳で製造して発送5されるですが、このミスに気づいた時にはもう、成田空港に届いていました。
結局、違うタイプのボタンを実装することにして、ことなきを得ました(最後の2個だった)。
まとめ #
ということで、今回は、自分の在宅状況を家族に伝えるデバイスの製作と、それを通して得た教訓をお話ししました。MQTTを活用することで、離れていても簡単に状況を共有できる仕組みを実現することができました。皆さんもぜひ、急ぐときこそ技術に頼るということ、あと、やっぱり夜更かしは良くないということを、心に留めておいてもらえたらと思います。以上で、私の発表を終わります。
番外編 #
最初は、たまごっちの赤外線通信をハックして、札幌と埼玉で遠隔赤外線通信をやろうとしていた。 赤外線を受信したデバイスから、赤外線を送信するデバイスまで0.5秒で到達できるけど、それでもうまく通信できなかった。 MQTT自体は面白いので、このときに使用したプログラムが、今回の製作につながっています。
(たまコネ)遠隔で双方向に赤外線通信するのは困難だった。
— 鈴木 孝宏 (@sussan0416) December 29, 2024
最初のハンドシェイクっぽい通信の後は、通信のタイミングがシビアな感じだった。(SYN-ACKを出した側が、すぐACKを受け取れないとエラーさせている感じ)
通信経路として使ったMQTT自体は面白いから、また別の何かを作るときに使おう。
-
Pub/Sub型の通信プロトコルの名称。HTTPと比べてヘッダサイズが最小2バイトと小さく、処理負荷が小さい等の理由により、IoTデバイスでは標準の通信プロトコルになっている。 ↩︎
-
ESP-WROOM-02を使うことは、最近はほぼありません。ESP32シリーズに置き換わっています。これは2018年ごろに買ったものでして、ついに、やっと役割を与えられたという…。我が家にあったESP-WROOM-02は、これで全部使い切りました。 ↩︎
-
送受信するメッセージを区別するキーになるもの。いわゆる「スレ」のようなもの。例えば「myhouse/living/temperature」のように
/
で階層構造を作ることができる。さらに、myhouse/living/#
のようにしてリビングの全デバイスを対象にしたり、myhouse/+/temperature
のように、自宅の全温度計を対象にしたりすることができる。 ↩︎ -
テスターで何回試しても、USB電源のところに5Vがかかっているだけで、それ以降、導通している気配がなかった。もちろんレギュレータにも到達せず。 ↩︎