For DIY & developers
For DIY users and developers who want to put live Sigenergy data on a Shelly device, or build on top of the Sigenergy OpenAPI. Three working recipes plus full API, Modbus, and MQTT reference.
What you can build
Five live Sigenergy values mirrored as Virtual Components on any Shelly device with scripting capability (Pro 2, Pro 3EM, Pro 4PM, Plus 2PM, etc.). The values appear in the Shelly app, on the device's local web page, and in the Shelly Cloud dashboard.
VC 200 - PV Power (W) icon: solar-power (gold)
VC 201 - Battery SOC (%) icon: battery-medium (green)
VC 202 - Battery Power (W) icon: battery-charging (teal) positive = charging
VC 203 - Grid Power (W) icon: transmission-tower (orange) positive = export
VC 204 - Load Power (W) icon: home-lightning-bolt (blue)

Recipe A - Local Modbus TCP bridge
The Sigenergy system exposes Modbus TCP on port 502 with the inverter as the slave at unit ID 247. On a typical home installation, the inverter is reachable on the home LAN through the gateway. A small Python script on any always-on host on the same LAN - a small router with a Linux distro is a good fit - reads five registers once per second and pushes the values to the Shelly device over HTTP.
Polling: 1 second.
Cloud: not required.
Dependencies: none (Python stdlib only).
Auto-start: runs as a system service (
procdon OpenWrt-based routers,systemdon Linux, Scheduled Task on Windows).
Architecture:
sigen-bridge.py
-> Modbus TCP -> Sigenergy inverter (<SIGEN_IP>:502, Unit ID 247; reached via the gateway on the home LAN)
-> Number.Set HTTP POST -> Shelly VCs 200-204
Script: sigen-bridge-router.py (in Downloads below).
Recipe B - Sigenergy data subscription (HTTP push)
Configure the Sigenergy developer portal to push data to an HTTPS endpoint you control, then have the Shelly device poll that endpoint. The full setup lives in the portal: App settings → Data Subscription, mode set to http, with three endpoint URLs (system, telemetry, alarm). Sigenergy then POSTs telemetry on its push cycle (5 minutes by default) and pushes system and alarm data on event.
For displaying live values on a Shelly device, the flow is:
In your endpoint, parse the telemetry POST, extract
pvPowerW,storageSOC%,storageChargeDischargePowerW,gridActivePowerW, andinverterActivePowerW. Compute load asinverterActivePowerW + gridActivePowerW. Store the latest values where they can be served back as JSON.Expose a GET on your endpoint that returns the cached JSON.
Point the Shelly script (
sigen-monitor.jsin Downloads) at the GET URL. The script's Timer polls every 5 minutes and updates Virtual Components 200-204.
How you host the endpoint is up to you: a serverless function, a small VM, an existing internal API, anything that speaks HTTPS and is publicly reachable. A Cloudflare Workers starter is included in Downloads (worker.js, wrangler.toml) as one example.
For the portal-side steps and the activation API call, see Sigenergy's documentation: Application Dashboard → Data Subscription and Subscribe for Telemetry.
Recipe C - Modbus RS485 add-on (beta)
A direct RS485 link from the inverter's COM port terminal to a Shelly device with a Modbus RS485 add-on. The Shelly script reads the inverter's Modbus registers directly. There is no authentication, no tokens, no developer portal, no internet involved, just physical wiring and the Modbus serial parameters.
What you need:
A Shelly device with a Modbus RS485 add-on (for example a Shelly Pro device fitted with the add-on).
A twisted pair from the add-on's A+/B- terminals to the inverter COM port terminal. Ground bonded only at one end to avoid loops.
The inverter's RS485 serial parameters (baud rate, parity, stop bits) and slave ID, as documented in the SigenStor inverter spec sheet.
Shelly + Modbus RS485 add-on <-(twisted pair)-> inverter COM port
Shelly script: Modbus.Read every ~30 s -> Virtual.getHandle().setValue() -> VCs 200-204
The register map is the same one used over Modbus TCP and is documented in the next section. This recipe will be published in full (wiring photos, parameter values, ready-to-run script) once the inverter-side connection has been validated end-to-end on a production install.
API authentication
The Sigenergy OpenAPI uses a key-based auth pair (AppKey + AppSecret), obtained from the developer portal at developer.sigencloud.com → Control Center → Settings. Developer registration requires an invitation code from Sigenergy (approval typically 3-5 days).
POST /openapi/auth/login/key
Content-Type: application/json
Body: { "key": "<base64(AppKey:AppSecret)>" }
Response:
{
"code": 0,
"msg": "success",
"data": "{\"tokenType\":\"Bearer\",\"accessToken\":\"<token>\",\"expiresIn\":43199}"
}
The data field is a JSON string, not an object - parse it twice. Token lifetime is ~12 hours; re-request within 5 minutes of expiry.
Include in every subsequent call:
Authorization: Bearer <accessToken>
sigen-region: eu
Rate limits
Energy-flow / realtime endpoints: 1 call per 5 minutes per station.
General API: 10 requests per minute for third-party accounts.
Finding the System ID
mySigen → Settings → tap the three-dot menu (upper right). systemId appears in the Basic Info block.
Key endpoints
Energy Flow (real-time)
GET /openapi/systems/{systemId}/energyFlow
Fields (all kW except batterySoc):
pvPower - PV generation; always >= 0
gridPower - Grid power; positive = export, negative = import
batteryPower - Battery power; positive = charging
batterySoc - Battery SoC (%); 0-100
loadPower - Load consumption; always >= 0
evPower - EV charging power
heatPumpPower - Heat-pump power
System realtime data (generation totals)
POST /openapi/system/realtime/data
Body: { "systemId": "<systemId>" }
Returns daily, monthly, annual, and lifetime PV (kWh), plus CO2 / coal-saved / tree-equivalent figures.
Battery command (VPP / NBI)
POST /openapi/system/battery/command
Switch the battery between charge, discharge, selfConsumption, and idle modes, with optional limits on charge power, PV use, sell/purchase caps, and priority. Maximum 24 commands per batch per station.
Switch operating mode (NBI only)
POST /openapi/system/operationMode/switch
Body: { "systemId": "<systemId>", "energyStorageOperationMode": 0 }
Modes:
MSC (0) - Maximum Self-Consumption
FFG (5) - Full Feed-in to Grid
VPP (6) - VPP mode (service provider only)
NBI (8) - North Bound Integration
NBI onboarding / offboarding
POST /openapi/board/onboard
POST /openapi/board/offboard
Body: [ "<systemId>" ]
Result codes: 0 = success, 1401 = already in the requested state (harmless).
Operating modes - quick reference
Mode | Behaviour |
|---|---|
MSC | PV → load first; surplus charges battery; grid is last resort. |
Charge | Charges the battery from PV first, then grid; surplus PV is exported. |
Discharge | Discharges PV first, then battery - for peak shaving or export. |
Self-Consumption Grid | Like MSC but surplus goes to the grid, not the battery. |
Idle | Battery sits; PV surplus is exported. |
VPP | Service provider controls dispatch; owner cannot change mode. |
NBI | Designed for third-party integrations; query enabled by default, control requires explicit permission from Sigenergy. |
Modbus register map (TCP and RS485)
Connection (TCP): <SIGEN_IP>:502, Unit ID 247. The Modbus slave is the inverter; on a typical home installation it is reachable on the home LAN through the gateway. The same register map is used over RS485 to the inverter's COM port.
Using pymodbus 3.x: PDU address = full register number - do not subtract 30001.
Signal Register Count Type Scale Notes
gridPower 30005 2 int32 1 W Positive = import from grid
batterySoc 30014 1 uint16 0.1 Divide by 10 for %
pvPower 30035 2 int32 1 W
batteryPower 30037 2 int32 1 W Positive = charging
loadPower 30284 2 int32 1 W
The same register map applies on RS485. Physical RS485 parameters (baud, parity, stop bits) are in the SigenStor inverter spec sheet.
MQTT telemetry
Broker: mqtts://mqtt-eu.sigencloud.com:8883
Auth: Mutual TLS (ca.pem, client.pem, client.key from Sigenergy)
Data topic: {appKey}/openapi/period/{systemId}
Activation: publish {accessToken, systemIdList} to openapi/subscription/period
Interval: 5 minutes (configurable in developer portal)
Push types: Telemetry, Change (status change), Alarm (fault)
Telemetry payload includes per-phase grid and inverter power, total PV, storage SoC and power, charge/discharge headroom, plus system status, on/off-grid status, charge/discharge cut-off SoC, and peak-shaving / Storm Watch flags.
Sigenergy's MQTT broker enforces per-subscriber ACLs - mutual-TLS client certificates are scoped to subscribers registered through the developer portal. Plan to receive MQTT in a backend you control, then mirror to Shelly via HTTP.
Downloads
The following files are attached to this page:
sigen-bridge-router.py- Always-on Modbus-TCP bridge (Recipe A).sigen-modbus-bridge.py- Same logic, laptop variant.sigen-poller.py- Cloud-API poller, laptop variant.worker.js- Cloudflare Worker (Recipe B).wrangler.toml- Cloudflare Worker config.sigen-monitor.js- Shelly script that polls the Worker URL and updates Virtual Components.sigen-monitor-rs485.js- Shelly script for the RS485 add-on (Recipe C).sigen_agent.py- Claude-powered Sigenergy API helper.sigen_agent_README.md- Setup and usage guide for the helper.