Huawei FusionSolar (Northbound API)
Reads Huawei FusionSolar photovoltaic plants through the Northbound API (the thirdData
REST interface Huawei publishes for third-party monitoring platforms). Surfaces per-plant
daily, monthly and lifetime yield, plant health state, and — optionally — live inverter
output power.
Driver name: huawei_fusionsolar
The Northbound interface is read-only. There is no on/off, curtailment or setpoint command in this driver because the API exposes none. If a site needs to control Huawei equipment, that is a Modbus/TCP conversation with the SmartLogger, not this driver.
Prerequisites
- A Northbound API account. This is not your installer or owner login. It is created in the FusionSolar web portal under System > Company Management > Northbound Management, and it issues a username plus a system code which functions as the password. An ordinary portal login will be rejected.
- The correct regional host. A FusionSolar account is bound to one region. Credentials
valid on
eu5fail onsg5with an authentication error rather than a redirect, so theapi_baseattribute has to match the account's region. - Plants assigned to the account. Northbound accounts do not inherit the plant list from the parent company — each plant is granted explicitly. An account with no grants authenticates successfully and then returns an empty station list.
- Outbound HTTPS from the controller. This is a cloud API; a WAN outage blanks telemetry.
Regional hosts
| Region | api_base |
|---|---|
| Europe | https://eu5.fusionsolar.huawei.com (driver default) |
| Asia-Pacific / Singapore | https://sg5.fusionsolar.huawei.com |
| Australia | https://au1.fusionsolar.huawei.com |
| Latin America | https://la5.fusionsolar.huawei.com |
| International | https://intl.fusionsolar.huawei.com |
Setup steps
- Go to /admin/devices and add a device with driver
huawei_fusionsolar. - Enter
username(the Northbound account name) andpassword(the system code). - Set
api_baseif the account is not in the European region. - Run
get_stations. The response lists every plant the account can see with itsstationCode, name and capacity. If this is empty, the plants have not been assigned to the Northbound account. - Create one zone per plant. Set
zone.addressto thestationCodeexactly as returned, including theNE=prefix when the API supplies one. - Optionally enable
poll_devicesto derive live plant watts from inverter KPIs — read Rate limits first.
Rate limits shape everything
This is the constraint that determines how the driver is configured, and it is worth understanding before tuning anything.
Huawei limits the Northbound KPI interfaces to roughly one call per five minutes per
account. Exceeding it returns failCode 407 ("interface access frequency is too high").
Critically, polling faster does not get fresher data either — the cloud aggregates plant
KPIs on roughly that same cadence, so a one-minute poll spends quota to receive the same
numbers repeatedly.
The driver therefore:
- defaults
status_intervalto 300000 ms (5 minutes) and enforces a floor of 60000; - batches every plant into a single
getStationRealKpicall rather than one call per plant, so plant count does not multiply quota usage; - on
failCode 407, backs off for five minutes rather than retrying, so a misconfiguration degrades instead of compounding; - leaves
poll_devicesoff by default, because inverter polling adds one call per inverter type per cycle on top of the plant call.
The quota is per account, not per integration. If the same Northbound account is already feeding another monitoring platform, GEM is competing with it for the same budget. Create a dedicated Northbound account for GEM where possible.
Attribute reference
Device — required
| Attribute | Type | Description |
|---|---|---|
username | string | Northbound API account name. Not the portal login. |
password | string | The system code issued with the Northbound account. Stored encrypted. |
Device — optional
| Attribute | Type | Default | Description |
|---|---|---|---|
api_base | string | https://eu5.fusionsolar.huawei.com | Regional FusionSolar host. |
poll_devices | bool | false | Also poll inverter KPIs to derive live plant watts. |
status_interval | int | 300000 | Poll period in ms. Floor of 60000; 300000 recommended. |
request_timeout | int | 30000 | Per-request HTTP timeout in ms. |
Attributes written by the driver
Per zone (one zone = one plant):
| Attribute | Type | Unit |
|---|---|---|
day_energy_kwh | float | kWh generated today |
month_energy_kwh | float | kWh generated this month |
total_energy_kwh | float | kWh generated lifetime |
power_w | int | live output, watts — only with poll_devices enabled |
state | string | healthy / faulty / disconnected |
On the device row (rolled up from the first plant, so a single-plant site is useful without
creating a zone at all): day_energy_kwh, total_energy_kwh, health_state, and power_w
when poll_devices is on.
Zone address format
zone.address is the FusionSolar stationCode, copied verbatim from get_stations:
NE=12345678
Some accounts return codes without the NE= prefix. Use whatever the API returned — the
driver matches on exact string equality, so a mismatched prefix means the zone silently
never updates while the plant itself polls fine.
Commands
| Command | Arguments | Notes |
|---|---|---|
get_stations | — | List plants visible to the account. Walks the paginated endpoint, falling back to the legacy one. |
get_devices | — | List inverters, meters and other devices across the discovered plants. |
get_station_status | address | Live KPIs for one plant. |
get_device_status | dev_type_id | Real-time KPIs for all devices of one type. 1 and 38 are inverter families. |
refresh | — | Re-poll every plant now, outside the interval. |
refresh_token | — | Force a fresh Northbound login. |
Session handling
Northbound sessions expire server-side without warning. When a call returns failCode 305
("you are not authenticated"), the driver logs in again and retries that one call
transparently — a 305 in the logs followed by normal operation is expected behaviour, not
a fault. Repeated, unrecovering 305s usually mean the account has been locked by failed
logins.
The session token arrives as an XSRF-TOKEN, either as a response header or inside a
Set-Cookie; both forms exist across regions and versions, and the driver accepts either.
Known limitations
- Cloud-only. No local polling path. A WAN outage blanks all telemetry. Sites that need local resilience should use Modbus/TCP against the SmartLogger instead.
- Energy counters, not power. Plant KPIs are kWh totals. Live watts exist only by
summing inverter
active_power, which is whatpoll_devicesdoes and why it costs extra quota. - Income figures carry no currency.
day_income/total_incomeare returned in the account's currency, but the interface does not expose which currency that is, so the driver does not store them rather than label them wrongly. - Battery and meter telemetry is not mapped.
get_devicesenumerates ESS units, power meters and combiner boxes, but only inverter families (devTypeId1 and 38) are polled for plant power. Reading battery state of charge is a follow-up. - No alarms. The Northbound alarm interface is not wired; plant health comes from
real_health_stateonly, which is a three-state summary.
Troubleshooting
| Symptom | Check |
|---|---|
| Login fails immediately | Confirm this is a Northbound account, not a portal login, and that api_base matches the account's region. |
failCode 407 on every poll | status_interval is too low, or another platform shares the account. Raise to 300000+. |
get_stations returns empty | Plants must be explicitly assigned to the Northbound account under Northbound Management. |
| Plant polls fine but the zone never updates | zone.address must equal stationCode exactly, NE= prefix included. |
power_w is never written | Enable poll_devices. Plant KPIs carry energy counters only. |
Repeated failCode 305 that never recovers | The account may be locked from failed logins; reset it in the portal. |
| "login succeeded but no XSRF-TOKEN was returned" | A proxy is stripping response headers and cookies between the controller and the FusionSolar host. |