Skip to main content

SRNE ASP48120SH3 Modbus Register Map (validated)

Validated Modbus register map for the SRNE ASP48120SH3 three-phase hybrid inverter, verified register-by-register against the live Nansana unitunit, (including a grid-off / grid-on transition test on 2026-07-27).27 that resolved the previously-unknown registers and corrected the battery-current sign.

Bus: RS485, 9600 8N1, function code 03 (read holding registers), slave address 1. Source of truth (code): src/inverter/registers.py in nfe-modbus-energy-logger. Legend: VERIFIED = decoded value matched physical reality live. INFERRED = best-effort from live values. UNCONFIRMED = needs a different operating state (off-grid / heavy charge) to prove.

Valid register ranges (probed live)

  • P00 product info: 0x0000 to 0x0049
  • P01 battery / DC: 0x0100 to 0x0111
  • P02 inverter telemetry: 0x0200 to 0x023F (0x0240 and beyond return "Illegal data address")
  • P03 control commands: 0xDF00 to 0xDF09 (write-only, read back 0)
  • Settings E (writable params): 0xE001 to 0xE02D
  • ; Settings F: 0xF000 to 0xF01F

Live telemetry, full per-phase (P02) - VERIFIED

quantity phase A phase B phase C notes
grid voltage 0x0213 0x022A 0x022B x0.1 V (all go to 0 when grid is off)
grid current 0x0214 (none)0x0238 (none)0x0239 x0.1 A. GRIDB/C CURRENT IS PHASE A ONLYlive in the documentedextended mapblock, CONFIRMED grid-side by the transition test
grid frequency 0x0215 - - x0.01 Hz
grid active power0x023A0x023B0x023CW (extended block, grid-side)
inverter voltage 0x0216 0x022C 0x022D x0.1 V
inverter current 0x0217 0x022E 0x022F x0.1 A (rises when off-grid, inverter sources the load)
inverter frequency 0x0218 - - x0.01 Hz
load current 0x0219 0x0230 0x0231 x0.1 A (load-side, holds through the transition)
load active power 0x021B 0x0232 0x0233 W. NONo total register: sum the three phases
load reactive power (none)derive) 0x0234 0x0235 var. REACTIVE IS B/C ONLY (phasePhase A: derive)S=sqrt(P^2+Q^2) not given, derive
load apparent power 0x021C (none)derive) (none)derive) VA. APPARENT IS PHASE A ONLY (B/C: derive S = sqrt(P^2 + Q^2))
load ratio 0x021F 0x0236 0x0237 %
load PF0x021A--reads 0 (unpopulated) - derive PF = P / S

Other P02: state 0x0210 (enum),0x0210, password status 0x0211, bus V 0x0212 (x0.1) = PBus 0x0228 + NBus 0x0229, inverter DC component 0x021D (mV), mains charge current 0x021E (x0.1 A), heat-sink temps 0x0220/0x0221/0x0222 (x0.1 C, 0x0223 bogus), PV charge current 0x0224 (0, no PV), inverter fault 0x0226, charge status 0x0227. Extended grid block tail 0x023D/0x023E/0x023F (0/221/245/309 on grid) is grid-side reactive/apparent, exact split still to confirm.

Battery / DC (P01) - VERIFIED

SOC 0x0100 (%), battery V 0x0101 (x0.1 V), battery Icurrent 0x0102 (x0.1 A, signed, + charge / - discharge)signed), device temp 0x0103 (reads 0, dead), DC load 0x0104-0x0106 (0), PV1 0x0107-0x0109 (0, no PV), charge state 0x010B (enum, mislabelled on this model),0x010B, charge power 0x010E (W),0x010E, PV2 0x010F-0x0111 (0).

IMPORTANT - battery current sign is POSITIVE = DISCHARGE on this unit (the OPPOSITE of the generic SRNE V1.7 doc). Proven by the 2026-07-27 off-grid test: with grid and PV both at 0, the battery is the only source, and while it was unambiguously discharging ~750 W to the loads it read +14.2 A; when the grid returned, discharge collapsed to +0.4 A (idle). So positive current = discharge, negative = charge.

