This document describes the local LAN API protocol for the EMS energy management system. It uses mDNS service discovery combined with TCP/JSON for device parameter query & set, energy control parameter management (16 power control periods), and Modbus-TCP data pass-through. Endpoint and protocol: TCP:8080 + JSON, plus Modbus-TCP on TCP:8080.
CT/IR/P1/Linky/Plug
ZL-xxx
PV / AC
Electricity/Power
Connector 1/2
Heating/Cooling
EMS devices on the LAN expose themselves via mDNS service discovery, and Apps can discover and connect to them without manually configuring IPs.
1.1.1 Communication Configuration
1.1.2 mDNS Discovery Fields
| Field | Type | Description |
|---|---|---|
s_type |
string | Service type identifier, e.g. SXD-mDNS-IF-NKYWLTS011 |
s_sn |
string | Device unique identifier (e.g. NKYWLTS011) |
s_domain / name |
string | Domain: SXD-mDNS.local |
s_ip |
string | Device IP address, e.g. 192.168.3.206 |
s_port |
string | Service port: 8080 |
s_type |
string | Device type |
Service Type: _http._tcp Name: SXD-mDNS-IF-NKYWLTS011 Domain: local Port: 8080 Address: SXD-mDNS.local TXT Records: s_sn=NKYWLTS011 s_ip=192.168.3.206 s_port=8080 s_type=xxx
Apps connect to the device via TCP:8080 and send JSON commands to obtain device-side power summary info, energy management parameters, and sub-device status.
| Field | Type | Description |
|---|---|---|
Get |
string | "EnergyParameter" : Get energy management parameter |
SerialNumber |
int | Request packet sequence, auto-incremented each time |
CommandSource |
string | Source identifier: "Web" (web page) / "HA" (Home Assistant) |
Request example:
{
"Get": "EnergyParameter",
"SerialNumber": 1,
"CommandSource": "Web"
}
Response includes three main sections: top-level fields, power summary (SSumInfoList), and sub-device lists (Storage_list, InterverInfoList, PlugInfoList, ChargerInfoList).
1.3.1 Top-level Fields
| Field | Field Name | Type | Description |
|---|---|---|---|
Response |
Response | string | "EnergyParameter" |
SerialNumber |
SerialNumber | int | Echo of request packet sequence |
Target |
Target | string | Response target: "Web" / "HA" |
SSumInfoList |
SSumInfoList | array | Power summary list |
ControlEnableStatus |
ControlEnableStatus | int | Green power plan switch: 0=Close, 1=Open |
1.3.2 SSumInfoList Fields
| Field Name | Type | Unit/Description |
|---|---|---|
| MeterTotalActivePower | double | Meter total active power |
| TotalPVPower | double | PV power |
| TotalPVChargePower | double | PV total charge power |
| TotalACChargePower | double | AC total charge power |
| TotalSmartLoadElectricalPower | double | Smart load total power |
| AverageBatteryAverageSOC | int | Battery average SOC |
| TotalBatteryOutputPower | double | Battery total output power |
| TotalGridOutputPower | double | Device total grid output power |
| TotalBackUpPower | double | Device total off-grid power |
| TotalChargePower | double | Battery total charge power |
1.3.3 Sub-device List Fields
| Sub-device | Field | Type | Description |
|---|---|---|---|
| Storage_list Energy Storage |
DevAddr | int | Registration ID |
| StorageSN | string | Energy storage SN (e.g. ZL-2502250374-00039) | |
| StorageStatus | int | Energy storage status | |
| PvChargingPower | double | PV charging power (W) | |
| AcChargingPower | double | AC charging power (W) | |
| BatterySoc | int | Battery SOC (%) | |
| BatteryDischargingPower | double | Battery discharging power (W) | |
| AcInActivePower | double | AC grid-connected active power (W) | |
| OffGridLoadPower | double | Off-grid power (W) | |
| BatteryChargingPower | double | Battery charging power (W) | |
| PvStringCount | int | Number of PV strings | |
| Pv1Power / Pv2Power / Pv3Power / Pv4Power | double | Per-PV-string power (W) | |
| Connector2Status / Connector2Power | int / double | Connector2 status / power | |
| InterverInfoList Inverter List |
InterverSN | string | Inverter SN |
| InterverStatus | string | Inverter status | |
| InterverActivePower | int | Active power (W) | |
| Connector1Status / Connector1Power | int / double | Connector1 status / power (2=Charging, 3=Charging end) | |
| PlugInfoList Smart Plug List |
DevAddr | int | Registration ID |
| lsThirdParty | int | Third-party flag (0=Close, 1=Open) | |
| FansDevType | int | Third-party device model | |
| PlugSN | string | Plug SN | |
| PlugStatus | int | Plug status (0=Close, 1=Open) | |
| PlugActvePower | double | Plug active power (W) | |
| PlugVol | double | Plug voltage (V) | |
| PlugCurrent | double | Plug current (A) | |
| PlugRatePower / PlugElectricity | double | Rated power (W) / Electricity (KWh) | |
| ChargerInfoList Charger List |
DevAddr / lsThirdParty / FansDevType | int / int / int | Same as plug fields |
| ChargerSN | string | Charger serial number | |
| ChargerStatus | int | Charger status (0=Close, 1=Ready, 2=Charging, 3=End) | |
| ConnectorElectricity | double | Charger electricity (KWh) |
Response example:
{
"Response": "EnergyParameter",
"SerialNumber": 1,
"Target": "Web",
"SSumInfoList": [{
"MeterTotalActivePower": 0,
"TotalPVPower": 0,
"TotalPVChargePower": 0,
"TotalACChargePower": 0,
"TotalSmartLoadElectricalPower": 0,
"AverageBatteryAverageSOC": 20,
"TotalBatteryOutputPower": 40,
"TotalGridOutputPower": 0,
"TotalBackUpPower": 0,
"TotalChargePower": 0
}],
"ControlEnableStatus": 0,
"Storage_list": [{
"DevAddr": 1,
"StorageSN": "ZL-2502250374-00039",
"StorageStatus": 1,
"PvChargingPower": 0,
"AcChargingPower": 0,
"BatterySoc": 100,
"BatteryDischargingPower": 50,
"AcInActivePower": -350,
"OffGridLoadPower": 0,
"BatteryChargingPower": 0,
"PvStringCount": 0,
"Pv1Power": 0,
"Pv2Power": 0,
"Pv3Power": 0,
"Pv4Power": 0
}, {
"DevAddr": 2,
"StorageSN": "ZL-2411080327-00039",
"StorageStatus": 1,
"PvChargingPower": 0,
"AcChargingPower": 0,
"BatterySoc": 20,
"BatteryDischargingPower": 40,
"AcInActivePower": 0,
"OffGridLoadPower": 0,
"BatteryChargingPower": 0,
"PvStringCount": 0,
"Pv1Power": 0,
"Pv2Power": 0,
"Pv3Power": 0,
"Pv4Power": 0
}]
}
| Field | Field Name | Type | R/W | Description |
|---|---|---|---|---|
EnergyManagement |
EnergyManagement | string | R/W | Energy management switch: 0=Close, 1=Open |
PowerControlPeriod1 ~ PowerControlPeriod16 |
PowerControlPeriod1~16 | string | R/W | Power control period 1~16 |
BaseDischargePower |
BaseDischargePower | string | R/W | Base discharge power (W) |
PeriodValid |
PeriodValid | string | R/W | Period valid |
Timestamp |
Timestamp | string | R/W | Format: "yyyy-mm-dd hh:mm:ss", e.g. "2024-09-20 00:00:00" |
ScheduledModeEnabled |
ScheduledModeEnabled | string | R/W | Scheduled mode enable |
PhaseDetectionEnabled |
PhaseDetectionEnabled | string | R/W | Phase detection enable (only effective in 3-phase imbalance regulation mode). 0=Close, 1=Open |
MeterSelector |
MeterSelector | string | R/W | Meter ID participating in energy management control |
SystemMaxPowerLimit |
SystemMaxPowerLimit | string | R/W | System max power limit, used in total power control mode with total power data |
PowerControlPeriod Format
[时间段使能],[起始时间],[结束时间],[强制取/馈电功率限制],[允许取电功率限制],[功率控制模式],[充电最大SOC],[放电最小SOC]
Example:
"1,09:00,23:59,1000,500,0,100,10"
Explanation: This period enabled, time 09:00-23:59, forced take/feed power limit 1000W, allowed take power limit 500W, load priority mode.
Common Fields
| Field | Field Name | Type | Description |
|---|---|---|---|
Get |
Get | string | "Energycontrolparameters" : read energy control parameters |
Set |
Set | string | "Energycontrolparameters" : set energy control parameters |
Response |
Response | string | "Energycontrolparameters" : reply to read command |
SerialNumber |
SerialNumber | int | Auto-increment each request |
CommandSource |
CommandSource | string | "Web" : Web page / "HA" : Home Assistant |
Target |
Target | string | Response target field name |
RegControlField |
RegControlField | string | Read the corresponding field |
| Field | Description |
|---|---|
Get |
Returned address data to read |
SetParameters |
Returned set address & data |
SetControlInfo |
Returned set fields & data |
Query request example:
{
"Get": "Energycontrolparameters",
"SerialNumber": 1,
"CommandSource": "Web",
"RegControlField": [
"EnergyManagement",
"PowerControlPeriod1",
"PowerControlPeriod2",
"PowerControlPeriod3",
"PowerControlPeriod4"
]
}
{
"Response": "Energycontrolparameters",
"SerialNumber": 1,
"Target": "Web",
"ControlInfoField": {
"EnergyManagement": "1",
"PowerControlPeriod1": "1,09:00,23:59,1000,500,0,100,10",
"PowerControlPeriod2": "1,00:00,1:59,0,500,1,100,10",
"PowerControlPeriod3": "1,02:00,4:59,0,500,2,50,10",
"PowerControlPeriod4": "1,05:00,8:59,0,500,2,100,10"
}
}
{
"Set": "Energycontrolparameters",
"SerialNumber": 1,
"CommandSource": "Web",
"SetControlInfoField": {
"EnergyManagement": "1",
"PowerControlPeriod1": "1,09:00,23:59,1000,500,0,100,10"
}
}
{
"Response": "Energycontrolparameters",
"SerialNumber": 1,
"Target": "Web",
"SetParametersField": {
"EnergyManagement": "1",
"PowerControlPeriod1": "1,09:00,23:59,1000,500,0,100,10"
}
}
Apps can pass Modbus RTU frames to EMS-accessed sub-devices via the data pass-through command; the device returns the Modbus response.
| Field | Field Name | Type | Description |
|---|---|---|---|
Set |
Set | string | "DataTransmission" : data pass-through |
Response |
Response | string | Reply for pass-through |
SerialNumber |
SerialNumber | int | Auto-increment each request |
CommandSource |
CommandSource | string | "Web" : Web page / "HA" : Home Assistant |
Target |
Target | string | Response target: "Web" / "HA" |
SetCommand |
SetCommand | string | Pass-through parameter config |
FunctionCode |
FunctionCode | int | Standard Modbus function code: 0x03, 0x04, 0x06, 0x10 |
TransmittedData |
TransmittedData | string | Set / returned pass-through data |
CommandResponse |
CommandResponse | string | Response data |
ControlState |
ControlState | string | Pass-through state: "succeed" / "fail" |
{
"Set": "DataTransmission",
"SerialNumber": 1,
"CommandSource": "Web",
"SetCommand": {
"FunctionCode": 3,
"TransmittedData": "01 03 FE 06 00 03 56 67"
}
}
{
"Response": "DataTransmission",
"SerialNumber": 1,
"Target": "Web",
"CommandResponse": {
"FunctionCode": 3,
"ControlState": "succeed",
"TransmittedData": "01 03 06 00 01 02 03 04 05 2F CE"
}
}
When port 8080 is occupied or the device doesn't support the pass-through, the data pass-through command (Section 3) over TCP:8080 + JSON is recommended as it provides a more standardized interface.
_http._tcp) to discover the device's IP and port without manual configuration.
EnergyParameter is used to obtain real-time device power summary and sub-device status info; Energycontrolparameters is used to read / set the energy management configuration (16 power control periods and various switches).
0x03 (read holding registers), 0x04 (read input registers), 0x06 (write single register), and 0x10 (write multiple registers).
[enable], [start time], [end time], [forced take/feed power limit], [allowed take power limit], [power control mode], [max charge SOC], [min discharge SOC]. Example: "1,09:00,23:59,1000,500,0,100,10".
PowerControlPeriod1 ~ PowerControlPeriod16.
DataTransmission passes Modbus commands via JSON over TCP:8080 with a more standardized protocol; direct Modbus-TCP requires parsing based on the device protocol currently accessed by EMS.