Sungrow iSolarCloud Integration for Home Assistant
Custom component that integrates Sungrow inverters via the iSolarCloud API into Home Assistant using the sungrow-isolarcloud library (a maintained fork of pysolarcloud).
It authorizes once against your iSolarCloud OpenAPI application, discovers every plant on the account, and polls each on a schedule — mapping your inverters, batteries, meters and WiNet-S onto Home Assistant's device tree, with the correct device/state classes so everything feeds straight into the Energy dashboard.
📖 Full documentation & setup guide → sungrow-hass.kroper.uk
flowchart LR
subgraph HA["🏠 Home Assistant"]
direction TB
E["Config entry<br/>(iSolarCloud account)"] --> C["Coordinator<br/>per plant"]
C --> S["Sensors · binary sensors<br/>numbers · selects"]
end
HA <-->|"OAuth 2.0 · token refresh"| API["☁️ iSolarCloud<br/>OpenAPI"]
C -.->|"poll ~5 min"| API
API --> HW["🔌 Inverters · batteries<br/>meters · WiNet-S"]
Your hardware maps onto Home Assistant as one account → many plants → each plant's physical devices (inverter, battery, meter, WiNet-S) nested underneath it. See Sensors → Device grouping.
Features
- Cloud Polling — fetches real-time data from the iSolarCloud API.
- Auto-Discovery — automatically finds all plants linked to your account.
- Sensors — creates sensors for every available data point (power, energy, battery SOC, etc.) with correct device/state classes for the Energy dashboard.
- Device health & diagnostics — a per-device Fault (problem) and Connectivity (online/offline) binary sensor, plus device-level diagnostic sensors (inverter temperature, MPPT voltages/currents, grid frequency, WLAN/wireless signal strength). Device cards are enriched with model, serial number and manufacturer; the Fault sensor exposes a human-readable reason (operating status) so you see why, and the Connectivity sensor exposes the commissioning date.
- Per-device grouping — plant readings are automatically grouped under the physical device they come from (inverter, battery, meter, WiNet-S), nested beneath the plant, so the Home Assistant device tree mirrors your hardware. Entity IDs and history are unchanged; aggregate readings on multi-inverter plants stay on the plant device.
- Plant health & tariffs — plant-wide alarm/fault counts, nameplate power, and your configured import/export electricity prices, surfaced as sensors on the plant device.
- Custom measure points — request additional iSolarCloud point IDs (e.g. battery charge/discharge power or EV charger values) via the options flow.
- Dispatch / control entities — number and select entities for charge/discharge command, power, SOC limits, forced charging, and export/active-power limiting, with automatic EMS heartbeat when dispatching. Battery-only controls are hidden on PV-only plants so they can't be triggered on a system without a battery.
- Safer dispatch (auto-revert) — set a Forced Dispatch Duration and a forced charge/discharge automatically reverts to Stop after that long (surviving restarts), so a command can't silently persist and curtail your solar. Leave it at 0 to keep the legacy always-on behaviour.
- Resilient polling — rides out brief network/API hiccups instead of flapping every entity to unavailable, and automatically backs off the polling interval when iSolarCloud rate-limits the account.
- Guided repairs — surfaces iSolarCloud whitelist (E918/E919) and rate-limit (E998/E999) rejections as actionable Home Assistant Repairs with fix instructions, and proactively warns as the observed API call rate approaches the ~2000 calls/hour budget — naming the call type that dominates — so you can widen the interval requests start being rejected.
Use cases
Typical things people use this integration for:
- Monitor your solar system in Home Assistant — live generation, house consumption, grid import/export and battery state of charge as sensors, with the correct device/state classes so they feed straight into the Energy dashboard and long-term statistics.
- Time-of-use battery control — combine the dispatch number/select entities with automations to charge the battery from the grid when electricity is cheap and discharge it during peak-price periods (see Example automations).
- Force-charge before high demand — top the battery up ahead of a known heavy-usage window (e.g. before cooking or an EV charge session) using the forced-charging entities.
- EV charger & meter visibility — enable per-device sensors to surface EV charger power/energy and meter readings alongside the plant data.
- Alerting — notify on low battery SOC, a plant going unavailable, or a fault, using standard Home Assistant automations on the sensors this integration creates.
Installation
HACS (Recommended)
Or manually:
- Open HACS → Integrations.
- Click the three-dot menu → Custom repositories.
- Add
https://github.com/KRoperUK/sungrow-hass as an Integration.
- Search for Sungrow iSolarCloud and install.
- Restart Home Assistant.
Manual
- Download the latest release.
- Copy
custom_components/sungrow into your Home Assistant custom_components directory.
- Restart Home Assistant.
Configuration
- Go to Settings → Devices & Services.
- Click Add Integration and search for Sungrow iSolarCloud.
- Enter your iSolarCloud API credentials:
| Field | Description |
|---|
| Gateway | Your region: Europe, International, China, Australia, or India |
| App Key | AppKey from the iSolarCloud Developer Platform |
| App Secret | AppSecret from the Developer Platform |
| App ID | App ID — found in the Developer Platform URL: …/editApplication?id=1234 |
| Redirect URI | Pre-filled; leave as default unless you know what you're doing |
- Click Submit. The hub is created immediately and Home Assistant prompts you to authorize it (shown as a "reconfigure/authorize" notification on the integration). Creating the hub first is what registers the callback endpoint, so the redirect resolves reliably even on a brand-new install.
- Open the authorization prompt → a "Waiting for authorization" screen appears with a link. Open the link, log in to iSolarCloud, and approve the application. You're redirected back and Home Assistant captures the authorization code automatically (via the
/api/sungrow_hass/callback endpoint) and finishes — no copy-and-paste needed.
- If the automatic redirect doesn't complete within a couple of minutes (for example because iSolarCloud strips query parameters from your redirect URI), the screen falls back to a manual entry form. Paste the
code from the redirect URL — or the whole redirect URL — to finish authorizing the hub.
Obtaining Credentials
Register an application on the iSolarCloud Developer Platform to get your App Key, App Secret, and App ID.
Note: New developer applications must be approved by Sungrow (and have OAuth 2.0 enabled) before authorization will work — this can take up to a week.
Options
After setup, go to Settings → Devices & Services → Sungrow → Configure to change:
- Polling interval (default 5 minutes)
- Extra measure points — add custom
point_id=code pairs to request additional data points from iSolarCloud
- Create per-device sensors — off by default. When enabled, each discovered device (EV charger, meter, extra battery) is polled for its own realtime points and exposed as sensors under its own device card, grouped beneath the plant. Combine with Extra measure points to surface device-specific point IDs (e.g. an EV charger). Adds extra API calls, so leave it off if you only need plant-level data.
Changing region or credentials
Picked the wrong gateway region, or rotated your API secret? Use Settings →
Devices & Services → Sungrow → ⋮ → Reconfigure to update the region, App Key,
App Secret, or redirect URI without deleting and re-adding the integration (your
entity history is kept). You'll be asked to authorize again in the browser, since
new credentials or a new region need fresh tokens. The App ID stays fixed.
Removing the integration
Go to Settings → Devices & Services → Sungrow iSolarCloud → ⋮ → Delete. This
removes the config entry and all of its entities and devices; no files are left
behind (uninstall the repository from HACS separately if you also want to remove
the code). Your iSolarCloud account and developer application are unaffected.
Sensor mapping
Not sure which sensor corresponds to which value in the iSolarCloud app? See docs/SENSORS.md.
How data updates
This is a cloud-polling integration — it does not talk to the inverter locally.
- Polling. Home Assistant polls the iSolarCloud API on a fixed interval using one data update coordinator per plant. Every sensor for a plant refreshes together on each poll.
- Interval. The default is 5 minutes. Change it under Configure → Polling interval (minimum 10 seconds). Lower intervals update sooner but use more of your API quota (the free developer plan allows ~2000 calls/hour); enabling per-device sensors adds a call per device type each poll.
- Availability. Entity state reflects the last successful poll. A single failed poll (network/API blip) no longer flips everything to unavailable — the integration keeps serving the last-known values through a short grace period (~15 minutes) and retries on the next interval. Only a sustained outage marks entities unavailable; no restart is needed to recover.
- Rate limiting. If iSolarCloud rejects a poll for exceeding the call quota (E998/E999), the integration automatically backs off — doubling the effective interval up to a 1-hour cap — and raises a Home Assistant Repair suggesting a higher polling interval. It returns to your configured interval once the quota recovers. Separately, the integration tracks the request rate it generates itself (tagged by call type) and raises a proactive Repair once the observed rate approaches ~80% of the ~2000 calls/hour budget, before iSolarCloud rejects anything; the per-call-type rate is included in the diagnostics download (
api_call_rate).
- Authentication. Access tokens are refreshed automatically and the rotated tokens are persisted, so entities stay available across restarts. If your credentials are revoked or expire, the integration triggers a re-authorization prompt rather than silently failing.
- Dispatch controls are write-only. The dispatch number/select entities send commands to the inverter; iSolarCloud does not report their current value back, so they act as controls (their state is not polled). Setting Charge or Discharge also switches Energy Management Mode to Compulsory (Forced) so the inverter actually follows the command; Stop restores Self-consumption. While actively charging/discharging, a background EMS heartbeat is kept running.
Example automations
Entity IDs depend on your device name — check Settings → Devices & Services → Sungrow for the exact IDs. The examples below assume a device called inverter.
Charge the battery overnight (cheap tariff), then return to self-consumption:
automation:
- alias: "Battery: charge overnight"
triggers:
- trigger: time
at: "00:30:00"
actions:
- action: number.set_value
target:
entity_id: number.inverter_charge_discharge_power
data:
value: 3000
- action: sungrow.set_battery_mode
data:
mode: force_charge
duration_minutes: 300 # auto-revert after 5 hours
entity_id: select.inverter_battery_mode
- alias: "Battery: self-consumption at peak start"
triggers:
- trigger: time
at: "05:30:00"
actions:
- action: sungrow.set_battery_mode
data:
mode: self_consumption
entity_id: select.inverter_battery_mode
Notify when the battery gets low:
automation:
- alias: "Battery: low SOC alert"
triggers:
- trigger: numeric_state
entity_id: sensor.my_plant_battery_state_of_charge
below: 15
actions:
- action: notify.notify
data:
message: "Home battery is below 15%."
Selecting Charge/Discharge (or setting charge/discharge power) automatically starts the EMS heartbeat; selecting Stop ends it.
Blueprints
Rather than writing the automations above by hand, you can import ready-made blueprints. Each takes your Sungrow device (or the relevant sensor) as an input selector — no entity IDs to look up — and arms dispatch through sungrow.set_battery_mode so the EMS heartbeat is started correctly.
To import one, copy its raw URL into Settings → Automations & scenes → Blueprints → Import blueprint, for example:
https://raw.githubusercontent.com/KRoperUK/sungrow-hass/main/blueprints/automation/sungrow/cheap_tariff_charge.yaml
Supported devices & regions
- Regions / gateways: Europe, International, China, Australia, and India. Pick the one matching the account you registered your developer application under.
- Devices: grid-tied inverters, hybrid inverters, and energy storage systems (ESS / batteries) that appear in your iSolarCloud account. Sensors are created for whatever data points iSolarCloud returns for your plant.
- Per-model details: the supported models matrix lists every catalogued model with its phases, AC nameplate and battery charge/discharge limits, and flags the rows still awaiting datasheet confirmation.
- Dispatch / control: number and select entities are created for inverter / ESS devices that support External EMS control. Battery controls (charge/discharge command & power, SOC limits, forced charging, battery-first mode) only appear when the plant actually has a battery/ESS — on a PV-only plant they are hidden, since dispatching charge/discharge on a battery-less inverter can force it into External-EMS mode and suppress generation. Non-battery controls (export limiting, active-power limiting) remain available on PV-only plants.
Limitations
- Cloud-only. All data comes from the iSolarCloud cloud API — there is no local polling. If iSolarCloud is unreachable, or your account/plan loses API access, entities become unavailable.
- API quota. The free developer plan allows ~2000 calls/hour; keep the polling interval sensible, especially with many sensors.
- Dispatch needs compatible firmware and plan. External EMS / parameter setting requires an inverter and iSolarCloud plan that permit it. Where unsupported, dispatch entities may error on write.
- Developer app approval. New iSolarCloud developer applications must be approved by Sungrow (with OAuth 2.0 enabled) before authorization works — this can take up to a week.
Troubleshooting
Having trouble authorizing, or entities showing as unavailable? See the
Troubleshooting guide — it covers the common
"Invalid authentication" / "Operation failed" setup errors and the
unavailable-after-reboot problem.
Development
See CONTRIBUTING.md for full developer setup and guidelines.
By participating, you agree to follow our Code of Conduct.
Helping verify a Modbus register
Several Modbus features are blocked only on confirming a register's address,
width, scale or encoding against real hardware (for example
#483,
#453 and
#334). If you run a
local Modbus entry you can help without a code change, using the read-only
sungrow.read_registers service.
In Developer Tools → Actions, pick Sungrow: Read Modbus registers, choose
your local Modbus integration entry, and set:
- Register type —
input (FC4, measurements) or holding (FC3,
config/control). Defaults to input.
- Start address — the on-the-wire address, which is the documented
register number minus one (documented
5000 → 4999).
- Count — how many registers to read (1–125).
- Slave ID — optional; only needed to probe a non-default unit, e.g. an SBR
battery at
200 (#334).
The service is read-only — it never writes — and it reuses the entry's
existing WiNet-S connection and lock, so it cannot collide with the normal poll.
It returns the raw 16-bit registers plus decoded convenience values
(u16/s16/u32/s32, decoded exactly as the register maps are: signed
two's-complement, 32-bit low-word-first). Paste that whole response into the
relevant issue so the mapping can be verified before it is added.
action: sungrow.read_registers
data:
config_entry: <your local Modbus entry>
register_type: input
start: 4999 # documented 5000
count: 4
Running Tests
pip install -r requirements_test.txt
ruff check custom_components/
ruff format --check custom_components/
pytest
Live Integration Testing
To run live tests against the real iSolarCloud API:
-
Copy .env.example to .env and fill in your credentials:
SUNGROW_APPKEY="your_app_key"
SUNGROW_APPSECRET="your_app_secret"
SUNGROW_APP_ID="your_app_id"
-
Run the live tests:
pytest -m live
Live tests are automatically skipped when credentials are not set.
Logo & icon
The integration ships icon.png / logo.png under custom_components/sungrow/.
For the brand images to appear in the Home Assistant UI's official brand system
(and on brands.home-assistant.io), the
sungrow domain also needs a PR to the
home-assistant/brands repository.
Security
Found a security issue? Please follow the disclosure process in
SECURITY.md rather than opening a public issue.
Support
Found a bug or have a feature request? Open an issue.