FlexiSpot の高さを Raspberry Pi につないで計測する

これは CAMPHOR- Advent Calendar 2022 の20日目の記事です。

こんにちは、この記事では FlexiSopt に接続して高さを出力する Prometheus Exporter を使ったので、それを紹介します。

作るに至った経緯

今年の春に新社会人になったタイミングで FlexiSpot E71 を購入しました。
スタンディングデスクを使ってる人にありがちなのが、「最初は立って仕事をしていたがしばらくしてからはずっと座ってばかりでただの机になってしまっている」という現象です。
しかし、ずっと座ってばかりいることが健康に悪いことは様々な研究などでも指摘されており、このような「座りすぎ」の状況は一刻も早く改善されるべきです。

一般論として、問題解決のためにあるソリューションを導入した後にはそれらを適切にモニタリングする必要があります。
健康のために、座りすぎと言うという問題を解消するためにスタンディングデスクを導入したわけですから、その使用状況はモニタリングされているのが適切でしょう。
そこで、今回の記事では FlexiSpot を Raspberry Pi に接続してその高さを計測する方法を紹介します。
(ここで紹介する方法は FlexiSpot が公式に推奨しているものではありませんので真似する際には自己責任でお願いします。)

接続回りのハードウェア

Flexi Spot の昇降に関わるモジュールは大きく分けて、モーター、リモコン、コントローラーがあり、コントローラーにその他のモジュールや電源が接続されています。

コントローラーとリモコンを繋ぐ端子は RJ45 (いわゆる「LANケーブル」 で使用される端子) でしかも2つあります。そのうち1つはリモコンへの接続に使用されますが、残る1つは未使用の状態で残されているわけです。これはもう何かを繋いでくれと言ってるも同然です!

実際に他にも同じことを考えてる人はいるようで、すでにリモコンと同様の機能をもつプログラムが GitHub 上に存在し、それらの調査は非常に参考になります2。E7 のモデルに関する記述はここにはありませんが、リモコンを分解して中の基板にある記述を確認したらところ、EK5 などと同じ配置のようです。(以下の画像はリモコンの基盤部分を撮影したものです。)

ケーブルの端子に RJ45 が使用されているとはいってもその通信内容は Ethernet などではなく、シリアル通信が行われています。Cisco のルーターなどでもRJ45 端子を使用したシリアル通信が行われていますが、それとはピン配置が違うようです。

参考にした GitHub Repository に書かれている PIN 配置を基に、 Raspberry Pi との接続方法を以下に記述します。 Raspberry Pi の Pin 配置に関しては公式のドキュメントを3参照してください。 (「役割」のカラムは Flexi Spot から見た役割で、 RX・TX は Raspberry Pi 側から見たものとは逆になります。)

JR45 の PIN 番号役割Raspberry Pi の GPIO
4GNDGND
5TXGPIO 15 (RX)
6RXGPIO 14 (TX)

この表にある通りRaspberry Pi の UART ポートを介して通信しています。

ソフトウェアの動き

先述の通り、FlexiSpot と Raspberry Pi を接続してリモコンの機能をさせるためのプログラムはすでに存在します。

しかしながら、それらはリモコンのようにFlexiSpot を操作するのが主目的となっており高さをモニタリングするのに適したプログラムにはなっていないようです。
そこで、今回は FlexiSpot の高さをモニタリングし、その情報を出力する Prometheus Exporter を作りました。
いくつかの GitHub Repository の情報によると、 Flexi Spot の現在の高さを伝えるパケットは以下の構造をしているようです。

0123-56-78
開始byte長さパケットタイプリモコンに表示される数字チェックサム終了byte

ちなみに開始、終了バイトはそれぞれ 0x9B0x9D で、机の高さを伝えるときのパケットタイプは 0x07 です。 (チェックサムの計算方法はここではあまり重要ではないので割愛します。)
また、このパケットは常に送られてくるのではなく、リモコンにあるパネルのLED が点灯している時のみ送られてきていることが分かりました。(どちらかといえばパケットが送られてくる間のみ LED が点灯する、と解釈すべきでしょうが。)

パケットの body の3 byte はそれぞれの 8 セグ LED の点灯状態を表しています。このbyte列をパースすることにより高さを取得することができます。
Raspberry Pi 上で動作するプログラムは Rust を使用して上述の処理を記述しています。
高さに関する情報が送られてこない時には高さは変化していないものとして処理しています。

できたもの

今回作成したプログラムは GitHub にて公開しています。

Repository の URL はこちらです https://github.com/KMConner/flexi-receiver

以下の画像のような感じで、 Prometheus の Web UI 上で机の高さを確認することができます。(Prometheus 側の Target に関する設定などは検索すればいくらでも情報が出てくるのでここでは割愛します)

Prometheus 上で高さのグラフを描画した様子

今後はこれを Grafana などの可視化ツールで1日あたりどれくらい立っていたかなどを確認できるようにしたいと考えています。

終わりに

この記事では FlexiSpot と通信して高さをモニタリングする方法を紹介しました。

FlexiSpot を持っているものの有効活用できていないと感じている人は是非参考にしてみてください!

明日は Saza さんの担当です。 どんな記事なのでしょうか??お楽しみに!