Protocol Definition - HAEdwin/homeassistant-apsystems_ecu_reader GitHub Wiki

Overview

The APSystems ECU (Energy Control Unit) uses a proprietary TCP-based protocol over port 8899. The protocol consists of ASCII command strings and binary response data. This protocol definition is not based on any public or official documentation provided by APsystems. It is an independent interpretation and reverse-engineered understanding. As such, it may contain inaccuracies or misinterpretations. There is no guarantee of correctness, and it is not affiliated with or endorsed by APsystems in any way.

Connection Details

  • Protocol: TCP
  • Port: 8899
  • Encoding: Mixed (ASCII commands, binary responses)
  • Byte Order: Big Endian
  • Buffer Size: 1024 bytes (default)

Message Structure

Command Format (ASCII)

All commands follow the pattern: APS<length><type><ecu_id>END\n

Response Format (Binary)

All responses follow the pattern:

APS<4-byte-length><4-byte-type><payload><checksum>END\n

Commands

1. ECU Basic Query

Command: APS1100160001END\n

  • Length: 11001 (decimal)
  • Type: 6
  • Query Type: 0001

Response Structure:

Offset Length Type Description Encoding
0-2 3 ASCII Signature "APS" UTF-8
3-6 4 ASCII Data length Decimal string
7-8 2 ASCII Message type Decimal string
9-12 4 ASCII Query type "0001" UTF-8
13-24 12 ASCII ECU ID UTF-8
25-26 2 ASCII Data format version UTF-8
27-30 4 Binary Lifetime energy (×10 Wh) Big Endian Int
31-34 4 Binary Current power (W) Big Endian Int
35-38 4 Binary Today energy (×100 Wh) Big Endian Int

Version "01" Additional Fields:

Offset Length Type Description Encoding
46-47 2 Binary Total inverters Big Endian Int
48-49 2 Binary Online inverters Big Endian Int
52-54 3 ASCII Firmware version length Decimal string
55+ VSL ASCII Firmware version UTF-8
55+VSL 3 ASCII Timezone length Decimal string
58+VSL TSL ASCII Timezone UTF-8

Version "02" Additional Fields:

Offset Length Type Description Encoding
39-40 2 Binary Total inverters Big Endian Int
41-42 2 Binary Online inverters Big Endian Int
49-51 3 ASCII Firmware version length Decimal string
52+ VSL ASCII Firmware version UTF-8

2. Inverter Data Query

Command: APS1100280002<ECU_ID>END\n

  • Length: 11002 (decimal)
  • Type: 8
  • Query Type: 0002

Response Structure:

Offset Length Type Description Encoding
0-2 3 ASCII Signature "APS" UTF-8
3-6 4 ASCII Data length Decimal string
7-8 2 ASCII Message type Decimal string
9-12 4 ASCII Query type "0002" UTF-8
14-15 2 ASCII Status "00" UTF-8
15-16 2 ASCII Replacement flag "01" UTF-8
17-18 2 Binary Inverter quantity Big Endian Int
19-32 14 Binary Timestamp BCD (YYYYMMDDHHMMSS)

Per-Inverter Data (starting at offset 26):

Offset Length Type Description Encoding
+0 6 Binary Inverter UID Hex (12 chars)
+6 1 Binary Online status Boolean (0/1)
+7 2 ASCII Inverter type UTF-8
+9 2 Binary Frequency (×10 Hz) Big Endian Int
+11 2 Binary Temperature (+100°C) Big Endian Int

2-Channel Inverters (Types "01", "04" - YC600/DS3 series):

Offset Length Type Description Encoding
+13 2 Binary Channel 1 Power (W) Big Endian Int
+15 2 Binary Channel 1 Voltage (V) Big Endian Int
+17 2 Binary Channel 2 Power (W) Big Endian Int
+19 2 Binary Channel 2 Voltage (V) Big Endian Int

Total record length: 21 bytes

4-Channel Inverters (Types "02", "05" - YC1000/QT2 series):

