あのGPSガジェットからの情報をインターネット経由で飛ばしたい
GPSガジェットからは、現在地と目的地までの距離とがとれているので、迎えに行ったり待たせたりしているときに、いまこの辺ですよとか、目的地まであと何キロです、のようなメッセージを送ることができるといいなあ、と考えていました。運転中の操作なので、できればボタンひとつで済むような簡単操作にしたい。
メッセージは家族専用group chat、「パパチカ(近)」に届くようにしました。
GPSガジェットからの情報は、software serial portをもう一つ追加して、シリアル通信で引き出します。受け手側にはAdafruitのQt Py ESP32-S3を使いました。小さなボードで邪魔にならず、wifi接続とcircuitpythonでのコーディングが可能なスゴイやつです。ケータイのホットスポット経由でインターネットに接続させます。
telegramに送られたメッセージ
一例を以下に示します。こんな感じでメッセージが届きます(北緯130度???一部情報を加工しています😛)。
ボタン1は目的地に着いたとき用。「ついたぜ!」メッセージが飛びます。ボタン2は、現在地にピンのついたGoogle MapのURLを送信するのに使います。メッセージ中のリンク、「Google Map URL」をタップすると地図で現在地を見ることができます。ボタン3は目的地までの距離を送信します。
ガジェットへの接続図
これまでに指さしユニットとbluetoothユニットとを増設したので、もしかしてピンが空いてないかも、思いましたが、A2, A3が空いていました。それぞれtxPin, rxPinとして使いました。Qt Py ESP32-S3側が3.3V logicなので、Rxへの入力に抵抗分圧を挟んでいます。(これまでの増設分も入っているので、配線図がものすごく込みあってしまいました)ボタンにはAdafruitのNeokey 1×4、スイッチもAdafruitから買えます。Cherry mx compatibleのものが使えます。
手作りキーキャップ
A、Bレジンを混ぜて固めるものを使ってオリジナルキーキャップを作りました。鋳型は、1U、Kitty PawともにAdafruitから購入しました。
Kitty Pawのほうは、レジンが角までうまく満たされていないことに気が付かず、欠けてしまいましたが、かわいらしいのでよしとしました。
telegram botの使い方
Telegramのgroupにプログラムからメッセージを送りたいわけですが、そのためには次の二つに対する答えが必要です。
- だれが送るのか — (1)
- どのgroupに送るのか — (2)
bot token、chat idがそれぞれの答えに対応します。
プログラムからメッセージを送信する際には、電話番号に紐づいている本人としてではなく、botに送信(代理人)を頼むことになります。(簡単に本人としてプログラムから送信できるようでは、ナリスマシが横行することになってしまいます)
botにはbot tokenと呼ばれる文字列が与えられます。プログラムはそれを使ってbot役を名乗ります。
次に、どのgroupに送るのかですが、telegram上での会話にはそれぞれchat idが割り当てられています。groupのchat idを調べることで、メッセージの行先を指定することができます。
それではvamos、我们走吧。
botを作ってbot tokenを得る
ここはstraight forwardです。まず、BotFatherに/start(/helpでも同じ)と話しかけてみてください。
次のようなコマンド一覧がでます。
/newbotで作成開始です。
(1)まず、ボットの呼び名をつけましょう。これと、次につけるusernameとを混同しないようにしましょう。呼び名は、チャットリストに表示される名前です。日本語でもつけることができました。
(2)次にusernameです。これはbotで終わる必要があります。すべてアルファベットでつけましょう。アンダースコアbotでも(_bot)、例のように最後が大文字スタートのBotでも通ります。
(3)に表示されるのがbot tokenです。(モザイクで隠してあります)これをどこかにコピーしておきましょう。これがあるとbotの名乗りができてしまうので、公開してはいけません。もし、モレが疑われる場合には、BotFatherに/revokeをお願いしましょう。
しまった、コピーするのを忘れてしまった、というときでも大丈夫です。BotFatherとの会話が残っているはずですし、もし会話が消えてしまっていても、/tokenと打つと、教えてもらえます。(botが複数ある場合には、どれの?と聞いてくれます)
ちなみに(4)をクリックし、表示される会話画面の一番下のSTARTをクリックするとbotとの会話が始まり、ボットの名前が左のリストに登場します。
bot tokenが取れましたので、次へ移りましょう。
groupのchat idを調べる
普段、chat idを知る必要はまるでありませんので、メニューからクリック、のような方法ではchat idを調べることができません。
まずは手順を見ておきましょう。
- groupを作ってbotをメンバーに加える
- http apiをたたいてbotの会話記録を見る(jsonの形で返ってくる)
- group chatでbotの読めるメッセージを送る(/で文を始める)
- もう一度http apiをたたく。さっきなかった会話記録が追加されているはず
- 追加された部分からchat idを探し出して記録
めんどくさ。
ですね。でも一度だけですから、辛抱して元気に行きましょう。
groupを作ってbotをメンバーに加える
1.左上の三本線をクリック。
2.New Groupをクリック。
3.名前を付けて、4.Nextをクリック。
5.検索欄がでますので、作ったbotのusername、あるいは呼び名で検索。似たものが出る可能性がありますので、6.よく見て正しいものをクリック。
7.右下のCreateをクリック。
これで、あなたとbotの入ったグループができたはずです。
http apiをたたく その1
apiをたたく、などと書いていますが、下のようなURLを用意して、ブラウザでアクセスすることです。botのあとの、<token>部分を上でコピーしておいたbot tokenに置き換えてください。私の場合、数字10桁のあとコロン、そのあと35文字のアルファベットです。”bot”のあとに続けてください。
置き換えたURLをブラウザーのURLバーに用意したURLを入れて、リターン。json形式のデータが帰ってきてそのまま表示されます。
私の場合、次のような空っぽのデータが表示されました。もっと長いものがでるぞー、という場合もそのまま次へ進んでください。(すでに会話をしましたね)
botの読めるメッセージを送る
先ほど作ったgroupで、メッセージを送ります。groupでは、slash(/)で始めたメッセージだけをbotは見ることができます。/ではじめて、なにか打ってみてください。
ちなみに、botに直接メッセージする場合にはslashはいりません。
そのまま次へ進みます。
http apiをたたく その2
もう一度、先ほど作ったURLにアクセスします。新しくtabを開いてアクセスすると、最初のアクセスの時に帰ってきたデータと比較がしやすいです。
一回目のアクセスの時よりもデータが長くなっていますね。いや、変わらないぞ、という場合には、もう一度slashで始まるメッセージを打ってからURLにアクセスしてみてください。
どうでしょう。このURLは、ところでこのbotちゃんの、最近の会話データを教えて、というもので、返事はjsonと呼ばれる形式でapi.telegram.orgから帰ってきます。
もう一度URLをよく見ると、なるほど、そうか、と思えますね。
https://domain/このbotについて/updateをゲットしたい
というリクエストをしているわけです。bot tokenさえあれば、だれのbotに関しても情報がとれてしまうことになります。”これがあるとbotの名乗りができてしまう”と上で書いたのは、この意味です。bot tokenは慎重に管理してください。
chat idを探し出す
さて、先ほどのjsonデータをよくよく眺めます。とくに、メッセージを送ったあとに追加された部分をよく見ます。“chat”:{“id”: という部分を見つけてください。その、id:の後の部分、マイナスサインではじまっている数字のならび、下の図でココと書いてあるところにあるもの、それがchat idです。マイナスサインも含めたものがchat idです。どこかにコピーしておきます。お疲れ様でした。
👉注意:botに直接メッセージを送ったり、botを複数のgroupに入れたりしている場合、異なるchat idが見られるはずです。目的のgroupのchat idを探し出すには、上で行ったように、apiをたたき、メッセージを送って、再度apiをたたく、を行い、増分からchat idを得るようにすればどのchat idが目的のものなのかがわかります。
さて、bot tokenとchat idがとれました。これで、プログラムからbotを名乗り、目的のgroupへメッセージを送ることができますよ。
せっかくですから、ちょっと実験してみましょう。プログラムからやることは、URLを構築してhttpリクエストとして送る、です。これはプログラムからやらなくても試すことができます。
main.pyの中に、下のような関数を書きました。
91-92行でRULを作っています。じーっと見ますと、こうなんじゃない?って見えますね。そうです。そうなんです。
手作りしてみましょう。
<bot token>の部分はあなたのbot tokenに、<chat id>はあなたのgroupのchat idに置き換えて、text=のあとに何か。できたらブラウザのURLバーに入れてリターン。
おおお!キター!
うれしいです、そんなに喜んでくれて。
ここからはArduino側と、esp32-s3側で使ったpythonコードに関する説明です。もし興味があればどうぞ。codeはGitHubにのせてあります。
用いたcodeについて
GPSガジェット側codeの追加部分 (Arduino)
Software serial portをA2, A3ピンを指定してもう一つ作り、setup()中でbegin(9600)、あとはloop中で目的地、緯度、経度、目的地までの距離、の4つをカンマ区切りでprint、print後は忘れずにGPSのつながったシリアルに振りなおす、が追加部分です。codeはGitHubにあります(myGPS-7seg-servo-ble-esp32-s3.ino)ので、追加した行たちのみ下に示します。
// myGPS-7seg-servo-ble-esp32-s3.ino より
// 3つ目のsoftware serial portを作る
SoftwareSerial mySerial3(A3, A2); // rxPin, txPin
// setup()中
mySerial3.begin(9600);
// あとはloop()中で
mySerial3.print(dest_num); mySerial3.print(",");
mySerial3.print(mov_lat, 6); mySerial3.print(",");
mySerial3.print(mov_lon, 6); mySerial3.print(",");
mySerial3.println(d_to_dest);
// switch back to mySerial (GPS)
mySerial.listen();
Qt Py ESP32-S3側のcode(Circuitpython)
Circuitpythonとライブラリについて
CircuitpythonについてはAdafruitのページにある説明を読んでいただきたいのですが、まず知っておくべき要点の一部は以下の通りです。
- circuitpythonを(マイクロコントローラー)ボードにインストールして使う。その実体はuf2を拡張子にもつひとつのファイル。これが、code.py、main.pyなどと名付けられたファイルとボードとを仲立ちすることでpython codeが実行される。
- ボードが対応している、というより、ボードに対応したcircuitpythonが用意されている必要がある。自分の使いたいボード用のcircuitpythonがあるかどうかは、circuitpython downloadのページで調べることができる。使いたいボード用のcircuitpythonファイルをダウンロードしてボードにインストールする。
- ライブラリは、バンドル(zipファイル)として配布されている。日々メインテナンスされており、頻繁にアップデートされる。バンドルの中から必要なものだけをボードのlibraryフォルダにコピーして使う。初期のころは全部コピーできるほどしか整備されていなかったが、今の充実度はその頃の比ではない。libraryやdocumentationの整備に尽力してくれているAdafruitはじめ、コミュニティーの皆様には感謝の念しかありません。
今回用いたcircuitpythonとバンドルのバージョンは以下の通りです。circuitpythonのバージョンが8.0.5だったので、ライブラリも8.xのほうをとりました。7.xのものもライブラリのページには見えましたので、間違えないようにします。
- adafruit-circuitpython-adafruit_qtpy_esp32s3_nopsram-en_US-8.0.5.uf2
- adafruit-circuitpython-bundle-8.x-mpy-20230408 (zip fileとして取ります)
codeとlibrary
CodeはGitHubに置いておきました。main.pyが名前の通りmainのcodeです。今回、wifiへの接続情報と、telegram botのtoken、chatのidが必要ですが、それらはmain.pyへは書き込まず、別ファイル、mycreds.pyに情報を保存しています。(こうしておくとファイルを配布する際に、mycreds.pyだけに気を付ければいいので便利なのです)
mycreds.pyにはdictを一つ作り、その中に上の情報を書き込みます。
# mycreds.py
# papa-chika project
secrets = {
# wifi APへの接続情報。
# ssidとpasswordとをタプルにいれてリストにしておく。
# リストにある順に接続が試される。
'ap-info': [
('ssid1をここへ', 'ssid1へのパスワード'), # 例えばケータイのホットスポット
('ssid2をここへ', 'ssid2へのパスワード') # 例えば家のwifi
],
# bot
'token': "bot tokenをここへ",
'chatid': "chat idをここへ"
}
libraryフォルダには以下のものを入れて使いました。
使ってみて
あまり家族からの目立った反応はなく、さみしい感じがしないでもないですが、ひとまず自分の位置やら「ついたぜ!」メッセージをボタン一つで送信できるのは便利です、と思いたい。
それにしてもQt Py ESP32-S3、すごいです。みなさんも何か工作してみてください。