Skip to main content

Documentation Index

Fetch the complete documentation index at: https://fop-50527c4b.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

The V3 generation of the SUN2000 — specifically the M3 and MB0 series — introduces native support for the LUNA2000 battery system (ESS). Alongside the expanded inverter firmware, Huawei added a dedicated register block starting at address 37000 to expose battery state, power flow, and lifetime energy totals in real time.
ESS registers are only present on V3 series inverters (M3, MB0) with a LUNA2000 battery physically connected. On V2 inverters or V3 units without a battery, these addresses will return errors or undefined values.

ESS register table

RegisterDescriptionTypeGainNotes
37000ESS unit 1 run stateU161See state values below
37001Charge / discharge powerI321W; positive = charging, negative = discharging
37003Battery bus voltageU1610V
37004SOC — ESS unit 1U1610%; e.g. raw 955 = 95.5%
37066Total charge accumulatedU32100kWh
37068Total discharge accumulatedU32100kWh
SOHState of healthU1610% — address varies by series; check your Modbus Interface Definitions

ESS unit 1 run state (register 37000)

ValueState
0Offline
1Standby
2Running
3Fault
4Sleep

ESS management modes

The ARM processor in V3 inverters manages the battery through two primary strategies:
  • Time-of-Use (TOU) — you define time windows and charge/discharge targets aligned with grid tariff schedules. The inverter charges the battery during low-tariff periods and discharges during peak-tariff periods to minimize electricity costs.
  • Self-consumption — the inverter prioritizes using solar generation to power loads directly, stores any surplus in the battery, and draws from the battery before importing from the grid. This mode maximizes self-sufficiency without requiring a tariff schedule.
Both modes are fully configured through the FusionSolar app or SmartLogger and are reflected in real time in the registers above.

Python example: reading SOC and power flow

from pymodbus.client import ModbusTcpClient
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder

HOST = "192.168.200.1"  # Inverter Wi-Fi AP address
PORT = 6607
SLAVE_ID = 1

client = ModbusTcpClient(HOST, port=PORT)
client.connect()

def read_u16(address):
    result = client.read_holding_registers(address, count=1, slave=SLAVE_ID)
    return result.registers[0]

def read_i32(address):
    result = client.read_holding_registers(address, count=2, slave=SLAVE_ID)
    decoder = BinaryPayloadDecoder.fromRegisters(
        result.registers, byteorder=Endian.BIG, wordorder=Endian.BIG
    )
    return decoder.decode_32bit_int()

def read_u32(address):
    result = client.read_holding_registers(address, count=2, slave=SLAVE_ID)
    decoder = BinaryPayloadDecoder.fromRegisters(
        result.registers, byteorder=Endian.BIG, wordorder=Endian.BIG
    )
    return decoder.decode_32bit_uint()

# ESS registers
ess_state        = read_u16(37000)
charge_power_w   = read_i32(37001)   # positive = charging, negative = discharging
bus_voltage_v    = read_u16(37003) / 10
soc_percent      = read_u16(37004) / 10
total_charge_kwh = read_u32(37066) / 100
total_disch_kwh  = read_u32(37068) / 100

STATE_LABELS = {0: "Offline", 1: "Standby", 2: "Running", 3: "Fault", 4: "Sleep"}

print(f"ESS state       : {STATE_LABELS.get(ess_state, ess_state)}")
print(f"Charge/discharge: {charge_power_w} W  (>0 charging, <0 discharging)")
print(f"Bus voltage     : {bus_voltage_v} V")
print(f"SOC             : {soc_percent} %")
print(f"Total charged   : {total_charge_kwh} kWh")
print(f"Total discharged: {total_disch_kwh} kWh")

client.close()