ECHONETLite の一部機器だけ cannot_connect になった
Home Assistant を再起動したところ、ECHONETLite に登録していた一部の機器だけがcannot_connectとなり、初期化を繰り返すようになった。
特に困ったのは、太陽光発電と分電盤の電力を取得している SPW277-LP である。Home Assistant には旧 IP の192.168.xxx.27が残っていたが、実機の IP は DHCP によって192.168.xxx.13へ変わっていた。これが今回の原因だった。
新 IP で再検出した後、Entity Registry を確認すると、既存の 38 エンティティは新しい Config Entry 側に紐づいていた。旧 Config Entry は 0 件だったため、Home Assistant の UI から削除した。主要なentity_idは以前のまま維持できた。
その後、ECHONETLite の Custom integration は 4.0.6 に戻し、同じ構成で動作することを確認した。旧 Config Entry の削除後も先月分の履歴グラフを表示でき、グラフに目立った破綻がないことも概ね確認できた。
Home Assistant と ECHONETLite の構成
問題が起きた環境は次のとおり。
- Home Assistant は Incus コンテナ上で実行
- ECHONETLite は HACS から導入した Custom integration
- 問題発生時のバージョンは 4.0.6
- 切り分け中に 3.9.0 へダウングレード
- 対象 LAN は
192.168.xxx.0/24 - Home Assistant から見える ECHONET 通信用インターフェースは
maclan0 - 対象機器は SPW277-LP と複数台のエアコン
寝室と仕事場のエアコンは、問題が起きている間も Home Assistant から操作でき、状態も更新されていた。ECHONET Lite 全体が通信できない状態ではなく、一部機器に絞って調べる必要があった。
Home Assistant へ ECHONET Lite 対応機器を登録したときの手順は、以前の記事にまとめている。
今回使用した ECHONETLite Custom integration のリポジトリは次のとおり。
旧 IP に ping が通っても SPW277-LP とは限らなかった
最初に旧 IP の疎通を確認した。
ping -c 3 192.168.xxx.273 回とも応答があり、近隣テーブルにも MAC アドレスが表示された。ここだけを見ると、SPW277-LP は旧 IP に存在して いるように見えた。
しかし、ping に応答したのは「その IP にいる何らかの機器」であり、それが SPW277-LP であることや、ECHONET Lite の UDP/3610 へ応答できることまでは確認できない。
その後、旧 IP で見えた MAC アドレスが別の IoT 機器のものに似ていると分かった。旧 IP に現在いる機器は完全には特定していないが、DHCP の再割り当てによって別機器が旧 IP を使っている可能性が高かった。
また、他のエアコンは実際に操作できていたため、Home Assistant 側のネットワークや ECHONETLite 統合全体の障害という仮説とも合わなかった。
ECHONETLite Custom integration を 4.0.6 から 3.9.0 へ戻しても直らなかった
問題発生時に使っていた ECHONETLite のバージョンは 4.0.6 だった。最初はアップデートによる回帰を疑い、3.9.0 へダウングレードした。
しかし、3.9.0 でも同じ初期化ループが続いた。バージョンを戻しても現象が変わらなかったため、4.0.6 だけの問題を追うのをやめ、機器ごとの接続先を確認する方針に変えた。
この切り分けでは、4.0.6 に問題がないことまで証明したわけではない。少なくとも、今回のcannot_connectは 3.9.0 でも再現したため、4.0.6 固有の回帰だけでは説明できなかったという結果である。
機器側の表示から SPW277-LP の新 IP を見つけた
ルータの端末一覧を確認すると、SPW277-LP の候補となる機器が192.168.xxx.13にいた。さらに太陽光のコンパネを確認すると、現在の IP として同じ192.168.xxx.13が表示されていた。
ここで、Home Assistant が保持していた旧 IP と実機の表示が一致していないことが分かった。
Home Assistantの旧Config Entry: 192.168.xxx.27
SPW277-LPの現在IP: 192.168.xxx.13旧 IP に現在いる機器の特定や、新 IP の MAC アドレスと SPW277-LP の Wi-Fi モジュール MAC との最終照合までは行っていない。それでも、実機のコンパネが新 IP を表示し、その IP で SPW277-LP を再検出できたことから、IP 変更が原因だったと判断した。
新 IP で再検出すると旧・新 Config Entry が並んだ
192.168.xxx.13を使って SPW277-LP を再検出すると、新しい[Auto Discovery]の Config Entry が追加された。
新しい Config Entry では、次の 3 デバイスが正常に表示された。
| デバイス | エンティティ数 |
|---|---|
| Controller | 2 |
| Distribution panel metering | 27 |
| Home solar power generation | 9 |
| 合計 | 38 |
一方、旧 IP の[Auto Discovery]も残っていた。こちらはcannot_connectのままで、3 デバイス名は表示されるものの、エンティティ数は表示されていなかった。
この時点では旧 Config Entry をすぐ削除せず、既存エンティティがどちらに紐づいているかを先に確認した。
Entity Registry で旧 0 件・新 38 件を確認した
Home Assistant の設定ディレクトリにある.storage/core.config_entriesから、ECHONETLite の Config Entry ID と IP を確認した。
jq -r '
.data.entries[]
| select(.domain=="echonetlite")
| [.entry_id, .title, .data.host]
| @tsv
' .storage/core.config_entries出力から旧 IP と新 IP に対応する Config Entry ID を特定し、シェル変数へ入れた。次の値は例なので、実際の出力で置き換える。
OLD="<旧IPのConfig Entry ID>"
NEW="<新IPのConfig Entry ID>"次に、core.entity_registryからそれぞれの Config Entry に紐づく ECHONETLite エンティティを抽出した。
echo "=== OLD ==="
jq -r --arg id "$OLD" '
.data.entities[]
| select(.platform=="echonetlite" and .config_entry_id==$id)
| [.entity_id, .unique_id, .device_id]
| @tsv
' .storage/core.entity_registry
echo "=== NEW ==="
jq -r --arg id "$NEW" '
.data.entities[]
| select(.platform=="echonetlite" and .config_entry_id==$id)
| [.entity_id, .unique_id, .device_id]
| @tsv
' .storage/core.entity_registryOLD: 0件
NEW: 38件新 Config Entry 側には、これまで使っていた買電、売電、発電などのentity_idが紐づいていた。完全な Config Entry ID、unique_id、device_idは環境固有のため、この記事には掲載しない。
古い Config Entry に紐づくエンティティがないことを確認できた。再検出時の内部ロジックまでは調べていない。
空になった旧 Config Entry を UI から削除した
旧 Config Entry に紐づくエンティティが 0 件で、新 Config Entry に 38 件が存在することを確認してから、旧 IP の[Auto Discovery]を Home Assistant の UI で削除した。
.storage内の JSON ファイルは直接編集していない。今回は再検出後の紐づきが期待どおりだったため、UI から不要な Config Entry を削除するだけで復旧できた。
削除後は、新 IP の Config Entry が SPW277-LP の 3 デバイスと 38 エンティティを持つ状態になった。ほかのエアコンも含め、ECHONETLite の対象機器は復旧した。
旧 Config Entry の削除後も先月分の履歴グラフを確認でき、表示に目立った破綻は見つからなかった。
DHCP 予約は IP レンジを設計してから進める
今回の原因は、SPW277-LP の IP が DHCP で変わった一方、Home Assistant の Config Entry に旧 IP が残っていたことだった。再発防止としては、IP を Config Entry に持つ ECHONET 機器から DHCP 予約するのがよさそうである。
回線変更によって DHCP を担うルータも変わっており、リース時間などの挙動が以前と異なっている可能性もある。ただし、現在の DHCP pool と全端末の使用状況を確認できておらず、予約アドレスの設計はまだ行っていない。DHCP の払い出し IP を固定すれば IP 変更の再発を防ぐ対策になるが、利用する IP レンジを先に設計し、計画して進めることにした。
今後確認したいのは次の 2 点である。
- 現在の DHCP pool を確認し、ECHONET 機器の予約アドレスを決める
- DHCP 予約後、リース更新をまたいでも同じ IP を維持できるか確認する
ping が通っていたため、最初は IP 変更を疑いにくかった。旧 IP に応答する機器が目的の機器とは限らないと分かってから、実機表示、Config Entry、Entity Registry を順に照合でき、.storageを直接編集せずに復旧できた。
おしまい


