Real-time home energy monitoring dashboard built around eGauge circuit monitors and Tesla Powerwall via Home Assistant. Tracks per-circuit power consumption, calculates costs by TOU (Time-of-Use) period, and provides full solar/battery/grid source attribution.
Works great without solar too — set solar.enabled: false for a grid-only cost tracking dashboard.
- Live Power Flow — WebSocket-powered 5-second updates showing per-circuit watts
- Energy Flow Sankey — Visual breakdown of where solar/grid/battery energy goes (Home / EV / Grid Export) over 1d / 7d / 30d windows
- Multi-Battery Panel — Combined view of Powerwall + every connected EV (SOC, kWh stored, capacity)
- Charge Provenance Bars — Per-battery solar vs grid mix (e.g., "Powerwall: 56% solar / 44% grid charged this week"; "Car charging: 10% solar / 90% grid"). EV provenance includes Powerwall's solar share, attributed through.
- TOU Cost Tracking — Automatic rate calculation based on your utility's peak/off-peak schedule
- Hourly & Historical Charts — Stacked bar charts by TOU period with click-to-drilldown
- Circuit Breakdown — Sortable table with today's kWh and cost per circuit
- Solar + Battery Tracking — Live solar generation, battery charge/discharge, grid import/export via Home Assistant + Tesla Powerwall
- Battery Economics — Cost per kWh, charge source breakdown (solar vs grid), round-trip efficiency, savings vs peak rates
- Per-Hour Cap Optimizer — Recommends tomorrow's grid-charge cap by simulating 24h hour-by-hour. Models same-day-of-week load patterns (weekday vs weekend), EV-excluded base load, Tesla SOC taper above 90%, and measured battery efficiency. Picks the lowest-cost cap (or pin to backup_reserve via
experiment_no_grid_chargeconfig flag to baseline pure self-consumption). - Optimization Opportunities — Identifies circuits with high peak usage and potential savings
- Weekly Email Reports — Automated Monday morning cost summaries
git clone https://github.com/epheterson/energy-dashboard
cd energy-dashboard
cp config.example.yml config.yml # Edit rates for your utility
cp .env.example .env # Add your eGauge credentials
docker compose up -d # Dashboard at http://localhost:8400Defines your utility rates, TOU schedule, and optional solar integration:
| Section | Purpose |
|---|---|
rates |
$/kWh by season and TOU period |
tou_periods |
Which hours are peak, part-peak, off-peak |
solar |
Home Assistant integration (set enabled: false if no solar) |
alerts |
Threshold for high peak usage warnings |
Contains credentials (never committed to git):
| Variable | Required | Description |
|---|---|---|
EGAUGE_URL |
Yes | Your eGauge device URL |
EGAUGE_USER |
Yes | eGauge username |
EGAUGE_PASSWORD |
Yes | eGauge password |
HA_URL |
If solar | Home Assistant URL |
HA_TOKEN |
If solar | HA long-lived access token |
EMAIL_ENABLED |
No | Set true for weekly email reports |
SMTP_* |
If email | SMTP server settings |
Designed around the Tesla Powerwall + Home Assistant integration. When solar.enabled: true in config.yml, the dashboard pulls real-time data from HA sensors:
- Live power flow — Solar generation, battery charge/discharge rate, grid import/export
- Source attribution — Per-hour and per-circuit breakdown of solar vs battery vs grid
- Battery economics — Cost per kWh stored, charge source (solar vs grid), round-trip efficiency
- Savings tracking — Dollar savings from solar + battery vs full grid rates, self-sufficiency %
- Weekly reports — Email summaries include solar/battery data
When solar.enabled: false, all solar/battery UI is cleanly hidden — you get a pure grid cost tracking dashboard with no Home Assistant dependency.
- Backend: FastAPI (Python) with async eGauge polling + WebSocket broadcast
- Frontend: Single-page vanilla HTML/JS with Chart.js
- Data: SQLite for historical storage, in-memory cache for live data
- Container: Docker with mounted config and persistent data volume
MIT
- Docker + Docker Compose
- eGauge meter on your network
- (Optional) Home Assistant + Tesla Fleet integration — required for solar/Powerwall features
git clone https://github.com/epheterson/energy-dashboard
cd energy-dashboard
cp .env.example .env
cp config.example.yml config.ymlMinimum:
EGAUGE_URL=https://your-egauge.egaug.es
EGAUGE_USER=owner
EGAUGE_PASSWORD=your_password
HA_URL=http://homeassistant.local:8123 # optional (solar)
HA_TOKEN=long_lived_token # optional (solar)
CONTACT_EMAIL=you@example.com # for Open-Meteo User-Agent- Rates: replace example PG&E values with your utility plan
- TOU periods: hours match your utility schedule
- Solar: set
enabled: true, map your HA entity IDs (see below for discovery) - EV: set
enabled: true, fill in vehicle entity IDs + yourgas_baseline_mpg - Billing: set
nem_version(2 or 3), CCA if applicable, lat/lon, solar capacity
The HA mount line points at a specific path — change it to YOUR HA .storage directory:
- /path/to/your/homeassistant/.storage/core.config_entries:/app/ha_config_entries.json:roComment it out entirely if you do not have HA Tesla Fleet integration.
docker compose up -d
./validate.sh # tier-by-tier health checkYou should see all green. Any red ✗ tells you exactly which tier is broken.
curl http://localhost:8400/api/battery/recommended-capThis generates the first prediction. After that, the in-process daily scheduler (23:50 PT) backfills yesterday's actuals nightly. Auto-tune calibrates over ~30 days.
Open HA → Developer Tools → States → search keywords:
solar→ solar power, generationgrid→ grid import/exportbatteryorpowerwall→ battery state, SOCteslaor your car name → vehicle entities
Copy the entity_id column (looks like sensor.solar_power_plant_solar_power) and paste into the matching field in config.yml. Tesla Fleet integration auto-creates the standard names.
If you have Enphase, SolarEdge, LG Chem, etc. — just use whatever entity IDs YOUR HA exposes. The dashboard is brand-agnostic.
HA → Settings → Devices & Services → your Tesla Fleet integration → click any Powerwall device → copy the integer "Energy Site ID". Paste into config.yml under billing.tesla.site_id. Token is auto-pulled from HA — no manual refresh ever.
./validate.sh and /api/health give tier-by-tier status:
✓ All tiers healthy
✓ dashboard ok
✓ egauge ok
✓ home_assistant ok
✓ tesla ok
✓ forecast ok (14 days of history)
If something is red, check container logs:
docker compose logs -f --tail=50The dashboard's calculated total_bill matches actual PG&E bills within ~25% for typical months. Validated: actual $172.64 vs calculated ~$128 (-26%). Remaining gap = PG&E line items the simplified model doesn't include yet:
- PCIA (Power Charge Indifference Adjustment) — 5–15%, varies monthly
- Franchise Fees — 0.5–1%
- Climate Credit — twice/year credit (~$50-200)
- Taxes
For "is my dashboard tracking energy correctly?" → trust the kWh numbers (validated 100% accurate vs Tesla and eGauge directly). For "will my next PG&E bill be exactly $X?" → directional indicator only, not bill-perfect.
| Symptom | Likely cause |
|---|---|
| Tesla data stale (>6h old) | HA's Tesla Fleet integration broke — re-auth in HA Settings → Integrations |
/api/battery/prediction-history returns {"history": []} |
hit /api/battery/recommended-cap once to seed |
validate.sh shows egauge unreachable |
check EGAUGE_URL hostname + credentials in .env |
| Solar shows 0 always | HA token expired or solar.ha_entities IDs wrong — check HA Developer Tools |
| Email never arrives | use SMTP App Password not regular; enable 2FA on Gmail |
Lightweight smoke tests cover config (TOU classification, rate lookups), solar load prediction, and endpoint registration:
# In the running container:
docker exec energy-dashboard sh -c 'pip install pytest && pytest -v'
# Or locally:
pip install -r requirements-dashboard.txt -r requirements-dev.txt
pytestThese are smoke tests, not full integration coverage — they run without needing eGauge or Home Assistant access.
Source is COPY'd into the Docker image at build time:
docker compose up -d --buildA simple docker restart does NOT pick up code changes.
The dashboard recommends a daily grid-charge cap based on tomorrows solar forecast — but doesnt push it to your Powerwall directly. To close the loop, drop in the HA package included with this repo:
→ examples/home-assistant/grid_charge_cap.yaml — REST sensor + automation that monitors Powerwall SOC and turns off grid-charging when it crosses the cap.
See examples/home-assistant/README.md for the 5-step install (copy file → edit 3 entity IDs → restart HA → verify).
Without HA, the recommended cap is still useful as advisory — set it manually in the Tesla app each morning.