- TypeScript 60.6%
- JavaScript 25.1%
- CSS 13.2%
- Dockerfile 0.8%
- HTML 0.3%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| .github | ||
| dist-server | ||
| server | ||
| src | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .prettierignore | ||
| .prettierrc | ||
| docker-compose.yml | ||
| Dockerfile | ||
| eslint.config.js | ||
| index.html | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.app.json | ||
| tsconfig.json | ||
| tsconfig.server.json | ||
| vite.config.ts | ||
PV Monitor
A self-hosted photovoltaic (solar) monitoring dashboard that reads live and historical data from Home Assistant and displays it in a React web UI.
Features
- Live power chart – PV generation, grid import/export, and battery charge/discharge over the last 24 hours
- Yield cards – today, this month, this year, and all-time totals
- Daily & monthly bar charts – production history with optional autarky overlay
- Battery status – state of charge, current power, and charge/discharge totals for today
- EV card – state of charge, charging power, odometer, energy charged, and solar share percentage
- Earnings – estimated revenue from feed-in and savings from self-consumption
- Auto-refresh every 30 seconds with a manual refresh button
All sections are optional — if the corresponding environment variables are not set, that section is silently disabled.
Architecture
Browser ←→ React + Vite SPA (port 3000 in prod)
↕
Express API server ←→ Home Assistant REST / WebSocket API
The Express server proxies requests to Home Assistant so that the HA token is never exposed to the browser. In development, Vite's dev server proxies /api/* to the Express server.
Quick Start (Docker)
- Copy
.env.exampleto.envand fill in your values (see Configuration below). - Run:
docker compose up -d - Open
http://localhost:3000.
Development
npm install
# Start API server (watches for changes)
npm run dev:api
# In a separate terminal: start Vite dev server
npm run dev
The Vite dev server runs on http://localhost:5173 and proxies /api/* to http://localhost:3000.
Other scripts
| Script | Description |
|---|---|
npm run build |
Build React app + compile server TypeScript |
npm run serve |
Serve the production build (dist-server/index.js) |
npm run typecheck |
Run tsc --noEmit for both app and server |
npm run lint |
Run ESLint |
npm run format |
Format with Prettier |
Configuration
Set environment variables (e.g. in a .env file for docker compose, or in .env.local for npm run dev:api).
Required
| Variable | Description |
|---|---|
HA_URL |
Base URL of your Home Assistant instance, e.g. http://homeassistant.local:8123 |
HA_TOKEN |
Long-lived access token from your HA user profile |
Optional — Pricing
| Variable | Description |
|---|---|
FEED_IN_TARIFF |
Feed-in tariff in €/kWh (used to calculate feed-in earnings) |
GRID_PRICE |
Grid electricity price in €/kWh (used to calculate self-consumption savings) |
Optional — Sign Inversion
Some inverters/meters report power with the opposite sign convention. Set these to true to invert.
| Variable | Default | Description |
|---|---|---|
INVERT_GRID |
false |
Invert grid power sign |
INVERT_BATT |
false |
Invert battery power sign |
Optional — Entity IDs
All entity IDs support a comma-separated list of IDs whose values are summed (useful for multi-inverter setups).
| Variable | Description |
|---|---|
ENTITY_PV_POWER |
Real-time PV generation power (W) |
ENTITY_PV_TODAY |
Energy generated today (kWh) |
ENTITY_PV_MONTH |
Energy generated this month (kWh) |
ENTITY_PV_YEAR |
Energy generated this year (kWh) |
ENTITY_PV_ALLTIME |
Total energy generated all time (kWh) |
ENTITY_GRID |
Grid power — positive = import, negative = export (W) |
ENTITY_BATT_SOC |
Battery state of charge (%) |
ENTITY_BATT_POWER |
Battery power — positive = charging, negative = discharging (W) |
ENTITY_BATT_CHARGE_TODAY |
Energy charged to battery today (kWh) |
ENTITY_BATT_DISCHARGE_TODAY |
Energy discharged from battery today (kWh) |
ENTITY_FEED_IN_TODAY |
Energy fed into the grid today (kWh) |
ENTITY_FEED_IN_TOTAL |
Total energy fed into the grid (kWh) |
ENTITY_GRID_IMPORT_TODAY |
Energy imported from grid today (kWh) |
ENTITY_EV_SOC |
EV state of charge (%) |
ENTITY_EV_POWER |
EV charging power (W) |
ENTITY_EV_ODOMETER |
EV odometer |
ENTITY_EV_CHARGED |
Total energy charged to EV (kWh) |
ENTITY_EV_CHARGING |
Binary sensor — EV currently charging |
ENTITY_EV_CONNECTED |
Binary sensor — EV connected to charger |
Tech Stack
- Frontend: React 18, TypeScript, Vite, Recharts
- Backend: Node.js, Express, TypeScript
- Deployment: Docker (multi-stage build), Docker Compose