Solarman V5 Protocol#
Solarman V5 is a proprietary protocol used by Solarman (IGEN-Tech) solar inverter data loggers. Solarman V5 is TCP-based, and is used by the data loggers for communicating both locally and with Solarman Cloud. Solarman data loggers use Hi-Flying HF-A11 SOCs which by default use port tcp/8899.
By sending a suitably formed packet to the data logging stick on this port, one can send and receive Modbus RTU frames directly to/from the inverter on port tcp/8899 without interfering with Solarman Cloud operations.
Note
This information has been gathered from various internet sources and from reverse engineered packet captures. No warranty/liability of any kind is provided.
For the purposes of this implementation, the Solarman V5 frame is composed of three parts:
All Solarman V5 fields are encoded Little Endian, with the exception of the Modbus RTU frame, which is encoded Big Endian (as per Modbus spec).
Header#
The Header is always 11 bytes and is composed of:
Start (one byte) – Denotes the start of the V5 frame. Always
0xA5
.Length (two bytes) – Payload length
Control Code (two bytes) – Describes the type of V5 frame. For Modbus RTU requests, the control code is
0x4510
. For Modbus RTU responses, the control code is0x1510
.Serial (two bytes) – This field acts as a two-way sequence number. On outgoing requests, the first byte of this field is echoed back in the same position on incoming responses. pysolarmanv5 expoits this property to detect invalid responses. This is done by initialising this byte to a random value, and incrementing for each subsequent request. The second byte is incremented by the data logging stick for every response sent (either to Solarman Cloud or local requests).
Logger Serial (four bytes) – Serial number of Solarman data logging stick
Payload#
The Payload fields vary slightly between request and response frames. The size of the Payload will also vary depending on the size of the embedded Modbus RTU frame.
Request Payload#
A request payload is 15 bytes + the length of the Modbus RTU request frame, and is composed of:
Frame Type (one byte) – Denotes the frame type. pysolarmanv5 sets this to
0x02
on outgoing Modbus RTU requests, where0x02
is understood to mean the solar inverter.Sensor Type (two bytes) – Denotes the sensor type. pysolarmanv5 sets this to
0x0000
on outgoing requests.Total Working Time (four bytes) – Denotes the frame total working time. See corresponding response field of same name for further details. pysolarmanv5 sets this to
0x00000000
on outgoing requests.Power On Time (four bytes) – Denotes the frame power on time. See corresponding response field of same name for further details. pysolarmanv5 sets this to
0x00000000
on outgoing requests.Offset Time (four bytes) – Denotes the frame offset time. See corresponding response field of same name for further details. pysolarmanv5 sets this to
0x00000000
on outgoing requests.Modbus RTU Frame (variable length) – Modbus RTU request frame.
Response Payload#
A response payload is 14 bytes + the length of the Modbus RTU response frame, and is composed of:
Frame Type (one byte) – Denotes the frame type, where:
0x02
: Solar Inverter0x01
: Data Logging Stick0x00
: Solarman Cloud (or keep alive?)
Status (one byte) – Denotes the request status.
0x01
appears to denote real-time data.Total Working Time (four bytes) – Denotes the number of seconds that data logging stick has been operating. Other implementations have this field named TimeOutOfFactory.
Power On Time (four bytes) – Denotes the current uptime of the data logging stick in seconds.
Offset Time (four bytes) – Denotes offset timestamp, in seconds. This is defined as current data logging stick timestamp minus Total Working Time.
Modbus RTU Frame (variable length) – Modbus RTU response frame.
Response Timestamp Fields#
The following statements in relation to the timestamp fields are true:
Total Working Time minus Power On Time = Device Total Operation Time (as shown in Solarman Cloud).
Total Working Time plus Offset Time = Data acquisition timestamp. By definition, pysolarmanv5 frames are real-time data frames, so this is equivalent to the current unix timestamp.
Trailer#
The Trailer is always 2 bytes and is composed of:
Checksum (one byte) – Denotes the V5 frame checksum. The checksum is computed on the entire V5 frame except for Start, Checksum (obviously!) and End.
Note, that this field is completely separate to the Modbus RTU checksum, which coincidentally, is the two bytes immediately preceding this field.
End (one byte) – Denotes the end of the V5 frame. Always
0x15
.
Frame Diagrams#
Frame diagrams for request and response frames are shown below. Any values shown below are in Network Byte Order.
Request Frame Format#
Response Frame Format#
Further reading#
For further information on the Solarman V5 Protocol, see the following:
com.igen.xiaomaizhidian
APK (seesrc/java/com/igen/*
)https://github.com/XtheOne/Inverter-Data-Logger/issues/3#issuecomment-878911661