SRNE ASP48120SH3 (Direct Hybrid Inverter) + mbpoll Command Reference
Version: 1.01
Prepared For: Field & Deployment Teams
Platform: Raspberry Pi / Linux
Tool: mbpoll / pymodbus
1. Purpose
ThisComplete documentreference explains how to communicate withfor the SRNE ASP48120SH3 three-phase hybrid inverter usingover Modbus RTURTU: (mbpollwhat orcan pymodbus).
ItREAD, covers:what readingcan livebe telemetry (grid, inverter output, battery, temperatures), serial parametersWRITTEN, and function codes, the model-specifictested gotchaslimits. validatedValidated against the live unit,unit andat preparingNansana foron OpenEMS2026-07-21 integration.(slave address 1).
2. Hardware & Software Requirements
Hardware
- SRNE
ASP48120SH3ASP48120SH3,(three-phase hybrid inverter) - RS485 to USB converter (CH340) ,
- Raspberry Pi / Linux
PCPC. RS485 wiring:Wiring: A(converter) to WiFi-port RJ45 pin 7 (RS485-A),of the inverter WiFi-port RJ45, B(converter)B to pin 8 (RS485-B), GND to pin22.recommended.
Note: theThe WiFi port carries the monitoring RS485bus; bus. The separatethe RS485/CAN port is reserved for the battery BMS,BMS.
do
Software
.and/orsudo apt updatesudo apt install mbpollpip install pymodbus
3. Serial parameters (differand fromfunction the CHINT meters)codes
Baud96009600,baud, 8 data bits, No parity, 1 stop bit (8N1).TheSlavemetersaddressare 8N2.1.FunctionREAD: function code 03 (readholding registers).The meters use FC04 input registers.Slave address 1 (default).- 16-bit registers with scale
factors,factorsNOT(not 32-bitfloatsfloats). - WRITE: BOTH FC06 (write single) and FC16 (write multiple) are supported and tested. Note: the
meters.CHINT meters reject FC06, the inverter does NOT.
mbpollread flags: -b 9600 -P none -s 1 -t 4 -0.
-t 4-s 1-0-r4. Reading values (exhaustive, all ranges respond)
MachineEvery documented range answers FC03. Ranges (SRNE V1.7 segment map, confirmed on this unit):
Product info (P00), 0x0000 to 0x0049
- 0x000B machine type = 4 (integrated inverter-controller)
- 0x0014 software version = 925
- 0x001A RS485 address = 1 (read only)
Controller / battery (P01), 0x0100 to 0x0122
- 0x0100 SOC (%), 0x0101 battery V (x0.1), 0x0102 battery I (x0.1 signed, + charge / - discharge), 0x0103 device temp (reads 0, unused)
- 0x0104 to 0x0106 DC load V/I/P (0, no DC load on this unit), 0x0107 to 0x0111 PV panels 1/2 (0, no PV), 0x010B charge state (
0x02101 =528)quick charge)
Inverter (P02), 0x0200 to 0x0237 (the main live telemetry, see the register-map page)
- state 0x0210, bus 0x0212, grid+inverter phase A 0x0213 to 0x0218, load 0x0219 to 0x021F, heat-sinks 0x0220 to 0x0223, PBus/NBus 0x0228/0x0229, 3-phase B/C V/I 0x022A to 0x022F, 3-phase B/C load 0x0230 to 0x0237.
Settings / parameters, 0xE001 to 0xE02D (writable, see section 5). Raw values present; battery voltage thresholds around 0xE006 to 0xE00E appear as 48V-system values (register/10 x 4), e.g. 144 = 57.6 V. Exact per-register meaning is TBD from the ASP settings doc.
Settings F, 0xF000 to 0xF01F: additional parameters (raw values present).
Control commands, 0xDF00 to 0xDF09: write-only, read back as 0.
Example reads (mbpoll):
mbpoll# -mbattery rtublock -b0x0100 9600(dec -P none -s 1 -t256), 4 -0regs
-r 528 -c 1 -a 1 -1 /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0
Grid + inverter block (0x0210 to 0x0217):
mbpoll -m rtu -b 9600 -P none -s 1 -t 4 -0 -r 528 -c 8 -a 1 -1 <port>
Battery block (0x0100 to 0x0103):
mbpoll -m rtu -b 9600 -P none -s 1 -t 4 -0 -r 256 -c 4 -a 1 -1 <port>
# inverter block 0x0210 (dec 528), 32 regs
mbpoll -m rtu -b 9600 -P none -s 1 -t 4 -0 -r 528 -c 32 -a 1 -1 <port>
# settings 0xE001 (dec 57345), 45 regs
mbpoll -m rtu -b 9600 -P none -s 1 -t 4 -0 -r 57345 -c 45 -a 1 -1 <port>
(528 = 0x0210, 256 = 0x0100.)
5. Model-specificWriting gotchasvalues (validatedtested 2026-07-21)
The inverter accepts BOTH FC06 and FC16 and enforces a permission model:
MachineRead-only registers (telemetry, product info, e.g. 0x001A) REJECT writes with exception code 7 ("parameter is read only"). Tested.- Settings registers (0xE0xx) ACCEPT writes (both FC06 and FC16), with no password or run-state
0x0210lock on the tested registers (0xE015, 0xE01F, 0xE024). Tested via no-op write-back (wrote the current value, confirmed unchanged). - Control commands (0xDF00 to 0xDF09) are write-only actions. NOT fired on the live unit because it feeds customers. Documented below.
Exception code table (SRNE V1.7): 1 illegal function, 2 illegal data address, 3 illegal data value, 4 operation failed, 5 password error, 7 read only, 8 cannot change while running, 9 password protection, 10 length error, 11 permission denied.
Control command registers (DANGEROUS on a live system, documented only):
- 0xDF00 power ON/OFF: 1 =
2on,means0RUNNING= off. OFF cuts inverter output, do NOT fire while it feeds customers. - 0xDF01 reset: 1 = reset.
- 0xDF02 restore defaults: 0xAA wipes all settings.
- 0xDF03 clear current alarm: 1.
- 0xDF04 clear statistics: 1.
- 0xDF05 clear history: 1.
- 0xDF08 sleep/run: 0x5A5A sleep, 0xA5A5 run.
How to write:
# mbpoll FC06 (mains/bypass)write single): value as the last argument
mbpoll -m rtu -b 9600 -P none -s 1 -t 4 -0 -r <dec_addr> -a 1 <port> <value>
# pymodbus
client.write_register(address=REG, value=V, device_id=1) # FC06
client.write_registers(address=REG, values=[V], device_id=1) # FC16
6. Tested limits summary
- CAN: read every range over FC03; write settings 0xE0xx with FC06 or FC16; read-only registers are protected (code 7).
- CAUTION: control commands 0xDF00 to 0xDF09 are live actions (power, reset, restore). Documented, NOT fired on
thisthemodel,customer-feedingNOTunit. Only fire with an outage window and explicit sign-off. - UNKNOWN / next: exact meaning of each 0xE0xx and 0xF0xx setting (needs the
genericASPSRNEsettingsV1.7doc"initialization".orThecarefulgenericchange-and-revert testing offline); machine-statetable does not match this unit. Verifycodes othercodesthan 2 (verify by observingtransitions. Power factor 0x021A reads 0 (unpopulated). Derive PF = active power (0x021B) / apparent power (0x021C).Device temperature 0x0103 reads 0. Use heat-sink temps 0x0220, 0x0221, 0x0222 instead (scale 0.1 C). 0x0223 (heatsink D) is bogus.Writes need FC16, not FC06. Config/control registers reject FC06 with "Illegal function". Use write-multiple (FC16, or pymodbus write_registers).Bus voltage 0x0212 = PBus 0x0228 + NBus 0x0229 (split DC bus)transitions).
6.7. Preparing for OpenEMS integration
The validated registertelemetry map is captured as a declarative table (see the SRNE register-map page, andin src/inverter/registers.py in (nfe-modbus-energy-logger), grouped by OpenEMS nature:nature (ElectricityMeter for grid and grid/backup, SymmetricEss for the battery, OffGridBatteryInverter for machine state.state). It maps 1:1 to a GoodWe-style defineModbusProtocol (FC3ReadRegistersTask + UnsignedWordElementword elements + SCALE_FACTOR). Control writes map to FC16WriteRegistersTask on the 0xDF00 area and 0xE0xx settings.