Offset Length Type Description Encoding
+13 2 Binary Channel 1 Power (W) Big Endian Int
+15 2 Binary Channel 1 Voltage (V) Big Endian Int
+17 2 Binary Channel 2 Power (W) Big Endian Int
+19 2 Binary Channel 2 Voltage (V) Big Endian Int
+21 2 Binary Channel 3 Power (W) Big Endian Int
+23 2 Binary Channel 3 Voltage (V) Big Endian Int
+25 2 Binary Channel 4 Power (W) Big Endian Int

Total record length: 27 bytes

4-Channel Inverter (Type "03" - QS1 series):

Offset Length Type Description Encoding
+13 2 Binary Channel 1 Power (W) Big Endian Int
+15 2 Binary Voltage (V) Big Endian Int
+17 2 Binary Channel 2 Power (W) Big Endian Int
+19 2 Binary Channel 3 Power (W) Big Endian Int
+21 2 Binary Channel 4 Power (W) Big Endian Int

Total record length: 23 bytes

3. Signal Strength Query

Command: APS1100280030<ECU_ID>END\n

  • Length: 11002 (decimal)
  • Type: 8
  • Query Type: 0030

Response Structure:

Offset Length Type Description Encoding
0-2 3 ASCII Signature "APS" UTF-8
3-6 4 ASCII Data length Decimal string
7-8 2 ASCII Message type Decimal string
9-12 4 ASCII Query type "0030" UTF-8

Per-Inverter Signal Data (starting at offset 15):

Offset Length Type Description Encoding
+0 6 Binary Inverter UID Hex (12 chars)
+6 1 Binary Signal strength (0-255) Raw byte

Total record length: 7 bytes per inverter

Signal Strength Calculation:

signal_dbm = -100 + (raw_value / 255) * 100

Data Types and Encoding

String Extraction (aps_str)

  • Extracts UTF-8 encoded strings from binary data
  • Parameters: codec[start:start+amount].decode("utf-8")

Integer Extraction (aps_int_from_bytes)

  • Extracts big-endian integers from binary data
  • Parameters: int.from_bytes(codec[start:start+length], byteorder="big")

UID Extraction (aps_uid)

  • Extracts hexadecimal UID strings (12 characters)
  • Parameters: codec[start:start+length].hex()[:12]

Timestamp Extraction (aps_datetimestamp)

  • Extracts BCD-encoded timestamps
  • Format: YYYYMMDDHHMMSS → "YYYY-MM-DD HH:MM:SS"
  • Parameters: codec[start:start+amount].hex()

Checksum Validation

All responses include a checksum validation:

  1. Extract checksum from bytes 5-9 as decimal
  2. Verify: len(data) - 1 == checksum
  3. Verify signature: starts with "APS", ends with "END"

Inverter Type Mapping

Type Code Model Channels Description
"01" YC600 2 2-channel inverters
"02" YC1000 4 4-channel inverters
"03" QS1 4 4-channel (special voltage layout)
"04" DS3 2 2-channel inverters
"05" QT2 4 4-channel inverters

ECU Model Mapping

ECU ID Prefix Model Description
"2160" ECU-R Standard ECU
"2162" ECU-R-Pro Professional ECU
"2163" ECU-B Bridge ECU
"2150" ECU-C Commercial ECU (with CT support)
"2030" ECU-3 Third generation ECU

Special Notes

  1. ECU-C Models (215x): Support additional power meter data queries
  2. Replaced Inverters: When replacement flag ≠ "01", skip processing but advance 9 bytes
  3. Temperature: Raw value minus 100 gives degrees Celsius
  4. Energy Values: Lifetime energy divided by 10, today energy divided by 100
  5. Frequency: Raw value divided by 10 gives Hz
  6. Connection Management: Each query requires separate connection (open/close)

Error Handling

Common error conditions:

  • Invalid checksum
  • Malformed signature (not APS...END)
  • Socket timeout or connection errors
  • Invalid data length
  • Index out of bounds during parsing

Protocol Versions

The protocol supports multiple data format versions indicated by the version field in ECU responses:

  • Version "01": Includes timezone information
  • Version "02": Simplified format without timezone
⚠️ **GitHub.com Fallback** ⚠️