🗼

ECHONET Liteを初めて触るときに読む記事(2025 Summer)

に公開

はじめに

ユアスタンドでハードウェア・ファームウェア開発担当をしている吉田です。今回はECHONET Liteについてです。

ECHONET Liteを初めて触るときにサクッと概要を知りたい人向けの内容です。先人たちの記事なども貼りまくるので参考程度にどうぞ!

公式ドキュメント
https://echonet.jp/spec_v114_lite/

一番お世話になった記事
https://qiita.com/miyazawa_shi/items/725bc5eb6590be72970d?utm_source=chatgpt.com

ECHONET Liteとは

  • エコーネットコンソーシアムが策定し、ISO/IECの国際標準にもなっています
  • センサー、白物家電から太陽光発電、蓄電池、スマートメータまで、120種類以上の機器を「機器オブジェクト」として定義
  • 軽量化・高い相互運用性を追求しており、OSIモデルの第5層以上にフォーカスして設計されています。Modbusと比べると高レイヤーのプロトコルに位置する。

📡 ECHONET Lite 電文構造(例付き)

電文例

フィールド名 例(16進) 説明
EHD1 0x10 ECHONET Lite使用の宣言(固定値)
EHD2 0x81 フォーマット1(ECHONET Lite仕様)
TID 0x01 トランザクションID(任意)
SEOJ 05ff01 送信元オブジェクト(クラス:管理クラス=0x05ff、01:インスタンス)
DEOJ 027e01 送信先オブジェクト(クラス例:充放電器クラス=0x7e、01:インスタンス)
※他例:蓄電池=0x7d、太陽光発電=0x79
ESV 0x60 / 0x61 / 0x62 サービスコード(Set/SetC/Getなど)
OPC 0x01 プロパティ数(EPC以下のセット数)
EPC 0x80など プロパティコード(例:動作状態、蓄電残量など)
PDC 0x01など EDTのバイト数(例:1バイト)
EDT 0x30など 設定値 or 読み出された値(例:ON=0x30, OFF=0x31)

対応機器(オブジェクトグループ)の例

家電から産業機器まで広く対応するわけです。
それに対してグループコードが振られていています。(後ほど活用)


引用元:ECHONET Consortium ECHONET Lite 通信ミドルウェア仕様

EHD1,EHD2,THD

  • EHD1/EHD2 = 0x10/0x81で固定です。ECHONET Liteということを宣言します。
  • TIDはTransactionIDなので任意となります。デフォルトで0x01としておきます。

EDATA(SEOJ~EDT1)

ここが実質プロトコルのメインメッセージ群となります。

SEOJ (送信元オブジェクト)

  • 05FF01 は、管理クラス(Controller/Node Profile)である "自分自身(コントローラ)" を示します。💻
    • 05FF: コントローラー(HEMS制御コントローラーなど)💻
    • 01: インスタンス(送信元識別番号)

DEOJ(送信先オブジェクト)

  • クラスコードにより種別機能を特定します。例:
    • 0x027E01: 充放電器クラス(0x7E)⚡
    • 0x027D01: 蓄電池(0x7D)🔋
    • 0x027901: 太陽光発電(0x79)☀️
  • 0x02はグループコード、0x01はインスタンス

ESV(サービスコード)

  • 0x60 = Set(書き込み、応答不要)📝
  • 0x61 = SetC(書き込み+確認応答)📝✅
  • 0x62 = Get(読み出し要求)📖

Set(0x60)

設定値を書き込む指示

[ コントローラ: 05FF01 ] 💻
     ▶ 0x60: 書き込み指示
               (応答は不要)
     -----------------------------------> [ 充放電器クラス:0x027E01 ] ⚡

SetC(0x61)

Set+応答依頼を行う。設定したパラメータを返すことが多い

[ コントローラ: 05FF01 ] 💻
     ▶ 0x61: 書き込み + 応答依頼
     -----------------------------------> [ 充放電器クラス:0x027E01 ] ⚡
                          ◀ 0x71: 応答(例: 充電出力)

Get(0x62)

状態や設定値を読み出す

[  コントローラ: 05FF01  ] 💻
     ▶ 0x62: 読み出し要求
     -----------------------------------> [ 充放電器クラス:0x027E01  ] ⚡
                          ◀ 0x72: 状態応答 (例: 運転状態)

OPC(プロパティ数)

  • 1つの電文で送信するプロパティの数を指定します 🔢
  • 例:0x01 = 1つのプロパティ、0x02 = 2つのプロパティ
  • 通常は1つのプロパティを扱うことが多いため、0x01が一般的

EPC(プロパティコード)

  • 操作対象のプロパティを指定するコード 🔧
  • 機器の種類によって利用可能なプロパティが異なります

機器固有のプロパティ例:

  • 蓄電池(0x7D):0xE0 = 蓄電残量🔋、0xE1 = 運転モード⚙️
  • 充放電器(0x7E):0xE0 = 充電出力⚡、0xE1 = 放電出力⚡
  • 太陽光発電(0x79):0xE0 = 発電電力☀️、0xE1 = 発電電力量☀️

