M5Stack CoreInkをダッシュボードにつかう
BME280とCCS811を使って、部屋の環境データを取得してる。
取得したデータはPrometheusに集積して、グラフにして見たりしてる。
台風がきた時のグラフ
しかし、ページを開かないと見れない。
気圧が下がってきている時は頭痛に気をつけたり、 部屋のCO2濃度が上がってきたら換気をするようにしたいが、 ページを見ていないと気がつかない。
そこで、これを常に表示するダッシュボードを作ろうと思った。 常に表示するなら電子ペーパーがいい。
デバイスとして買うならM5 Paperがいいと思ったんだが、 M5 Paperは品薄で買えない。 そこで、画面が小さいけど電子ペーパーをもってるM5Stack CoreInkを買った。
これは200x200の解像度の電子ペーパーと、ESP32を搭載してる。
最初はPrometheusからデータをダウンロードして画面に表示するプログラムをC++で書いて、ESP32で動かそうと考えたが、 考えただけで面倒になった。
他の方法として、Prometheusを動かしているサーバーで、画像を生成して、それをCoreInkでダウンロードして表示する方法を考えた。
CoreInk側
探すと先人がいたので、参考にさせてもらった。
M5Stack CoreInkをWeb経由で取得して表示するやつ作った記録
この記事のCoreInk側のコードを参考にした、 ただし、この記事では、独自の画像フォーマットに変換した物を送っている。 それだとデバッグが大変だし、サイズも大きそうなので、 普通の2値BMPを読む用に変えた。
2値BMPを読むのは、
- 10-13バイト目にあるヘッダサイズ分を読み飛ばす。
- 各行のデータは4の倍数バイトでなければならない
- 200ピクセルは25バイトなので、3バイト余白があって1行28バイトになる。
- Y軸が下から上なので反転する必要がある
という点に気をつければ、ESP32でもBMPファイルを読める。
サーバー
サーバー側は、
を参考にした。
これはchromeのヘッドレスモードを使って、用意したHTMLのスクリーンショットを作る。 HTMLだと自由度が高くUIが簡単に定義できそうでいい。 元コードはPNGでそのまま吐いているが、今回はBMPで吐きたい。
そこで、jimpというモジュールを使って、 PNGをBMPに変換しようとしたが、jimpは2値bmpは生成できなかった。
そこで、単純にimagemagicで変換した。
await spawn("convert", [
input,
"-colors","2",
"+dither",
"-type","bilevel",
output ,
]);
HTML
最後にダッシュボードになるHTMLを書いた。
PrometheusのAPIで データは習得できる。
取得したデータは、chart.jsでグラフを書いた。
冷蔵庫に貼っておいて離れて見るので、 数字は大きめに書いた。