sun-stats er et lokalt dashboard for å vise:
- solproduksjon fra Tibber live (
powerProduction) eller Solarman - import/eksport mot strømnettet fra Tibber
- beregnet husforbruk
- 24 timers historikk lagret lokalt i SQLite
Målet er en enkel kiosk-visning for iPad eller skjerm på hjemmenettverket.
Prosjektet har en fungerende backend/frontend-struktur, lokal lagring, polling av live-data og et kiosk-UI.
Det som fungerer nå:
- Fastify-backend med API-endepunkter for live-data, historikk og health
- React/Vite-frontend med automatisk oppdatering
- lokal SQLite-lagring av snapshots og 24t-historikk
- Tibber-integrasjonsskjelett
- Solarman-integrasjonsskjelett
- Docker Compose-oppsett for hjem-server
Det som fortsatt er uavklart:
- Solarman-integrasjonen bruker nå Solarman Open API (
globalapi.solarmanpv.com) — krever appId/appSecret - frontend bruker HTTP-polling som primær oppdateringsmekanisme
- WebSocket-endepunkt finnes i backend-koden, men er ikke i aktiv bruk i frontend
Hvis du bare vil kjøre prosjektet lokalt og utvikle videre, er repoet klart til det.
Ligger i apps/backend.
Ansvar:
- hente data fra Tibber live, med valgfri Solarman-polling
- normalisere målepunkter til ett internt format
- lagre snapshots i SQLite
- eksponere API for frontend
Viktige filer:
- index.ts: oppstart, bakgrunnsjobber, server-start
- server.ts: HTTP-ruter
- tibber.ts: Tibber-klient
- solarman.ts: Solarman-klient
- snapshot-engine.ts: beregning av status og last
- db.ts: SQLite-lagring
Ligger i apps/frontend.
Ansvar:
- vise live snapshot
- vise 24 timers historikk
- fungere på iPad/kiosk-visning
Frontend poller:
/api/livehvert 5. sekund/api/history?window=24hhvert 60. sekund
SQLite-database lagres som:
Backend eksponerer disse endepunktene:
GET /api/liveGET /api/history?window=24hGET /api/healthGET /ws/livefinnes, men frontend er ikke avhengig av den nå
{
"ts": "2026-03-10T14:17:43.111Z",
"solarW": 0,
"gridImportW": 0,
"gridExportW": 0,
"homeLoadW": 0,
"solarFreshness": "offline",
"gridFreshness": "offline",
"status": "degraded"
}{
"now": "2026-03-10T14:17:46.979Z",
"tibber": {
"name": "tibber",
"freshness": "offline",
"authenticated": true,
"lastSuccessAt": null,
"lastError": null
},
"solarman": {
"name": "solarman",
"freshness": "offline",
"authenticated": false,
"lastSuccessAt": null,
"lastError": "Paused by config (SOLARMAN_ENABLED=false)"
}
}- Node.js 25 eller nyere
- npm 11 eller nyere
- Docker hvis du vil bruke Compose
Testet lokalt med:
- Node
v25.6.1 - npm
11.9.0
npm installKopier eksempel-filen:
cp .env.example .envFyll inn minst:
TIBBER_ACCESS_TOKEN="..."
SOLARMAN_ENABLED=falseHvis token eller passord inneholder spesialtegn, bruk anførselstegn.
npm run dev --workspace backendBackend lytter som standard på:
Nyttige sjekker:
I et nytt terminalvindu:
npm run dev --workspace frontendFrontend kjører på:
Vite er konfigurert til å proxye /api til backend på localhost:3001.
Se .env.example.
Viktigste felter:
TIBBER_ACCESS_TOKENSOLARMAN_ENABLED(true/false)PORTTZ
Når SOLARMAN_ENABLED=true må du også sette:
SOLARMAN_APP_ID— fra Solarman support (service@solarmanpv.com)SOLARMAN_APP_SECRET— fra Solarman supportSOLARMAN_EMAIL— e-posten du er registrert med i SolarmanSOLARMAN_PASSWORD— passordet ditt (SHA256-hashes automatisk)
Valgfrie Solarman-felter:
SOLARMAN_PLANT_ID— auto-resolves hvis tomSOLARMAN_DEVICE_SN— serienummer på inverter, auto-resolves hvis tomSOLARMAN_BASE_URL— standardhttps://globalapi.solarmanpv.com
Polling og freshness:
SOLARMAN_POLL_INTERVAL_MSSNAPSHOT_INTERVAL_MSSOLAR_STALE_AFTER_MSGRID_STALE_AFTER_MS
Repoet inneholder:
Start med:
docker compose up --build -dDa er frontend tilgjengelig på:
Kjør alle tester:
npm testBygg hele prosjektet:
npm run buildWorkspace-spesifikt:
npm run test --workspace backend
npm run test --workspace frontend
npm run build --workspace backend
npm run build --workspace frontendBackend normaliserer alle målinger til et snapshot med:
tssolarWgridImportWgridExportWhomeLoadWsolarFreshnessgridFreshnessstatus
homeLoadW beregnes som:
homeLoadW = solarW + gridImportW - gridExportW
Backend kjører ikke eller lytter ikke på 3001.
Sjekk:
curl http://localhost:3001/api/healthSjekk at .env finnes i repo-roten og at feltene ikke er tomme.
Eksempel:
TIBBER_ACCESS_TOKEN="..."
SOLARMAN_ENABLED=falseSjekk health-endepunktet:
curl http://localhost:3001/api/healthHvis SOLARMAN_ENABLED=false, vil health vise Solarman som pauset.
Denne advarselen er forventet med node:sqlite i Node 25:
ExperimentalWarning: SQLite is an experimental feature
Den stopper ikke appen.
Prosjektet forventer et Tibber access token i:
TIBBER_ACCESS_TOKEN
Per nå brukes Tibbers GraphQL-endepunkter fra backend-koden i tibber.ts.
Prosjektet bruker Solarman Open API (globalapi.solarmanpv.com) for å hente sanntidsdata fra inverteren.
API-ruter som brukes:
POST /account/v1.0/token— autentisering (SHA256-hashet passord)POST /station/v1.0/list— finne stasjonerPOST /station/v1.0/device— finne enheter (inverter) på en stasjonPOST /device/v1.0/currentData— sanntidsdata fra inverter
For å bruke Solarman-integrasjonen trenger du:
- En konto på
home.solarmanpv.com - En
appIdogappSecret— send e-post tilservice@solarmanpv.com - Sett alle fire påkrevde env-variabler (
SOLARMAN_APP_ID,SOLARMAN_APP_SECRET,SOLARMAN_EMAIL,SOLARMAN_PASSWORD)
Plant ID og device serial number resolves automatisk hvis de ikke er satt.
Naturlige neste steg:
- ferdigstille Tibber live measurement-verifisering mot faktisk Pulse-data
- rydde opp eller fjerne backend-WebSocket hvis polling er tilstrekkelig
- legge til batteristøtte hvis anlegget får det senere
- legge til bedre observability og tydeligere feilvisning i UI
Ingen lisens er satt i repoet foreløpig.