PDC (EDTのバイト数)

  • EDT(設定値)のデータ長をバイト数で指定 📏
  • 例:0x01 = 1バイト、0x02 = 2バイト、0x04 = 4バイト

EDT(設定値)

  • 実際のデータ値が格納される部分 💾
  • データ型やプロパティによって形式が異なります

よく使われる値の例:

  • 動作状態(0x80):
    • 0x30 = ON 🟢
    • 0x31 = OFF 🔴
  • 真偽値:
    • 0x41 = TRUE ✅
    • 0x42 = FALSE ❌
  • 数値:直接の値(例:0x64 = 100)🔢
  • 文字列:ASCIIコードで格納 📝

ソースコード例

シナリオ
コントローラーから充放電器に対してON/OFFを設定する

コントローラーから充放電器に対してON/OFFを設定する

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import struct
import datetime

# ECHONET Lite設定
TARGET_IP = "127.0.0.1"  # 接続先IP
PORT_ECHONET_LITE = 3610  # ECHONET Liteはポート3610で通信
EL_INSTANCE = 0x01  # インスタンスは0x01

# 電文構築関数
def build_echonet_message(esv, epc, pdc, edt):
    """ECHONET Lite電文を構築"""
    return struct.pack(">2B H 11B",
        0x10, 0x81, 0x01,        # EHD1, EHD2, TID
        0x05, 0xFF, 0x01,        # SEOJ (コントローラー)
        0x02, 0x7E, EL_INSTANCE, # DEOJ (充放電器)
        esv, 0x01, epc, pdc, edt # ESV, OPC, EPC, PDC, EDT
    )

def send_message(sock, message, description):
    """メッセージ送信"""
    print(f"=== {description} ===")
    print(f"送信: {message.hex()}")
    sock.sendto(message, (TARGET_IP, PORT_ECHONET_LITE))
    
    # 応答受信
    try:
        sock.settimeout(5.0)
        response, addr = sock.recvfrom(1500)
        print(f"受信: {response.hex()}")
        return response
    except socket.timeout:
        print("応答なし")
        return None

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    # 1. Get命令: 動作状態を読み取り
    get_message = build_echonet_message(
        esv=0x62,  # Get
        epc=0x80,  # 動作状態
        pdc=0x00,  # データなし
        edt=0x00
    )
    send_message(sock, get_message, "Get: 動作状態読み取り")
    
    # 2. Set命令: 動作状態をONに設定
    set_message = build_echonet_message(
        esv=0x60,  # Set
        epc=0x80,  # 動作状態
        pdc=0x01,  # 1バイト
        edt=0x30   # ON
    )
    send_message(sock, set_message, "Set: 動作状態ON")
    
    # 3. SetC命令: 運転モードを充電に設定(応答あり)
    setc_message = build_echonet_message(
        esv=0x61,  # SetC
        epc=0xDA,  # 運転モード(標準プロパティ)
        pdc=0x01,  # 1バイト
        edt=0x42   # 充電(標準値)
    )
    send_message(sock, setc_message, "SetC: 運転モード充電")
    
    sock.close()

if __name__ == "__main__":
    main()

実行結果例:

=== Get: 動作状態読み取り ===
送信: 10810105ff01027e0162018000
受信: 108101027e0105ff017201800130

=== Set: 動作状態ON ===
送信: 10810105ff01027e016001800130
応答なし

=== SetC: 運転モード充電 ===
送信: 108101027e0105ff016101da0142
受信: 108101027e0105ff017101da0142

受信電文の解説:

Get応答例: 108101027e0105ff017201800130

10 81 01          # EHD1, EHD2, TID
02 7e 01          # SEOJ (送信元: 充放電器)
05 ff 01          # DEOJ (送信先: コントローラー)
72                # ESV (Get_Res: 読み出し応答)
01                # OPC (プロパティ数: 1個)
80                # EPC (動作状態)
01                # PDC (データ長: 1バイト)
30                # EDT (ON=0x30)

SetC応答例: 108101027e0105ff017101da0142

10 81 01          # EHD1, EHD2, TID
02 7e 01          # SEOJ (送信元: 充放電器)
05 ff 01          # DEOJ (送信先: コントローラー)
71                # ESV (Set_Res: 設定応答)
01                # OPC (プロパティ数: 1個)
da                # EPC (運転モード)
01                # PDC (データ長: 1バイト)
42                # EDT (充電=0x42)

応答のESVコード:

  • 0x72: Get_Res (読み出し応答)
  • 0x71: Set_Res (設定応答)
  • 0x73: SetC_Res (設定応答、確認あり)

引用(公式ドキュメント)

各種スクショの引用元です。
開発背景とかも書いてますよ。
https://echonet.jp/spec_v114_lite/

Discussion