Solisdash
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.
What you get
- 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.
Quick start
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).
Pages
| 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. |
solisdash CLI
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.
Invoke tasks
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
Layout
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)
Development
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.
License
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.
Metadata
Release files for solisdash 0.10.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| solisdash-0.10.0.tar.gz | 291.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| solisdash-0.10.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 493.2 kB
Release files / solisdash-0.10.0.tar.gz
| Download URL | solisdash-0.10.0.tar.gz |
|---|---|
| Size | 291.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3e13c4438d660529d05cdb41b6cdcd941091f5282e026ab7e8c79f927c2dda1e
|
|
BLAKE2b-256 checksum How to use checksums |
b1a1860a13847d7a38c19e46cfbfdd3196e53a5c4085b2795d711b9b9ed1fd71
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency logRelease files / solisdash-0.10.0-py3-none-any.whl
| Download URL | solisdash-0.10.0-py3-none-any.whl |
|---|---|
| Size | 201.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8b53aa3f9f06797c01dca333254daeca2523cd038e783074ccca6052e76f7b5e
|
|
BLAKE2b-256 checksum How to use checksums |
741cd40e1f298dedb972083555dd837f9828fa1b314ca3e681d5751166bb1040
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency log