xdubx / Solax-Pocket-USB-reverse-engineering

Port of the Solax-Pocket USB to a generic ESP8266/ESP32.
14 stars 4 forks source link

Simmilar to RS485 interface protocol? #1

Closed tuxmike closed 2 years ago

tuxmike commented 2 years ago

That 0xAA 0x55 is known from the solax RS485 protocol, check the pdf here: https://github.com/syssi/esphome-modbus-solax-x1

There are definitely similarities, but it is not completely the same...

xdubx commented 2 years ago

thanks :+1:

tuxmike commented 2 years ago

The USB plug on the Stick is not using USB protocol, right? I got 5V TTL UART Signal on the USB header, when powering the dongle with 5V, just giving me the 0xaa,0x55,0x07,0x01,0x05,0x0c,0x01 every 1200ms or so with baud 9600...

The last two bytes seem to be the binary addition checksum of all previous bytes, like in the RS485 interface, but with LSB byte order...

So my guess: 0xAA, 0x55: Static protocol id / preamble 0x07: message frame size in byte 0x01: always 1? 0x05: cmd id? 0x0c, 0x01: LSB checksum (0xaa+0x55+0x07+0x01+0x05 = 0x010C)

xdubx commented 2 years ago

A few suspicions have dissolved and the theory of your side sounds quite obvious. Here my records from the usb site. https://github.com/xdubx/Solax-Pocket-USB-reverse-engineering/blob/main/uart%20output/usb.txt

Here to

EXAMPLE 1
------ HEADER 
0xaa 
0x55
------ SIZE?
0x11 -> 17 in dez  -> size of whole paket
------
0x02
------ 
0x01 -> Seems to be a terminator
------ DATA
b'S' 53
b'W' 57
b'A' 41
b'M' 4D
b'T' 54
b'L' 4C
b'Y' 59
b'4' 34
b'Z' 5A
b'M' 4D
------  LSB Checksum
0x1f
0x04    -> 4F1

EXAMPLE 2 
------ HEADER 
0xaa
0x55
------ SIZE
0x07
------
0x01
------
0x05
------ LSB Checksum
0x0c      
0x01  -> 10C    

EXAMPLE 3
----- HEADER 
0xaa
0x55
------ SIZE
0x07
------ 
0x01
------
0x16
------ LSB Checksum
0x1d
0x01 -> 011D

To support your claim, 3 examples from the log. The other values could be possible that it is a function for register selection or reading? But the bytes do not match the description in the PDF.

HEADER SIZE ? DATA LSB Checksum

tuxmike commented 2 years ago

Had some fun with my inverter today, this is what I found out so far :yum::

Message structure (header, payload, checksum)

Byte offset Datatype Description Value
0 uint16 Static preamble 0xAA55
2 uint8 Total msg frame size (byte) size of: (header + payload + checksum) & 0xff
3 uint8 Cmd control code e.g. 0x01
4 uint8 Cmd function code e.g. 0x8C
5 ... payload see cmd table
[Frame size-2] uint16 Checksum uint16 binary sum of all msg bytes

Commands

Control code Function Code Payload length (byte) Checksum length (byte) Description
01 05 0 2 Request read serial numbers
01 85 40 2 Response read serial numbers
02 01 10 2 Request register pocket dongle serial number
02 01 10 0 (!) Response register pocket dongle serial number
01 16 0 2 Request inverter settings
01 96 400 2 Response inverter settings
01 0C 0 2 Request inverter data
01 8C 200 2 Response inverter data
01 04 0 2 Request inverter error data
01 84 44 2 Response inverter error data
05 00 2 2 Request enter pin
05 42 2 2 Request write setting pwr limit value
05 60 2 2 Request write setting pwr limit on/off
03 80 0 2 Response enter pin ok
03 81 0 2 Response setting write ok

Response serial numbers (Control code=0x01, FuncCode=0x85)

Byte offset Datatype Description
0 char[14] Inverter serial number
14 char[14] Inverter serial number padding, spaces
28 uint16 Inverter model code
30 char[8] Pocket dongle serial number
38 uint16 Inverter model type

Request / Response register pocket dongle serial number (Control code=0x02, FuncCode=0x01)

Byte offset Datatype Description
0 char[10] Pocket dongle serial number

Response inverter data (Control code=0x01, FuncCode=0x8C)

Byte offset Datatype Description Unit
0 uint16 Grid voltage 0.1V
2 uint16 Grid current 0.1A
4 uint16 Grid power 1W
6 uint16 PV1 voltage 0.1V
8 uint16 PV2 current 0.1A
10 uint16 PV1 voltage 0.1V
12 uint16 PV2 current 0.1A
14 uint16 PV1 power 1W
16 uint16 PV2 power 1W
18 uint16 Grid frequency 0.01Hz
20 uint16 Mode 0: Wait, 1: Check, 2: Normal/Running, 3: Fault, (4: PermanentFault, 5: UpdateMode, ...?)
22 uint32 E Total 0.1kwh
26 uint16 E Today 0.1kwh
28 ? ? ?
... ... ... ...
78 uint16 Temperature °C (?)
82 uint32 Runtime-total 1h
86 ? ? ?
... ... ... ...
110 uint8 0x1B ? ?
... ... ... ...

Response inverter error data (Control code=0x01, FuncCode=0x84)

Byte offset Datatype Description Unit
0 uint16 PV1 voltage 0.1V
2 uint16 PV2 voltage 0.1V
4 uint16 ? ?
6 uint16 Grid voltage 0.1V
8 uint16 Grid frequency 0.01Hz
10 ? ? ?
... ... ... ...

Response inverter settings (Control code=0x01, FuncCode=0x96)

Byte offset Datatype Description Unit
0 uint16 VAC low 0.1V
2 uint16 VAC high 0.1V
4 uint16 FAC low 0.01Hz
6 uint16 FAC high 0.01Hz
8 uint16 ? 0.1?
12 uint16 VAC 10m avg 0.1V
14 uint16 VAC low slow 0.1V
16 uint16 VAC high slow 0.1V
18 uint16 FAC low slow 0.01Hz
20 uint16 FAC high slow 0.01Hz
... ... ... ...
208 uint16 Settings PIN A decimal
250 uint16 Settings PIN B (?) decimal
280 uint16 Start time s
... ... ... ...

Request enter pin (Control code=0x05, FuncCode=0x00)

Byte offset Datatype Description Unit
0 uint16 PIN decimal

Request write setting pwr limit value (Control code=0x05, FuncCode=0x42)

Byte offset Datatype Description Unit
0 uint16 power limit W

Request write setting pwr limit on/off (Control code=0x05, FuncCode=0x60)

Byte offset Datatype Description Unit
0 uint16 power limit on/off 0U=off, 1U=on
xdubx commented 2 years ago

thx i will approve this and start to port it to a esp8266.

xdubx commented 2 years ago

Yes all values are correct :+1:

tuxmike commented 2 years ago

Added some values for FuncCode=0x96, which seem to be the inverter settings - still have to check against the settings when my inverter is powered.

tuxmike commented 2 years ago

Updated "Inverter settings". Note that you confused the last to tables and missed some updates when coping to readme.

tuxmike commented 2 years ago

Added some values for pin entering and writing power limit settings.