Commit graph

11 commits

Author SHA1 Message Date
dlawler489
1dbfe3007b Share one iSolarCloud OAuth token across both household instances
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 24s
Sungrow's OAuth server keeps only one active token session per (app,
account), not per plant -- with Kallangur and McDowall each managing their
own independent token against the same account, whichever one refreshed
last was silently invalidating the other's refresh token. Both instances
now share one token file (a common bind-mounted volume) instead of each
holding their own.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 08:04:30 +10:00
dlawler489
ad232447b8 Add data freshness indicator, TOU cost breakdown, and solar self-consumption stats to dashboard
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 23s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 07:45:05 +10:00
dlawler489
8cbcd0155f Surface AER eligibility requirements in plan comparisons
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 17s
Cost modeling can't tell you whether you actually qualify for a plan --
several top-ranked results turned out to require things like buying
solar equipment through a specific installer partner, or being a new
customer only. AER's data states these restrictions explicitly in most
cases; surface them as modeling notes (and a badge in the comparison
table) so they're visible before considering a switch, rather than
only showing up when someone tries to sign up.

Doesn't catch every restriction -- some plans (e.g. concession/seniors
offers) carry no eligibility block in AER's data at all despite an
implied real-world restriction, so absence of the badge isn't a
guarantee of eligibility.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 15:23:50 +10:00
dlawler489
e4c41c3eb9 Fix missing GST on all AER-sourced usage rates and supply charges
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 35s
AER's Consumer Data Right unitPrice fields are GST-exclusive, confirmed
by comparing a real, currently-effective EnergyAustralia contract's own
GST-inclusive rates against this plan's cached AER data: usage rates and
the supply charge all matched the cached value multiplied by exactly
1.1 (four independent figures). A real AGL bill confirmed the same
convention separately (excl-GST line items, GST added back as one
combined amount at the end). This understated every one of the ~700+
cached comparison plans' costs by ~10% relative to manually-entered
current plans (which were correctly GST-inclusive, taken from real
bills), biasing every "savings vs current" figure across the board.

Feed-in/solar buy-back rates are the exception -- confirmed GST-free in
that same contract's own terms -- so the multiplier applies only to
usage rates and the supply charge.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 15:06:39 +10:00
dlawler489
9e66a9a97d Add battery telemetry for plants with a hybrid inverter/ESS
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 24s
Confirmed against Sungrow's own docs and live-tested against a real
battery plant: SOC and charge/discharge power live at the *device*
level (getDeviceRealTimeData against the hybrid inverter's ps_key,
device_type 14), not in the plant-aggregate points used elsewhere in
this client -- querying them via the plant-level endpoint just returns
null. Battery status is fetched once per live "today" poll (not
backfilled historically) and stored in three new nullable columns,
self-migrated on startup since there's no Alembic here.

Also fixes the dashboard's self-consumption line to derive from
load - import rather than generation - export, which overstated
"solar -> house" for battery systems (a chunk of that gap was going
into charging, not the house). The live flow diagram now shows a
Battery node (SOC + charge/discharge) that stays hidden entirely for
solar-only plants like Kallangur.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 12:25:09 +10:00
dlawler489
3d7c8d9ca0 Add live power-flow diagram and net revenue to the dashboard
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 24s
New /api/usage/live endpoint derives instantaneous-ish kW from the most
recent interval reading, shown as a solar -> house/grid flow diagram
that updates every 30s and flips direction/color between exporting and
importing. /api/usage/summary now also reports net revenue for the
selected period, reusing the existing costing engine against the
current plan.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 11:52:16 +10:00
dlawler489
5ffd91a643 Hide OAuth reconnect instructions once already connected
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 25s
Settings always showed the full "how to connect" steps and code-paste
form for oauth2 mode regardless of connection status, which read as
broken even when the token was live and polling successfully. Collapse
it behind a "Reconnect" toggle once connected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 11:32:07 +10:00
dlawler489
ba070e0ad5 Fix env_file path for Docker-outside-of-Docker deploy
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 8s
The stack manager runs docker compose inside its own container (talking
to the host daemon over the mounted socket), so env_file paths resolve
against its filesystem, not the host's -- unlike volume bind-mount
sources, which the daemon resolves against the real host. Point env_file
at the stack manager's own data mount instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 11:25:42 +10:00
dlawler489
eaecc41bb1 Use absolute host paths for env/data in docker-compose.yml
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 8s
The stack manager re-clones this repo fresh on every deploy, which was
silently wiping a .env and bind-mounted data placed inside the checkout
directory. Point both at a stable location outside it instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 11:23:15 +10:00
dlawler489
9e39792d49 Add CI to build/push Docker image, switch compose to pull it
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 36s
Matches the etsy-finance-tracker pattern: Forgejo Actions builds and
pushes the image on every push to main, and docker-compose.yml now
pulls that image instead of building from source on the deploy host.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 11:15:27 +10:00
dlawler489
84c4922bbc Initial commit: solar usage vs AER plan comparison app
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>
2026-09-09 11:07:01 +10:00