🏠

エアコン、照明をネットワーク(ECHONET Lite)から制御してみる

2024/06/19に公開

はじめに

自宅にはダイキン製のエアコンと、パナソニック製のリンクプラスの照明スイッチがあります。どちらもネットワークに接続可能で、ECHONET Liteを使って制御できます。

ECHONET Liteの規格書はこの辺のページからダウンロード可能なので、自分のような趣味でいじりたい人にもやさしいです。

自宅にある以下の機器を対象にして試してみます。

  • ダイキン エアコン うるさらX 2024年モデル
  • パナソニック アドバンスシリーズ リンクプラス スイッチ(受信器)
    リンクプラス用無線アダプタ(WTY2001)

照明をECHONET Liteで制御するためには無線アダプタ(WTY2001)が必要なんですが、価格が高すぎるのがちょっと…

ECHONET Lite

UDPのポート番号3610で、以下のパケットフォーマットで通信します。

EHD TID SEOJ DEOJ ESV OPC EPC PDC EDT
  • EHD (2B) … 0x1081 固定
  • TID (2B) … Transaction ID、応答との対応をとるためのID
  • SEOJ (3B) … 送信元オブジェクトコード
  • DEOJ (3B) … 相手先オブジェクトコード
  • ESV (1B) … 値の設定、取得などのサービス指定
  • OPC (1B) … プロパティ数
  • EPC (1B) … プロパティの種類
  • PDC (1B) … 後に続くEDTのバイト数
  • EDT … プロパティの値、PDCで指定したバイト数ある

EPC+PDC+EDT のセットがプロパティで、OPCで指定した個数のプロパティが続きます。ただし、値を取得する場合はプロパティのPDCが0になってEDTが無くなります。

照明で試してみる!

照明のリンクプラス用無線アダプタ(WTY2001)のIPアドレスにパケットを投げてみます。

get_instances.py
import socket

IP = '192.168.0.100' # WTY2001のIPアドレス
PORT = 3610
pkt = '1081 0000 0ef001 0ef001 62 01 d6 00' # get instance list

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', PORT))
sock.sendto(bytes.fromhex(pkt), (IP, PORT))
msg, addr = sock.recvfrom(1500)
print(msg.hex())
sock.close()

送っているパケットは↓で、無線アダプタWTY2001にぶら下がっている照明スイッチのリストを取得することになります。

ESV = 0x62 … プロパティ値読み出し(Get)
OPC = 0x01 … プロパティ数は1個
EPC = 0xd6 … オブジェクトのインスタンスリスト
PDC = 0x00 … 読み出しなのでEDTは0バイト

自宅での実行結果は↓

> python get_instances.py
108100000ef0010ef0017201d6130602a301029101029102029103029104029105

パケットから頑張ってEDTのインスタンスリスト部分を切り出すと、以下の6個のオブジェクトがあると応答しています。1バイト目がクラスグループコード、2バイト目がクラスコード、3バイト目がインスタンスコードで、ECHONET Liteの仕様書から種類がわかります[1]

  • 02a301 … 照明システムクラス、無線アダプタ自体
  • 029101 … 単機能照明クラス、1個目
  • 029102 … 単機能照明クラス、2個目
  • 029103 … 単機能照明クラス、3個目
  • 029104 … 単機能照明クラス、4個目
  • 029105 … 単機能照明クラス、5個目

実際に自宅にはリンクプラスのスイッチが5個あるので、これと合っています。

個々の照明のON/OFFは、このオブジェクトコードをDEOJにしたパケットを送信すれば制御できます。

set_on.py
import socket

IP = '192.168.0.100' # WTY2001のIPアドレス
PORT = 3610
pkt = '1081 0000 0ef001 029101 60 01 800130' # set on

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(bytes.fromhex(pkt), (IP, PORT))
sock.close()

パケットの内容はこんな感じ。

ESV = 0x60 … プロパティ値書き込み(Set)
OPC = 0x01 … プロパティ数は1個
EPC = 0x80 … ON/OFF状態
PDC = 0x01 … EDTは1バイト
EDT = 0x30 … ON状態 (0x30がON、0x31がOFF)

今、照明が点いているかどうかを確認するには、以下のようにパケットを送ります。

get_onoff.py
import socket

IP = '192.168.0.100' # WTY2001のIPアドレス
PORT = 3610
pkt = '1081 0000 0ef001 029101 62 01 8000' # get on/off

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', PORT))
sock.sendto(bytes.fromhex(pkt), (IP, PORT))
msg, addr = sock.recvfrom(1500)
print(msg.hex())
sock.close()

実行するとこんな感じ。

> python get_onoff.py
108100000291010ef0017201800131

この時は消灯していて最後のEDTが0x31です。点灯してれば0x30です。

状態確認にはこのパケットでポーリングしても良いのですが、状態変化があった場合にマルチキャストで知らせてくれるので、それを受信してみます。
ECHONETのマルチキャストアドレスは224.0.23.0なので、以下のようにします。

recv_stat.py
import socket

IP = '224.0.23.0' # multicast
PORT = 3610

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', PORT))
msg, addr = sock.recvfrom(1500)
print(msg.hex())
sock.close()

これを実行した状態(パケット受信待ち)で、壁のスイッチを操作するとこんな感じに受信します。

> python recv_stat.py
108100720291010ef0017301800130

EDT = 0x30なのでON状態を検知できました。

エアコンで試してみる!

照明と同様にインスタンスリストを取得してみます。

> python get_instances.py
108100000ef0010ef0017201d60401013001

取得できたオブジェクトコードが

  • 013001 … 家庭用エアコンクラス

なので、これにパケットを送信するんだけど、照明と違って運転モード(冷房、暖房など)や、設定温度、風量なんかが色々あります。これは複数のプロパティを含むパケットにしてあげると1度に指定できます。

こんな感じ。

pkt = '1081 0000 0ef001 013001 60 03 800130 b00142 b3011c'

3つのプロパティを指定していて、以下の内容です。

  • EPC1 = 0x80 … ON/OFF状態
  • EDT1 = 0x30 … ON
  • EPC2 = 0xb0 … 運転モード
  • EDT2 = 0x42 … 冷房 (0x41:自動, 0x42:冷房, 0x43:暖房, 0x44:除湿)
  • EPC3 = 0xb3 … 設定温度
  • EDT3 = 0x1c … 28度

つまり28度で冷房ONとなります。

エアコンでは気温や湿度も取得できるようです。(この辺はエアコンの機種によって違うと思います)

get_temp.py
pkt = '1081 0000 0ef001 013001 62 03 ba00 bb00 be00'
> python get_temp.py
108100000130010ef0017203ba0137bb011dbe011a
  • EPC1 = 0xba … 室内の湿度
  • EDT1 = 0x37 … 55%
  • EPC2 = 0xbb … 室内の温度
  • EDT2 = 0x1d … 29度
  • EPC3 = 0xbe … 屋外の温度
  • EDT3 = 0x1a … 26度

室外機から屋外の温度も取れるのが良いですね〜。

まとめ

ECHONET Liteを使って照明とエアコンの制御ができました。かなり簡単なプロトコルなので試しやすいかと思います。

日本はスマートホーム化が遅れてるなんて言われますが、ECHONET Liteが普及しているのは救いだと思います。
自分はこれでHome Assistantと連携して自宅をスマートホーム化していて、仕様が公開されているECHONET Liteには感謝です。

脚注
  1. 個々の機器についての詳細はECHONETのページAPPENDIX ECHONET機器オブジェクト詳細規定の仕様書にあります。 ↩︎

Discussion