自宅のエアコン状態を、Prometheusに出せたら面白いと思っていろいろ試したメモです。
きっかけはゼネラル社(最近社名変わりましたね)のノクリアアプリで、公式ヘルプにあるHEMS機器との併用に関する記載です。
「ノクリアアプリ」とHEMS機器からの操作を併用できます。
手元のノクリアアプリでは、明示的なECHONET Liteモードへの切り替えは見当たりませんでした。
ただ、よく読むと「ノクリアアプリ」とHEMS機器を併用できる、という説明があります。
そこから、LAN内でGETできる状態情報があるのでは、という程度の期待で試しました。
最終的に作ったものはこちらです。
何を作ったか
ゼネラル社製エアコン(ノクリア)の状態をECHONET Liteで読み、Web UIとPrometheus向けの /metrics に出す小さなツールを作りました。
手元ではTrueNAS上のコンテナで常時起動しています。
構成はだいたいこんな感じです。
ノクリア
↓ ECHONET Lite UDP/3610
echonet-ac-probe
↓ /metrics
Prometheus
↓
Grafana(そのうち)
やっていることは状態取得だけです。
エアコンの電源を入れたり、設定温度を変えたり、運転モードを変えたりする機能は入れていません。
ECHONET LiteのGETだけを使っています。
メーカーアプリの通信を解析したわけでもなく、クラウドAPIや認証情報にも触っていません。
LAN内で返ってくるECHONET Liteのプロパティを読んでいるだけです。
そもそもの動機
子どもが別室で寝るようになったのはよかったのですが、エアコン設定がたまに不安でした。
寒がりのくせに薄着のままで、なぜか設定温度を30℃まで上げてそのまま寝ている。
たまたま親が様子を見に行ったら、かなり部屋に熱がこもっていて慌ててOFFにする、みたいな実体験です。
自宅では以前からBルート通信(秋月白箱)での消費電力可視化を多少触っていたので、エアコンの状態が取れるなら、室温や運転状態を監視して通知につなげられそうだなと。
あと単純に、エアコンごとの瞬時消費電力が見えると面白そうでした。
最初に試したこと
まずECHONET Liteのマルチキャスト探索を試しました。
ECHONET LiteはUDP/3610を使います。
マルチキャストアドレスは 224.0.23.0 です。
ただ、手元の環境では最初のマルチキャスト探索では応答が取れませんでした。
たぶんWi-Fiアクセスポイント側のAP分離や、マルチキャスト転送まわりの都合だと思います。
家庭内LANだからといって、マルチキャストが素直に通るとは限らないようです。
そこで、ユニキャストでサブネット内をスキャンしました。
結果として、自宅のノクリアがきちんと全台レスポンスを返しました。
192.168.0.xx 1F
192.168.0.xx 2F
(略)
各機器は、エアコンのEOJである 0x013001 として応答しました。
読めた値
主に見ているEPCはこのあたりです。
| EPC | 内容 |
|---|---|
0x80 |
動作状態 |
0x83 |
識別番号 |
0x84 |
瞬時消費電力 |
0x85 |
積算消費電力量 |
0x88 |
異常発生状態 |
0x8A |
メーカーコード |
0xB0 |
運転モード |
0xB3 |
設定温度 |
0xBA |
室内湿度 |
0xBB |
室内温度 |
0xBE |
外気温度 |
手元のノクリアアプリでもそうでしたが、下位機種のためか、室内湿度 0xBA は取れませんでした。
一方で、運転状態、運転モード、設定温度、室内温度、外気温、瞬時消費電力、積算消費電力量は概ね取れています。
Prometheusには、たとえばこういう形で出します。
nocria_ac_up{id="1f_room",name="1F",room="1f_room",ip="192.168.0.xx"} 1
nocria_ac_operation_status{id="1f_room",name="1F",room="1f_room",ip="192.168.0.xx"} 1
nocria_ac_instant_power_w{id="1f_room",name="1F",room="1f_room",ip="192.168.0.xx"} 55
nocria_ac_total_energy_kwh{id="1f_room",name="1F",room="1f_room",ip="192.168.0.xx"} 15.918
nocria_ac_room_temperature_c{id="1f_room",name="1F",room="1f_room",ip="192.168.0.xx"} 23
Getプロパティマップを見るようにした
最初は、欲しいEPCを全部まとめて一括GETしていました。
一括GET自体は効率がよく、複数台をポーリングするときにも有利です。
ただ、未対応のEPCを混ぜると、要求全体が Get_SNA になって他の値まで取れなくなることがありました。
手元では、室内湿度 0xBA が該当します。
そこで、まず 0x9F のGetプロパティマップを読み、機器ごとに取得できるEPCを確認するようにしました。
流れはこんな感じです。
1. 0x9F Getプロパティマップを読む
2. 取得できるEPC一覧を作る
3. 欲しいEPCとの積集合だけを一括GETする
4. 未対応EPCは not supported として扱う
5. 一括GETが失敗した場合は個別GETへfallbackする
これで、湿度が取れない機器でも、室温や消費電力など他の値は安定して取れるようになりました。
自動運転時の設定温度
設定温度 0xB3 も少しハマりました。
冷房や暖房では、25℃ のような値が普通に取れます。
ただ、自動運転時には通常の温度として扱うべきではない値が返ってきました。
これをそのまま数値として扱うと、ありえない温度が記録に出てしまいます。
いったん、自動制御っぽい特殊値は無効値として扱うようにしました。
Prometheus上では、設定温度そのものとは別に nocria_ac_set_temperature_valid を出しています。
nocria_ac_set_temperature_valid 1
nocria_ac_set_temperature_c 25
特殊値の場合は、温度のメトリクスを出さずに valid=0 にします。
グラフのスケールが壊れるよりは、この方が扱いやすいです。
Web UI
Web UIはかなり簡単なカード表示です。
表示しているのは、動作状態、運転モード、異常状態、設定温度、室内温度、外気温度、消費電力、積算電力量などです。