ExtendedGrid-off / grid-on transition test (2026-07-27) - what died vs held

  • GRID-side (went to 0 when utility cut, back live when restored): grid V A/B/C (0x0213/0x022A/0x022B), grid I A (0x0214), grid freq (0x0215), and the whole extended block 0x0238 to 0x023F - MODEL-SPECIFIC, NOT in the SRNE V1.7 doc

    Discovered by probing (the V1.7 doc stops at 0x0237). Read live in mains/bypass:

    addrlive valueINFERRED meaningstatus
    0x0238~12 (1.2 A)per-phase current B (likely GRID current B)UNCONFIRMED (= loadgrid I B in bypass)
    0x0239~13 (1.3 A)per-phase current C (likely GRID current C)UNCONFIRMED
    0x023A~1816active power phase AINFERRED (matches load P_A)
    0x023B~267active power phase BINFERRED (matches load P_B)
    0x023C~201active power phase CINFERRED (matches load P_C)
    0x023D~2150total or apparent (phase A ~2187 VA)UNCONFIRMED
    0x023E~297unknownUNCONFIRMED
    0x023F~309unknownUNCONFIRMED

    IMPORTANT: in mains/bypass mode grid current = load current = (near) inverter current, so grid-side vs load-side registers are indistinguishable from this state. To confirm 0x0238/0x0239 as GRID current B/C (and+ grid power). This is how the 0x023A-Fextended meanings),block re-readwas duringidentified.

  • an
  • LOAD-side (held through the transition, source-independent): load I/P/Q per phase (0x0219, 0x021B, 0x0230-0x0237).
  • INVERTER-side (rose off-grid oras heavy-chargeit took the load): inverter I A/B/C (0x0217/0x022E/0x022F).
  • STATE 0x0210: 2 = on-grid / mains-bypass, 3 = off-grid / inverter-powered (both codes validated by the transition). Charge state where0x010B: 0 off-grid, load1 andon-grid.
  • inverter differ. Community SRNE docs found online map 0x0230+ differently (e.g. "R-phase voltage") because they are for other SRNE models; they do NOT apply to this three-phase ASP unit.

Corrections vs the generic SRNE V1.7 doc (do NOT trust the generic enums)enums/signs)

  • Battery current sign: positive = discharge (doc says positive = charge - WRONG here).
  • Machine state 0x02100x0210: 2 = 2running/mains-bypass, means3 RUNNING= (mains/bypass),off-grid. NOT the generic "initialization"initialization/soft-start". Only code 2 is verified.
  • Power factor 0x021A reads 0. Derive PF = active (0x021B) / apparent (0x021C).
  • Device temperature 0x0103 reads 0. Use heat-sink temps 0x0220 to 0x0222.
  • Charge-state enum 0x010B reads "1 = quick charge" even at 94% SOC with 0 W charge power, so the generic charge-state enum does NOT match this model either.

For the OpenEMS driver (important)

  • There is NO grid-power register, NO inverter-output-power register,and NO ESS/battery AC-power register, and NO total-power register on this unit.register. The only power registers are LOAD power per phase.
  • Therefore the ESS SymmetricEss.ACTIVE_POWER must be DERIVED from battery DC power (0x0101 x 0x0102), the same V x I used for DcDischargePower.. Do NOT map load power 0x021B to ACTIVE_POWER: 0x021B(that is what the loads consume (verified 1803 W while the battery was idle/charging ~16 W), and it isloads, phase A only.only).
  • Dc/ESS power sign: since positive battery current = discharge, DcDischargePower = +V x I (do NOT negate). A negated formula reports a real discharge as a charge.
  • Grid meter can now have per-phase current and power: grid I A/B/C (0x0214/0x0238/0x0239) and grid active power A/B/C (0x023A/0x023B/0x023C).
  • Consumption/backup meter active + reactive power per phase are available from the load registers (0x021B/0x0232/0x0233 active, 0x0234/0x0235 reactive) and can populate the ElectricityMeter power channels..

Writes

Both FC06 and FC16 are supported. Read-only registers reject with exception code 7. Settings 0xE0xx are writable. Control 0xDF00 area (power/reset/restore) is dangerous on the live unit: documented, not fired.