Two battery systems, one energy plan — built through LLM conversations
How I used LLM conversations to build a working home energy controller, connect FoxESS and EcoFlow systems, and learn to coordinate solar production, battery storage and wholesale electricity prices.
- Starting expertise
- Familiar with inverter control; some battery optimisation knowledge; new to electricity markets.
- Delivery
- Development record: 4–22 September 2026; ongoing
- What the AI did
- All custom code generated through LLM chats, plus research, design, testing, debugging and Raspberry Pi configuration.
- What a human verified
- Requirements, domain judgement, review of operating behaviour and feedback from the physical installation.
- Controls
- Bounded inverter commands, battery reserves, fault handling, recorded decisions and device read-back.
- Outcome
- Owner-reported $4.16 credit against usage costs over the first 19 days with Amber, consuming around 40–45 kWh/day.
I built a controller for my home solar installation through conversations with LLMs. I did not edit any of the custom code by hand. The work covered the application, integration between two power-system vendors, testing and debugging, and a Raspberry Pi display with its disk preparation and Linux configuration.
The result is a running system that coordinates a FoxESS house battery and an EcoFlow Delta Pro 3 around solar production and wholesale electricity prices. In my first 19 days with Amber, I recorded a $4.16 credit against energy usage costs, while consuming roughly 40–45 kWh a day.
From manual adjustments to a shared plan
My installation has approximately 27 kWh of FoxESS battery storage and 8.2 kWh in the EcoFlow Delta Pro 3. Previously, I coordinated them through manual adjustments.
The timing matters. Charging from the grid too early can fill space that would otherwise absorb solar production. Holding too little energy can mean buying electricity at a premium later. Selling stored energy at an attractive wholesale price creates another question: will replacing it cost more than the sale earns?
Two independently managed systems can work against each other. I needed a common view of production, demand, storage and prices, then a way to translate that plan into each vendor’s controls.
Using AI to work into unfamiliar territory
I already understood inverter control and had some familiarity with battery optimisation. Electricity markets were new to me. Relating weather and solar-radiation forecasts to the output of my own installation was also a substantial learning exercise.
LLM conversations supported that learning as well as the implementation. I used Superpowers to structure designs, implementation plans and verification, and long-running tasks to carry work forward. My role was to explain the problem, make engineering decisions and feed observations from the operating system back into the work.
The development record reviewed for this case study covers 619 commits from 4–22 September, supported by 12 design specs and 26 plans or briefs. Those documents gave tasks a defined scope and made decisions reviewable as the system evolved. The dates describe the development record, rather than a measured delivery effort.
The deployed controller runs implemented planning and control algorithms. LLMs helped create those algorithms and their surrounding system; live inverter commands come from the software.
Architecture: planning above a local control loop
The architecture separates decisions about the next few hours from the fast loop that controls the inverter. Four services run in Docker: the controller, a local inverter agent, the Mosquitto message broker and PostgreSQL with TimescaleDB.
| Layer | Responsibility |
|---|---|
| Controller — Bun and TypeScript | Combines prices, solar forecasts, demand and battery state into an energy plan, then coordinates its execution across both vendors. |
| Inverter agent — Node.js and Modbus | Reads the FoxESS every second and executes timed policies locally, with charge limits, battery reserves and watchdog handling. |
| MQTT — Mosquitto | Carries policies to the agent and returns telemetry, acknowledgements and operating status. |
| Storage and views | PostgreSQL/TimescaleDB retains measurements and decisions. The React dashboard and Raspberry Pi power-bus screen make operation visible. |
The EcoFlow has its own cloud integration, combining MQTT telemetry with authenticated HTTP commands and read-back checks. FoxESS cloud settings also remain part of the integration. Separating these vendor interfaces lets the planner describe a shared operating intention while each execution path handles the device’s particular behaviour.
Making two vendors behave as one system
One integration detail illustrates why this needed custom work. The EcoFlow charges through the household circuit. Its charging demand therefore appears in the house measurements. If the planner also treats that charging as a separate future load, it counts the same demand twice. The household demand profile was corrected to account for that relationship.
Later work kept the EcoFlow running its server circuit from its own battery when the roof was not producing. That helps prevent the house battery from also carrying the server load through the EcoFlow’s input. The integration changes how energy moves between the systems.
Reverse-engineering undocumented controls and registers
Part of the work was establishing how undocumented or incompletely understood controls behaved on the actual equipment. LLMs helped me investigate the interfaces, interpret observations and turn discoveries into code. The evidence came from register readings, device responses and measured power flows.
The meaning of the power command mattered. On the FoxESS KH10, register 44002 was initially treated as a battery-power command. Operation revealed that it controls the inverter’s net AC power. A recorded command of −2,163 W drew approximately 2,166 W from AC while solar was also charging the battery. Subtracting solar production again in the control calculation had caused unwanted daytime grid imports. Correcting that interpretation changed the control law.
The order of commands mattered too. Hardware checks showed that enabling remote control through register 44000 reset the watchdog register, 44001, to its 60-second default. The implementation therefore refreshes the intended timeout after enabling control. A register’s apparent purpose did not explain this interaction; reading it back exposed the behaviour.
EcoFlow settings had coupled effects. Enabling the DP3’s backup reserve also switched it into self-powered mode. The integration had to account for that side effect, as well as delayed cloud readings, when coordinating charging and server supply. An accepted API request alone was insufficient evidence that the intended state had been reached.
Unresolved register values remain captured as raw data rather than receiving guessed meanings. That distinction became part of the engineering approach: use AI to develop and test an interpretation, then retain only what the device evidence supports.
Learning what the forecasts actually mean
A weather forecast needs interpretation before it becomes a useful charging plan. The system has to estimate production for this installation, compare it with measured output and respond when the day unfolds differently.
The development history contains several useful corrections. Historical calibration needed to pair each day’s actual production with that day’s own forecast. Using the wrong forecast lookup undermined the comparison. Intraday rescaling then used production observed so far to adjust expectations as conditions changed.
Another correction concerned time: radiation periods were being interpreted an hour out. Aligning the periods with the energy they represented changed both the graph and the planning inputs. A plausible-looking chart had not been enough to establish that the data was aligned correctly.
The dashboard exposes the remaining errors, separating predictions of a whole day’s energy from predictions for individual hours. Both views matter when a charging decision depends on when solar will arrive.
Making operation visible
Because the software controls a physical installation, its commands need boundaries and its decisions need to be traceable. The implementation includes battery reserves, fault handling, recorded control decisions and checks that devices accepted requested changes. The export setting defaults to 9,999 W and is bounded between 500 and 9,999 W.
A dedicated screen for the live system
A small Raspberry Pi touchscreen puts the power-bus view on a dedicated display. I can see solar production, grid exchange, household demand and both battery systems together without opening a laptop. The separate server load also makes it easier to see where the EcoFlow’s energy is going.
The work went beyond drawing the dashboard. I used LLMs to prepare the Pi’s disk and configure Linux, as well as build the display. The companion implementation waits for the dashboard to become available, opens Chromium in kiosk mode and includes browser restart and endpoint-recovery handling.
That gives the software a practical place in the installation: an immediate view of what the system is doing, with the detailed history and decision logs available when I need to investigate further. It is another example of using AI across the whole delivery task — application code, operating-system configuration and the device used day to day.
An early result, and a purpose beyond the electricity bill
Over my first 19 days with Amber, the wholesale electricity provider, I imported 100 kWh from the grid while consuming around 40–45 kWh per day overall. Alongside solar generation and storage, I used favourable wholesale export prices to earn revenue from energy sold back to the grid. My reported usage-cost balance for the period was a $4.16 credit.
This is an early usage-cost result. It does not establish an all-inclusive electricity bill or a return on equipment costs. I have not measured a like-for-like saving against my previous manual operation.
The next purpose is to support a feature-complete OpenStack homelab on older Dell PowerEdge R410 and R620 servers. Making their power consumption affordable would let me keep useful hardware working for longer and avoid sending it to e-waste. That lab remains planned.
For my work with AI, this project provides a concrete example of delivery across software, vendor interfaces and Linux configuration while learning a new domain. The useful discipline was to turn observations into requirements, give the LLMs structured work, and check the resulting behaviour against the installation.
Explore eight more views of the running system
Select any image to inspect the original capture.
