Solar and battery control that follows the tariff, not the vendor's app
Homes with solar, batteries, heat pumps and smart tariffs were running on the manufacturers' fixed schedules. We moved control onto Home Assistant, locally, and taught it to follow price bands and the seasons.
At a glance
- 3
residential installs
- 127
days reconciled against the utility meter
- 14
months of meter history backfilled on one site
- 21
Matter devices carried across a host rebuild
The challenge
Vendor apps give you a fixed charge window and not much else. Smart tariffs don't work like that: the price changes by band, dispatch windows appear at short notice, and what makes sense in January is wrong by June.
There was a trust problem as well. If the energy dashboard doesn't agree with the meter, nobody believes the automation that's driving off it.
Architecture
Swipe to explore the diagram
Tariff signals and the season drive the decisions, the utility's own data keeps the sensors honest, and the reasoning is always visible.
What we built
Control
- Battery control over Modbus with three seasons, state-of-charge latches, dispatch rules and a reserve clamp
- A master switch and visible decision sensors, so anyone can see why the battery is doing what it's doing
- Winter arbitrage between export and the night rate, and a hot-water catch-up that ran as a dry run first
- A glitch filter that strips state-of-charge spikes before they can drive a decision
Data you can trust
- Meter-grade sensors reconciled against the utility's data, within 0.45% over 127 days on one install
- History backfilled so each dashboard is one continuous series, including 14 months of import and gas history on one site
- Phantom solar generation found and removed from the history
Running it
- Three hardware shapes: virtualised on Proxmox with USB radio passthrough, a dedicated appliance for customer sites, and a reference install we pattern from
- Remote access through a Cloudflare tunnel, with LAN SSH opened per session only
- Fixes contributed back upstream to the open-source integrations we depend on
Engineering decisions
Local control beats cloud schedules
Home Assistant owns the inverter and battery schedule directly, and the vendor's time-of-use profiles were retired.
Write down what never gets touched
Certain inverter modes, the export limit and the rate plan are off-limits to automation. Some settings belong to the installer and the network operator.
A shadow day before every cutover
A new controller runs read-only against live data for a day before it takes over, with a numbered checklist and a rollback copy kept for a week. Two writers on one inverter is never allowed.
The box is the source of truth
Config syncs from the live system into git, never the other way, so a stale file in a repo can't overwrite something that works.
Outcome
Batteries charge and discharge on season and tariff under local control across three installs, and the dashboards agree with the utility. One install moved from bare metal to a VM and then to a second host without missing a nightly battery switch.