⚡ Energy Dashboard
← Back to Dashboard

Guide

How to Build a Home Energy Dashboard

This dashboard gives a real-time view of a home solar, battery, and grid setup — showing live power flows, historical charts, electricity pricing, and running cost/earnings tracking. Here's how something like this can be put together from scratch.

Home Assistant Python / Flask Docker Vanilla JS Caddy Cloudflare

What You'll Need

Architecture Overview

The dashboard is split into three layers: a data source, a secure proxy, and a frontend.

1

Home Assistant — the data hub

Your inverter, battery, and smart meter all send data to Home Assistant via their respective integrations. HA stores these as sensor entities and exposes them through a local REST API. This is the single source of truth.

2

Python Flask proxy — read-only security layer

A small Python script sits between the dashboard and Home Assistant. It only exposes a whitelisted set of sensors (no smart home controls), polls them every 5 seconds, caches the results, and completely blocks any write operations. Your HA API token never leaves your local network.

3

HTML/JS dashboard — the frontend

A single HTML file with vanilla JavaScript fetches data from the proxy and renders it. No frameworks, no build step. Chart.js handles the 12-hour history graphs. The animated power flow diagram is built with SVG and CSS animations.

4

Docker + Caddy — deployment & HTTPS

The Flask app and a Caddy reverse proxy run together in Docker Compose. Caddy automatically handles HTTPS certificates and adds security headers including HSTS, CSP, and X-Frame-Options. Secrets like API tokens are kept in an environment file that is never committed to version control.

5

Cloudflare Tunnel — secure public access

Instead of opening ports in your router, a Cloudflare Tunnel container makes an outbound-only connection to Cloudflare's network. Your home IP is never exposed, there are no inbound ports to attack, and you get DDoS protection and global CDN performance for free. Traffic flows: visitor → Cloudflare → tunnel → Caddy → Flask → Home Assistant.

Setting Up Home Assistant

Once Home Assistant is running on your local network, install the integrations for your specific hardware from the HA integration store. Popular ones:

After setup, each piece of hardware exposes sensor entities in HA (e.g. solar power in watts, battery state of charge, grid import/export). Note down the entity IDs — you'll need them for the proxy whitelist.

Create a long-lived access token in your HA profile settings. This is what the proxy uses to authenticate with the HA API. Keep it private and never expose it in frontend code.

The Read-Only Proxy

The proxy is the most important security piece. Here's the core concept in pseudocode:

Flask is a good choice for this — it's lightweight, easy to read, and straightforward to containerise. The whole proxy is around 100 lines of Python.

The Dashboard Frontend

The dashboard is a single HTML file — no build tools, no npm, no frameworks. Everything runs in the browser.

Security Considerations

🔒

Never expose HA directly

Your Home Assistant instance should stay on your local network only. The proxy is the only thing that talks to it.

📋

Whitelist entities

Only expose the specific sensors you need. Don't create a catch-all proxy — your locks, cameras, and alarms should be unreachable.

🚫

Block writes at the proxy

Reject all HTTP methods except GET and OPTIONS. Even if someone finds the endpoint, they can't control anything.

🛡️

HTTPS + security headers

Caddy handles TLS automatically. HSTS, Content Security Policy, X-Frame-Options DENY, and X-Content-Type-Options headers are all set to harden the public-facing site.

🌐

Cloudflare Tunnel — no open ports

Running a Cloudflare Tunnel means your router has zero inbound ports open. Your home IP is never visible to the public internet, removing a large attack surface entirely.

🔑

Secrets in environment files

API tokens and URLs are stored in a .env file that is listed in .gitignore and never committed to version control. Rotate tokens periodically and never hardcode them in source files.

Deployment

A docker-compose.yaml with three services is all you need:

For a public URL, register a domain and point its nameservers to Cloudflare. In the Cloudflare Zero Trust dashboard, create a tunnel and add a public hostname route pointing to your local Caddy port. Cloudflare handles all TLS — no Let's Encrypt setup needed on your end.

Built With Claude

This dashboard was built with help from Claude by Anthropic

The dashboard code — including the animated SVG power flow diagram, the Flask proxy, the Docker configuration, and this guide — was developed collaboratively with Claude, Anthropic's AI assistant.

Claude helped design the architecture, write and iterate on the Python proxy code, debug edge cases in the JavaScript, and structure the frontend layout. The approach taken here — a read-only proxy layer, a whitelisted entity set, cookie-based visit tracking, and a single-file no-build frontend — all came out of back-and-forth conversation with Claude.

If you want to build something similar, Claude is a great tool for talking through the architecture, generating boilerplate, and working through problems as they come up. You can try it at claude.ai.

Tip for using Claude to build dashboards

Start by describing your hardware setup and what data you want to see. Then ask Claude to help you design the proxy first — getting the security layer right before building the frontend means you won't accidentally expose anything you shouldn't.