Growatt SPH (hybrid storage)
Status: Vendor Confirmed · Register points: 396 · Transports: Modbus RTU, Modbus TCP
A curated ModDef profile for the Growatt SPH (hybrid storage). Import it as
growatt.sph or load the .moddef.yaml directly.
Connect to one over Web Serial and watch its values live in the device dashboard.
Usage
Load the profile, bind a transport, and read a point by name. The runtime applies the offset, scaling, byte order, and sentinels from the definition.
- Go
- TypeScript
- Rust
- Python
- C
- C++
doc, _ := moddef.Load("growatt-sph.moddef.yaml")
dev, _ := client.New(doc, "growatt-sph", transport) // your modbus.Transport
v, _ := dev.ReadPoint(ctx, "rated_pv_voltage")
fmt.Println(v)
import {Device} from '@moddef/core';
import {loadDocument} from '@moddef/core/node';
const doc = await loadDocument('growatt-sph.moddef.yaml');
const dev = Device.create(doc, 'growatt-sph', transport);
console.log(await dev.readPoint('rated_pv_voltage'));
let doc = moddef_core::load("growatt-sph.moddef.yaml")?;
let mut dev = Device::new(&doc, Some("growatt-sph"), transport)?;
let v = dev.read_point("rated_pv_voltage").await?;
from moddef import Device, load
from moddef.pymodbus import Options, PymodbusTransport
doc = load("growatt-sph.moddef.yaml")
transport = await PymodbusTransport.tcp("192.168.1.50", options=Options())
dev = Device.create(doc, "growatt-sph", transport)
print(await dev.read_point("rated_pv_voltage"))
md_doc_t doc;
md_doc_init(&doc, flash_ptr, flash_len); /* zero-copy view */
md_dev_t dev;
md_dev_init(&dev, &doc, MD_STR("growatt-sph"), &transport);
md_value_t v;
md_dev_read(&dev, MD_STR("rated_pv_voltage"), &v);
auto doc = moddef::Document::view(flash_bytes).value(); // zero-copy over flash
auto dev = moddef::Device::open(doc, "growatt-sph", transport).value();
if (auto v = dev->read("rated_pv_voltage"); v)
std::cout << v->to_string() << '\n';
Commands
Multi-step register procedures (spec §11.7)
this profile defines — write params, arm a trigger, poll for completion, then
read the result. Run one with your language's command executor (RunCommand,
runCommand, run_command, or md_cmd_begin/md_cmd_tick in C/C++).
set_active_power_rate — Set Active Power Rate (Persistent)
Set the inverter's maximum active output power as a percentage, then make it survive a power cycle. 255 means no limit. The setpoint registers 3, 4, 5 and 99 are volatile until holding register 2 is set to 1, so this writes the value and then latches it (document register 02: "these settings will be acting or not when next power on"). Register 2 is a single flag covering all four setpoints, so latching one latches whatever the others currently hold. Leave at least 850 ms between the two writes (document section 5.3.1).
Params
| Field | Type | Required |
|---|---|---|
rate | DECIMAL | yes |
Results
| Field | Type |
|---|---|
applied | DECIMAL |
persisted | — |
set_reactive_power_rate — Set Reactive Power Rate (Persistent)
Set the inverter's maximum reactive output power as a percentage from -100 to 100, then make it survive a power cycle. 255 means no limit. The setpoint registers 3, 4, 5 and 99 are volatile until holding register 2 is set to 1, so this writes the value and then latches it (document register 02: "these settings will be acting or not when next power on"). Register 2 is a single flag covering all four setpoints, so latching one latches whatever the others currently hold. Leave at least 850 ms between the two writes (document section 5.3.1).
Params
| Field | Type | Required |
|---|---|---|
rate | DECIMAL | yes |
Results
| Field | Type |
|---|---|
applied | DECIMAL |
persisted | — |
set_power_factor — Set Power Factor (Persistent)
Set the inverter's output power factor, then make it survive a power cycle. The parameter is the raw register value, i.e. the power factor times 10000: 0 to 10000 is underexcited and 10001 to 20000 overexcited. Command params carry no transform, so unlike the power_factor_set point this value is not scaled for you. The setpoint registers 3, 4, 5 and 99 are volatile until holding register 2 is set to 1, so this writes the value and then latches it (document register 02: "these settings will be acting or not when next power on"). Register 2 is a single flag covering all four setpoints, so latching one latches whatever the others currently hold. Leave at least 850 ms between the two writes (document section 5.3.1).
Params
| Field | Type | Required |
|---|---|---|
power_factor_raw | UINT32 | yes |
Results
| Field | Type |
|---|---|
applied | UINT32 |
persisted | — |
set_pf_lock_in_voltage — Set CEI 0-21 PF Lock-In Voltage (Persistent)
Set the CEI 0-21 power-factor curve lock-in grid voltage, then make it survive a power cycle. The parameter is the raw register value in units of 0.1 V, since command params carry no transform. The setpoint registers 3, 4, 5 and 99 are volatile until holding register 2 is set to 1, so this writes the value and then latches it (document register 02: "these settings will be acting or not when next power on"). Register 2 is a single flag covering all four setpoints, so latching one latches whatever the others currently hold. Leave at least 850 ms between the two writes (document section 5.3.1).
Params
| Field | Type | Required |
|---|---|---|
voltage_raw | UINT32 | yes |
Results
| Field | Type |
|---|---|
applied | UINT32 |
persisted | — |
set_grid_first_slot1 — Program Grid First Time Slot 1
Write the start time, stop time and enable flag of grid first time slot 1 (discharging the battery to the load and grid) as one action. Start and stop times pack the hour in the high byte and the minute in the low byte. The enable flag is written last so a half-written window is never live; the protocol document does not mandate an order, that is this profile's choice. Leave at least 850 ms between the three writes (document section 5.3.1).
Params
| Field | Type | Required |
|---|---|---|
start_time | UINT32 | yes |
stop_time | UINT32 | yes |
enable | enum enable_state | yes |
Results
| Field | Type |
|---|---|
start_time | UINT32 |
stop_time | UINT32 |
enabled | — |
set_grid_first_slot2 — Program Grid First Time Slot 2
Write the start time, stop time and enable flag of grid first time slot 2 (discharging the battery to the load and grid) as one action. Start and stop times pack the hour in the high byte and the minute in the low byte. The enable flag is written last so a half-written window is never live; the protocol document does not mandate an order, that is this profile's choice. Leave at least 850 ms between the three writes (document section 5.3.1).
Params
| Field | Type | Required |
|---|---|---|
start_time | UINT32 | yes |
stop_time | UINT32 | yes |
enable | enum enable_state | yes |
Results
| Field | Type |
|---|---|
start_time | UINT32 |
stop_time | UINT32 |
enabled | — |
set_grid_first_slot3 — Program Grid First Time Slot 3
Write the start time, stop time and enable flag of grid first time slot 3 (discharging the battery to the load and grid) as one action. Start and stop times pack the hour in the high byte and the minute in the low byte. The enable flag is written last so a half-written window is never live; the protocol document does not mandate an order, that is this profile's choice. Leave at least 850 ms between the three writes (document section 5.3.1).
Params
| Field | Type | Required |
|---|---|---|
start_time | UINT32 | yes |
stop_time | UINT32 | yes |
enable | enum enable_state | yes |
Results
| Field | Type |
|---|---|
start_time | UINT32 |
stop_time | UINT32 |
enabled | — |
set_bat_first_slot1 — Program Battery First Time Slot 1
Write the start time, stop time and enable flag of battery first time slot 1 (charging the battery) as one action. Start and stop times pack the hour in the high byte and the minute in the low byte. The enable flag is written last so a half-written window is never live; the protocol document does not mandate an order, that is this profile's choice. Leave at least 850 ms between the three writes (document section 5.3.1).
Params
| Field | Type | Required |
|---|---|---|
start_time | UINT32 | yes |
stop_time | UINT32 | yes |
enable | enum enable_state | yes |
Results
| Field | Type |
|---|---|
start_time | UINT32 |
stop_time | UINT32 |
enabled | — |
set_bat_first_slot2 — Program Battery First Time Slot 2
Write the start time, stop time and enable flag of battery first time slot 2 (charging the battery) as one action. Start and stop times pack the hour in the high byte and the minute in the low byte. The enable flag is written last so a half-written window is never live; the protocol document does not mandate an order, that is this profile's choice. Leave at least 850 ms between the three writes (document section 5.3.1).
Params
| Field | Type | Required |
|---|---|---|
start_time | UINT32 | yes |
stop_time | UINT32 | yes |
enable | enum enable_state | yes |
Results
| Field | Type |
|---|---|
start_time | UINT32 |
stop_time | UINT32 |
enabled | — |
set_bat_first_slot3 — Program Battery First Time Slot 3
Write the start time, stop time and enable flag of battery first time slot 3 (charging the battery) as one action. Start and stop times pack the hour in the high byte and the minute in the low byte. The enable flag is written last so a half-written window is never live; the protocol document does not mandate an order, that is this profile's choice. Leave at least 850 ms between the three writes (document section 5.3.1).
Params
| Field | Type | Required |
|---|---|---|
start_time | UINT32 | yes |
stop_time | UINT32 | yes |
enable | enum enable_state | yes |
Results
| Field | Type |
|---|---|
start_time | UINT32 |
stop_time | UINT32 |
enabled | — |
Measurands
The 22 semantic quantities this device reports, each linked to the measurand catalog. Query a device by measurand instead of a raw point when you want portable code.
| Base quantity | Name | Unit | Description |
|---|---|---|---|
inverter_status | Inverter Status | undefined | Inverter operating state (enum) |
pv_power | PV Power | W | PV array / string power |
pv_voltage | PV Voltage | V | PV array / string voltage |
pv_current | PV Current | A | PV array / string current |
active_power | Active Power | W | Instantaneous real power |
apparent_power | Apparent Power | VA | Instantaneous apparent power |
reactive_power | Reactive Power | var | Instantaneous reactive power |
power_factor | Power Factor | 1 (ratio) | Ratio of real to apparent power (dimensionless) |
frequency | Frequency | Hz | Grid frequency |
voltage | Voltage | V | RMS voltage; qualify with phase_ref (L1_N, L1_L2, ...) |
current | Current | A | RMS current; qualify with phase_ref / direction |
dc_bus_voltage | DC Bus Voltage | V | Internal DC bus voltage |
energy_active | Active Energy | Wh | Cumulative active energy register |
inverter_temperature | Inverter Temperature | degC | Inverter internal temperature |
device_status | Device Status | undefined | Overall device operating status (enum) |
battery_power | Battery Power | W | Battery power (sign per direction) |
battery_voltage | Battery Voltage | V | Battery terminal voltage |
state_of_charge | State of Charge | % | Battery charge level |
state_of_health | State of Health | % | Battery health |
temperature | Temperature | degC | Temperature; qualify with location (INTERNAL, EXTERNAL, ...) |
fault_code | Fault Code | undefined | Vendor fault code (enum or integer) |
warning_code | Warning Code | undefined | Vendor warning code (enum or integer) |
Source
- Profile:
solar-inverter/growatt-sph/growatt-sph.moddef.yaml - Register map: vendor documentation