FastAPI app that pulls interval usage from Sungrow iSolarCloud (OAuth2), caches AER Consumer Data Right electricity plan data, and compares actual metered usage against every available plan to estimate real annual cost (TOU, tiered feed-in, and flat tariffs). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
100 lines
4.3 KiB
Markdown
100 lines
4.3 KiB
Markdown
# Connecting your real Sungrow system
|
|
|
|
Until you complete this, the app runs on synthetic mock usage data
|
|
(`USE_MOCK_ISOLARCLOUD=true`, the default) so the rest of the app is fully
|
|
usable in the meantime.
|
|
|
|
## What you need
|
|
|
|
Two separate things, both free:
|
|
|
|
1. A **regular iSolarCloud account** -- the same one you use in the app to
|
|
watch your system (username/password).
|
|
2. A **developer application** on the [Sungrow developer
|
|
portal](https://developer-api.isolarcloud.com/), which gives you an
|
|
**App Key** and **Secret Key** (and possibly an **RSA public key** --
|
|
see below). When creating the application, choose the **"V1 account
|
|
login"** option rather than OAuth2.0 -- this app talks to the plain
|
|
username/password login endpoint, not the OAuth2 authorization-code
|
|
flow (which uses a different set of endpoints and an Application ID /
|
|
redirect URI this app doesn't use).
|
|
|
|
Approval is manual on Sungrow's side and can take a couple of days.
|
|
|
|
## Configure
|
|
|
|
In `.env`:
|
|
|
|
```
|
|
USE_MOCK_ISOLARCLOUD=false
|
|
ISOLARCLOUD_APP_KEY=<your App Key>
|
|
ISOLARCLOUD_APP_SECRET=<your Secret Key>
|
|
ISOLARCLOUD_USERNAME=<your iSolarCloud account email/username>
|
|
ISOLARCLOUD_PASSWORD=<your iSolarCloud account password>
|
|
ISOLARCLOUD_REGION=australia
|
|
```
|
|
|
|
If your application's portal page also shows an **RSA public key**
|
|
(Settings -> Open API), some accounts require the password to be
|
|
RSA-encrypted before it's sent rather than plain text. Paste it into
|
|
`ISOLARCLOUD_RSA_PUBLIC_KEY` (see the commented example in `.env.example`
|
|
for the multi-line quoting). If login fails with the key set, try leaving
|
|
it blank -- not every app type needs it, and this app tries plain-text
|
|
login as the alternative.
|
|
|
|
Restart the app, then in Settings click **Test connection**. On success it
|
|
lists every plant visible to your account -- pick the right one if you
|
|
have more than one (most people don't, and can skip this).
|
|
|
|
## Verifying before trusting the numbers
|
|
|
|
The exact wire format Sungrow expects was pieced together from a
|
|
community-maintained, actively-used Home Assistant integration
|
|
([steven-g-w/HA-Sungrow](https://github.com/steven-g-w/HA-Sungrow)) built
|
|
against this same portal and app type, since Sungrow's own docs are only
|
|
visible after logging into the developer portal. Two things in
|
|
`app/isolarcloud/client.py` are explicitly flagged there as best-effort
|
|
rather than independently confirmed, and worth checking once you're
|
|
connected:
|
|
|
|
1. **RSA password encryption**, if your app was issued a key -- the exact
|
|
padding scheme isn't published anywhere public; `_encrypt_password`
|
|
uses the common RSA/PKCS1v1.5 + base64 convention. If "Test connection"
|
|
fails, check the portal's own "Documentation" page (visible after
|
|
login) for the login endpoint's exact field/encryption spec, and adjust
|
|
`_encrypt_password` if it differs.
|
|
2. **Which device is which.** iSolarCloud reports generation, load, and
|
|
grid import/export per *device* (inverter, meter, ...), not per plant.
|
|
`fetch_interval_data` assumes one meter device (for import/export/load)
|
|
and one inverter device (for generation), which fits the common
|
|
single-inverter household setup this app targets. Run:
|
|
|
|
```bash
|
|
python scripts/verify_isolarcloud_cli.py devices --ps-id <your plant id>
|
|
```
|
|
|
|
and confirm it finds exactly one of each. If your system has multiple
|
|
inverters or a different device layout, `fetch_interval_data` in
|
|
`app/isolarcloud/client.py` will need adjusting to combine them.
|
|
|
|
Then check the actual numbers look right:
|
|
|
|
```bash
|
|
python scripts/verify_isolarcloud_cli.py history --hours 6
|
|
```
|
|
|
|
Compare the printed generation/load/import/export figures against what
|
|
the iSolarCloud app itself shows for the same window. Also worth noting at
|
|
this point, since it affects how accurate the time-of-use plan comparisons
|
|
can be:
|
|
|
|
- **History retention**: how far back the minute-data endpoint actually
|
|
returns data for your account (days? weeks? months?). The app is
|
|
designed to be honest about small sample sizes and improve automatically
|
|
as local history accumulates either way.
|
|
- **True interval resolution**: confirm you're actually getting 5-minute
|
|
granularity, not a coarser aggregate -- time-of-use plans need at least
|
|
30-minute resolution to be modeled accurately.
|
|
|
|
Once satisfied, the scheduler will poll your real plant on the same
|
|
schedule it was polling mock data -- no other change needed.
|