最初は手早く innerHTML で組んでいました。
ただ、リポジトリをpublicにするなら、機器から来た値や設定名をHTML文字列として差し込むのはさすがに雑だなと思い直しました。
今は createElement と textContent でDOMを作っています。
家庭内LAN向けの自分用ツールではありますが、最低限そこは潰しておきました。
あと、Web UIのフッターと /api/version にビルド情報を出しています。
{
"appVersion": "main",
"gitSha": "...",
"gitShaShort": "...",
"buildDate": "...",
"nodeEnv": "production"
}
TrueNASで latest を使っていると、いま動いているイメージが新しいのか分かりにくいです。
画面でビルド情報を見られるようにしておくと、かなり楽でした。
Prometheusで見る
主なメトリクスは以下です。
| メトリクス | 内容 |
|---|---|
nocria_ac_up |
応答有無 |
nocria_ac_stale |
一定時間未更新 |
nocria_ac_operation_status |
1=ON, 0=OFF |
nocria_ac_error_status |
1=異常あり, 0=正常 |
nocria_ac_instant_power_w |
瞬時消費電力 |
nocria_ac_total_energy_kwh |
積算消費電力量 |
nocria_ac_set_temperature_c |
設定温度 |
nocria_ac_set_temperature_valid |
設定温度が有効か |
nocria_ac_room_temperature_c |
室内温度 |
nocria_ac_outdoor_temperature_c |
外気温度 |
nocria_ac_outdoor_temperature_valid |
外気温が有効か |
Grafanaでは、まずこのあたりを見る想定です。
nocria_ac_room_temperature_c
nocria_ac_instant_power_w
sum(nocria_ac_instant_power_w)
increase(nocria_ac_total_energy_kwh[24h])
本来やりたかったのは、室温が高いのに変な設定のまま寝ている、みたいな状態の検知です。
そこはPrometheusのアラートからLINE通知などにつなげればできそうですが、たぶんそのうち作りこみます。
動かし方
自宅ではTrueNAS上のコンテナとして動かしています。
エアコンのIPはDHCP予約で固定しています。
設定は config.json をマウントするか、手っ取り早く動かせるように DEVICES_JSON で環境変数として渡します。いちいち永続化ボリューム作るの大変ですし。
例としてはこんな感じです。
services:
echonet-ac-probe:
image: ghcr.io/whitenoise0000/echonet-ac-probe:latest
network_mode: host
restart: unless-stopped
environment:
TZ: Asia/Tokyo
HTTP_PORT: "3000"
REQUEST_TIMEOUT_MS: "2000"
POLL_INTERVAL_MS: "30000"
DEVICES_JSON: >-
[
{"ip":"192.168.0.xx","id":"1f_room","name":"1F"},
{"ip":"192.168.0.xx","id":"2f_room","name":"2F"}
]
network_mode: host にしているのは、LAN内のUDP/3610でECHONET Liteを使うためです。
このあたりは環境依存がありそうなので、詳しくはREADMEに寄せています。
AIにだいぶ頼った
画面を見れば察せられると思いますが、実装はかなりAI支援に寄せました。
CodexやGPT-5.5に方針整理やレビューをさせつつ、実装もAI支援のCLIにかなり投げています。
いわゆるVibe Codingです。
家庭内LANの自分用ツールなので、まず動くものを出して、実機で返ってくる値を見ながら直す進め方でもまあ許容かな、という判断でした。
実際、この進め方とは相性がよかったです。
ただ、当然ながらそのままでは済みませんでした。
最初のWeb UIは innerHTML で組んでいて、あとからHTML injectionやXSSの観点で直しました。
/api/version を入れたら、Dockerイメージ内に package.json がなくてTrueNASで再起動ループ、みたいな普通の事故も起きました。
サクッと形にはなるけれど、最後は実機とログを見つつ調整です。ただ爆速で形になるのは、なかなか楽しい体験です。(しばらくボーナスステージ続いてほしいけど、本務で取り組むのは大変)
やっていないこと
このツールでは、ECHONET LiteのSET系コマンドは実装していません。
つまり、このツールからはエアコンの電源、運転モード、設定温度などを変更できません。
外部公開も想定していません。
家庭内LANで自分用に動かす前提です。
セキュリティ面はある程度割り切っていますが、リポジトリをpublicにする以上、気になるところは最低限潰しています。
実IPや部屋名入りの設定ファイルはリポジトリに含めないようにしました。
Web UIも、機器応答値をHTMLとして直接描画しない形に直しています。
感想
GETだけでも、思ったよりいろいろ取れました。
室温、運転状態、瞬時消費電力、積算消費電力量が見えるだけでも、家庭内の可視化としては十分面白いです。
一方で、実機で試さないと分からないところも普通にありました。
マルチキャストが通らない。未対応EPCを一括GETに混ぜると失敗する。自動運転時の設定温度が普通の温度ではない。latest のイメージ更新確認で迷う。
このへんは、机上で綺麗に作るより、動かして見た方が早かったです。
今後やるなら、Grafanaダッシュボード整備と、室温や運転状態に応じた通知、
あとは記録にとどまらず、日次もしくは週次で電力消費の分析レポートを自動送付とかは、そのうち欲しくなりそうです。
リポジトリ
手元のゼネラル製ノクリア Lシリーズと、後付けの無線LANアダプター構成で確認したものです。
他メーカーや他機種で同じように動くかは未確認です。
同じようなことを試したい人の参考になれば、くらいの温度感でお願いします。