われがわログ

最適化アルゴリズムとかプログラミングについて書きたい

温湿度計付き置時計 MHO-C303 へのラズパイからの時刻同期

210411追記

MHO-C303は廃版になったもよう、、

CO2計測ついでに湿度もロギングしたいなぁと思って色々調べた結果、 Xiaomi製、温湿度計付き置時計 MHO-C303を買った。*1

旧機種のlywsd02とは違い、電池が単4二つになっているので長持ちするのではと思う。ただ、要らない機能(タイマー?使ったないのでよくわからん)のためにタッチ式ボタンが上側についており、持ち上げるたびに誤作動するのが不満。 また、湿度がEMPEXのアナログ式のものに比べて10%程度高く、どっちが真値なのかよくわからない。体感的にはEMPEXのに近いが、体のセンサはあてにならんことだし。

このMHO-C303であるが、Bluetooth LEによる通信機能が付いており、スマートホン向け専用アプリ(Mi Home)で接続&時刻同期できる。 そして、本機種は例によってハックされており、ラズパイからでもデータ取得&時刻同期が可能である。 具体的には以下のPythonライブラリを使えばよい。

github.com

旧機種向けだが、MHO-C303に対しても問題なく動いた。 なお、温湿度データ、バッテリレベルはadvertiseもされているとのこと。

tasmota.github.io

さて、C++に移植するか、ということで成果物がこちら。

github.com

データ取得機能はなく(思ったより湿度が不正確だったので作るモチベを失った)、時刻をラズパイと同期するだけの簡単なプログラムである。 これでめんどくさい、スマホを使った同期から解放される。 なお、BluetoothのCライブラリとしてはgattlibを使っている。 ライブラリを使う際にハマったのが、スキャンした直後でないと機器に接続できないということ。 MACアドレスさえわかれば接続できるでしょ、と思っていたのだが、どうやら違ったようだ(バグじゃないよな?)。 というわけで上記プログラムでは、一度接続してみてダメだったらスキャン&再接続する、という微妙なロジックになっている。

最近色々C++でプログラムを書いて思ったのは、C++はCの資産をシームレスに使えるのが便利だ、ということ。 PythonGolang、Rustだとひと手間必要だし。 加えて、C++17ならかなりモダンな感じで書けるのがよい。 パッケージ管理がないとか、ビルドファイル書くのがめんどいとか、標準ライブラリのカバー範囲が狭いとか、テンプレートに関するエラーがわかりづらいとか、辛い点は色々あるのだけれど。。

追記

MHO-C303と同じセンサを搭載したENV IIで測定した湿度は、EMPEXのものとほぼ同等の値だった。 やはりXiaomiの値がズレている?何か変なロジックでも入っているのだろうか。

*1:実はMHO-C401も買った。完全に無駄だったが。