Self-hosted web dashboard for the SolisCloud (Ginlong Solis) platform. Live tiles on top, historical charts and an alarm feed below. FastAPI + HTMX + Jinja2 + Pico CSS, MongoDB-backed, with an in-process APScheduler poller.
- Live tiles — current power, today's yield, this-month yield, battery SOC, open alarms. Refreshed every 30 s via HTMX; falls back to the most recent stored sample when SolisCloud rate-limits.
- History charts — day (5-min granularity), month (daily totals), year (monthly totals), all-time (yearly totals). Reads MongoDB only, no upstream calls on the chart path.
- CSV export for any chart view.
- Alarm feed paginated and filterable by station + state.
- In-process poller (APScheduler) that pulls
stationDetailevery 5 min and alarms on the same cadence, plus a nightly daily-rollup job at 00:30 UTC. Rate-limited via a sharedTokenBucket. - Session-cookie auth (bcrypt) with an
invoke add-userCLI. /health(liveness) and/ready(Mongo + scheduler) probes.- Dark-mode toggle that persists per-browser.
cp .env.example .envand fill in:SOLIS_KEY_ID/SOLIS_KEYSECRETfrom SolisCloud → Account → Basic Settings → API Management.SOLIS_API_URL— the region-specific base URL (EU:https://www.soliscloud.com:13333).SOLIS_MONGODB_URI— a non-prod MongoDB Atlas cluster.SESSION_SECRET— generate withpython -c "import secrets; print(secrets.token_urlsafe(32))".- Optional:
RUN_SCHEDULER=trueto enable the in-process poller,SOLIS_STATION_IDto pin the dashboard to one station.
uv sync --extra dev- Seed your first admin:
uv run python -m invoke add-user --username you --role admin - Pick one:
- Desktop window —
uv run solisdashopens the app in a native pywebview window with menus and the sun icon. Closes when you quit the window. Best for "me using it from my laptop". - Detached server —
uv run python -m invoke startruns uvicorn in the background, log atvar/uvicorn.log, lifecycle viastop/restart/status. Best for hosting on a small VPS.
- Desktop window —
- Visit http://127.0.0.1:8000 (or whatever port
solisdashprinted — it picks a free one by default).
| Path | Notes |
|---|---|
/ |
Live tile dashboard (auth-gated). |
/history |
Day / month / year / all-time charts with a download-CSV link. |
/alarms |
Filterable alarm feed (auth-gated). |
/login, /logout |
Session cookie auth. |
/health, /ready |
Liveness + readiness probes. |
uv run solisdash # open the dashboard in a pywebview window
uv run solisdash --no-window # serve uvicorn in the foreground (ssh / headless)
uv run solisdash --port 8000 # pin the port instead of letting the OS pick
uv run solisdash --debug # pywebview dev tools + debug uvicorn logging
The pywebview window picks a free port by default, ships a native menu bar (File / View / Help with Dashboard / History / Alarms shortcuts), and uses the bundled sun icon on the dock / taskbar.
uv run python -m invoke start # detached uvicorn
uv run python -m invoke stop / restart / status
uv run python -m invoke test # full suite under pytest-xdist
uv run python -m invoke lint # ruff + mypy
uv run python -m invoke add-user --username … --role admin|user
uv run python -m invoke poll-once # one-shot stationDetail pull
uv run python -m invoke backfill --start YYYY-MM-DD --end YYYY-MM-DD
src/solisdash/— application packageapp.py— FastAPI app, lifespan, routesclient.py— async SolisCloud client (HMAC-SHA1 signing, retry/backoff)signing.py— HMAC-SHA1 signing helper, pinned to the V2.0.3 worked exampledb.py— Mongo connection + index schemaauth.py— bcrypt hashing, session helpers, FastAPI depsconfig.py— pydantic-settings facadetiles.py,history.py,alarms.py— page-specific servicespoller.py,ratelimit.py,scheduler.py— APScheduler poller + token buckettemplates/,static/— Jinja2 + Pico CSS
tests/— pytest suite (160 tests, parallel-safe underpytest-xdist)tasks.py— invoke build/admin taskstasks/todo.md— build plan (every step ticked through Polish)CLAUDE.md— project conventions for Claude Code sessionsSolisCloud Platform API Document V2.0.3.pdf— upstream API spec (source of truth)
uv run python -m invoke lint # ruff + mypy
uv run python -m invoke test # pytest -n auto
CI runs the same against a mongo:7 service container in GitHub Actions on every push and PR to main.
GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). Network use is distribution — if you run a modified version of Solisdash on a server users interact with, they're entitled to the modified source.