前回は分割キーボード Jiffy75 から SwitchBot のスマート電球を操作する方法を投稿した。
この投稿の中で、スマート電球の操作に Home Assistant を入れたラズパイを使っていることを紹介していたが、実は使える状態になる前に「スマート電球の操作が遅延する」という事象があった。
原因は Home Assistant を入れたラズパイの Linux カーネルにあって、Linux カーネルを更新すると遅延は解消した。
今回はその原因と対策の流れを記録しておく。
遅延が発生するまで
ラズパイから Bluetooth 接続でスマート電球を操作できることを確認するために、最初はまっさらなラズパイに Home Assistant を入れていた。Raspberry Pi Imager で Home Assistant OS を選択して MicroSD カードに焼くだけ。

OS イメージを焼いたらラズパイを起動して、PC からブラウザで Home Assistant にアクセス、Bluetooth でスマート電球に接続する設定を入れるだけ。
Bluetooth 接続した状態でスマート電球を操作できることを確認したので、前回の投稿通り分割キーボード Jiffy75 からスマート電球を操作できるように Hammerspoon 周りを用意した。
この時点で遅延はなかった。
Home Assistant 専用のラズパイをそのまま使おうと思ったけど、今となっては高価なラズパイをスマート電球の操作のために 1 台使ってしまうのは勿体ないと思った。
そこで、既に動かしている Flightradar24 用のラズパイに Home Assistant を同居させることにした。Flightradar24 用ラズパイには Debian を入れていて、家の近くの飛行機から位置情報を受信できるように ADS-B 受信機を接続している。
ADS-B 受信機の選定やラズパイの設定はこの記事を参考にした。
動作確認をしていた Home Assistant 専用ラズパイに Flightradar24 の設定を入れるパターンも考えた。
だけど、Flightradar24 用のサービスを Home Assistant OS で動かせるか不明だったのと、 Home Assistant のコンテナイメージが提供されていて Flightradar24 側のラズパイにコンテナで Home Assistant を動かすほうが簡単そうだった。
Flightradar24 用ラズパイでコンテナを使えるようにして、Home Assistant コンテナを立ち上げるとあっさり Home Assistant から Bluetooth でスマート電球に接続できた。
これでラズパイ 1 台でスマート電球の操作も Flightradar24 も運用できる、と思った矢先、冒頭のスマート電球の操作で遅延が起きることが分かった。Jiffy75 のロータリーエンコーダーを使ってスマート電球の操作をしても 15 秒ほど反応しなかった。クラウド API 経由の操作と比べても圧倒的に遅い。どうしてこうなった。
遅延の調査
せっかくラズパイ 1 台に集約したのに、こんなに操作に遅延していては使い物にならない。用途ごとにラズパイを分けるか悩んだが、ダメ元で AI と原因調査をしてみることにした。
まずは上位レイヤーから切り分けをした。分割キーボード Jiffy75 のロータリーエンコーダーを操作すると PC で常駐している Hammerspoon を通じて Home Assistant の API を叩くようになっている。API 経由で Home Assistant が Bluetooth 接続しているスマート電球を操作してくれる。
ラズパイの集約によって Home Assistant を動かすラズパイが変わったので、Hammerspoon から叩く API の向き先を変えていた。旧 Home Assistant に向き先を戻してみると、遅延は発生しなかった。
一方、新 Home Assistant の GUI を直接操作すると遅延が発生した。PC (Hammerspoon) から Home Assistant の経路に原因はなく、やっぱり新 Home Assistant 側に問題があるらしい。
新旧のラズパイは同じモデル (Raspberry Pi 4B のメモリ 4GB) なので、OS 周りに原因がありそう。Flightradar24 関連が悪さしている可能性もあったけど、Home Assistant からスマート電球を操作するまでの経路での遅延箇所を特定するようにした。
Home Assistant からスマート電球までの経路は下図のようになっているらしい。ここらへんは AI にサポートしてもらった。これが正しいのかどうか裏付けできないのでやっぱり知識は必要、と思いつつ今回はこのまま調査を進めた。

まずは Home Assistant から BlueZ への経路に遅延がないか。BlueZ は Linux で Bluetooth 機器を管理・操作するための標準的なソフトウェアとのこと。Home Assistant からのリクエストが D-Bus に届いているか確認した。
$ sudo dbus-monitor --system "type='method_call',destination='org.bluez',interface='org.bluez.Device1'"Home Assistant で操作するとこんな感じで出てくる。なので Home Assistant → BlueZ には遅延はない。
method call time=1792071868.191183 sender=:1.8681 -> destination=org.bluez serial=2 path=/org/bluez/hci0/dev_XX_XX_XX_XX_XX_01; interface=org.bluez.Device1; member=Connect
method call time=1792071868.196170 sender=:1.8682 -> destination=org.bluez serial=2 path=/org/bluez/hci0/dev_XX_XX_XX_XX_XX_02; interface=org.bluez.Device1; member=Connect次に strace と btmon を使って BlueZ からの Linux カーネルへのリクエストと、Linux カーネルから Bluetooth アダプターへのリクエストの時間を比較する。
$ sudo env TZ=Asia/Tokyo strace -f -tt -T -yy -s 512 \
-e trace=socket,bind,connect \
-p "$(pidof bluetoothd)"$ sudo env TZ=Asia/Tokyo btmon -i hci0 -t \
| awk '
/^[<>@*=&]/ {
show = ($0 ~ /^< HCI Command: LE (Extended )?Create Connection /)
}
show {
print
fflush()
}
'ここで 15 秒くらいの時間差が発生していた。そこで Linux カーネルに当たりを付けて、類似事象として報告・対応されているか調べた。
すると、ドンピシャな修正が入っていた。
Bluetooth の接続前にスキャンを停止する処理で、内部状態の更新に必要なフラグを立てるタイミングが遅く、停止状態が正しく反映されない問題があった。この修正では、スキャン停止前にフラグを設定するよう処理順を変更している。
対応
ということで Linux カーネルに問題がありそうだったので、修正されているバージョンに更新してみることにした。元々使っていた Linux カーネルのバージョンは 6.12.25 で、6.12 系にバックポートされたのは 6.12.78。今回は現時点で最新の 6.12.109 を入れてみた。
Linux カーネル更新後、Home Assistant からの操作を試してみると見事に遅延が解消した。原因が分かればあっさり解決するもんだ。これで Home Assistant を動かすラズパイを 1 台に集約しても遅延なくスマート電球を操作できるようになった。
今回は Linux カーネルの更新だけでスマート電球の遅延が直った。
定期的に更新する運用をしていたら避けられたかもしれない問題だけど、原因を特定する過程で色々学べたのでヨシとしよう。
そして AI があるおかげで原因調査も早かった。むしろ「原因を調べて」と依頼してあとは眺めているくらいだった。時間がかかったのは自分が理解するところ。プライベートだからこそ時間をかけて理解をして知識を蓄えていかないと。