The battery said it was full. Half of it had never worked
For two years my home battery's screen looked normal while one of its two modules did almost nothing. Neither the vendor's app nor its support noticed. A set of clamps and my own database did, then kept the history when the vendor lost it, and now a small ESPHome board runs the battery locally.
Read aloud by an AI copy of my voice.
My home battery is two modules. The first went in at the end of 2021 and the second in August 2022, which should have taken it to about 9.2 kWh usable, going by the spec sheet. For the next two years the screen on the main unit looked like any healthy battery's: charging through the day, sometimes reading 100%, draining in the evening.
It was storing about half of what it should. I didn't find that out from the battery, the vendor's app or the company that sold it to me. I found it the week I started measuring the battery myself.
This is what happened, what my own data caught that the vendor's didn't, and how the battery now runs from Home Assistant without the vendor's cloud.
Day one was the clue
The day the second module went in, the whole battery stopped at 51%. Support told me the new module was on a different firmware version from the first, and an update was pushed overnight. After a guided restart it charged past 51%, and I took that to mean it was fixed.
Looking back, the signs were there. It rarely charged above about 80% and never went below 19%. I put that down to the battery management protecting the cells. The vendor's app was hard to read, so I mostly didn't.
What a set of clamps showed
In September 2024 I had an electrician fit current clamps on the battery, solar and grid circuits, feeding my own monitoring at home. The clamp on the battery circuit measures energy going in and coming out, whatever the battery itself claims. In October 2024 about 4.7 kWh a day went in. Two modules should hold about 9.2.
| Energy into the battery | |
|---|---|
| What two modules should hold | about 9.2 kWh usable |
| Average day, October 2024, from my clamps | about 4.7 kWh |
| Best day, from my clamps | just over 5 kWh |
| Best day ever in the vendor's own history | about 6.5 kWh, December 2022 |
Once I knew what to look for, the vendor's own figures said the same thing. They had always said it. Nobody on their side had noticed.
The part that stays with me: around the start of 2024, someone from the company that sold me the second module rang to ask if I'd like a third. They could see from the monitoring that I was exporting a lot of solar. The same monitoring showed half the battery doing nothing. The call was about selling me more of it.
The fix, and the data that went with it
A remote update in October 2024 was supposed to bring it to full capacity within two weeks. My clamps showed no change. In December the main unit was replaced under warranty, and after that the battery worked at full capacity: on a good day in 2025 it took 9 kWh or more.
The replacement had a cost the warranty didn't cover. When the new unit came online, the vendor's app showed only the new battery. Every day of history from the old one was gone, and the solar system showed as 3.0 kW instead of 6.6. The electricity retailer's app, which also read the battery, stopped showing it for weeks.
My own records aren't tied to a serial number. They measure the circuits, so a new battery is just more readings on the same line.
86 days of nothing
In late November 2025 the supply flickered off and on three times, then went out for over an hour. When it came back, the battery showed an error and wouldn't start. A technician came, called it a firmware fault, and switched the unit off. A second replacement went in on 17 February 2026.
My clamps had the outage to the day: about 7.4 kWh a day going in through October, then next to nothing for all of December and January.
| Month | Average energy into the battery a day |
|---|---|
| October 2025 | 7.4 kWh |
| November 2025 | 5.1 kWh (failed on the 22nd) |
| December 2025 | 0.01 kWh |
| January 2026 | 0.00 kWh |
| March 2026 | 6.6 kWh |
When I claimed for the outage, the figure came from my records: about $5.67 a day in lost savings over 86 days, worked out from what my own figures showed the battery saving before it failed. Without my own data, the only numbers in that conversation would have been theirs.
Then it happened again. The new unit didn't appear in the vendor's portal, and when I asked for the old unit's history to be carried over, the answer in writing was that it couldn't be done: the new battery was a separate data set. A later visit got most of it showing again. But whether I have my own battery's history is a decision someone else makes, on their systems, under their terms. If the company changes its app, starts charging for the portal or stops trading, the history goes with it.
My copy of the outage, and of every day since, is in a database in my house.
Taking control back
Measuring the battery was step one. Running it was step two.
In July this year the household moved to a plan that is free from 12:00 to 15:00 for the first 24 kWh a day. The obvious move is to fill the battery from the grid in that window and run the house on it through the evening peak. The battery's own time-of-use setting can't do it well: it's a fixed schedule set from the phone app, with no way for anything else in the house to start, stop or check a charge.
The battery's communications dongle talks to two things: the vendor's cloud over 4G, and the vendor's phone app over Bluetooth. It has no Wi-Fi and no network port. So I took the app apart and recorded its Bluetooth traffic while I changed modes in it, until I knew which messages set the working mode and which set a charge window.
Now a small ESP32 board running ESPHome sits within Bluetooth range of the battery and gives Home Assistant three controls: charge from the grid now, for how many hours, at what share of the battery's rating. The board sends the same settings the app would: a charge window from now until the hours run out, then back to ordinary self-consumption. It reads the mode back to check the battery took it, tries up to three times, and reports a failure instead of assuming success. It changes nothing the vendor's app can't.
At 12:00 Home Assistant starts a four-hour charge at 90% power, which runs through the free window and the one cheap hour after it. On every one of the 87 days from 1 August to 25 October, the battery took at least 9.1 kWh:
| Month | Average energy into the battery a day |
|---|---|
| August 2026 | 9.8 kWh |
| September 2026 | 9.8 kWh |
| October 2026, 1st to 25th | 10.0 kWh |
None of that touches the vendor's cloud. If the 4G dongle dropped off the network tomorrow, the battery would still fill at noon.
Local means the failures are yours too
Running it myself didn't make it simpler. It moved the faults to where I can see them.
Twice the ESP board crashed about a minute after a burst of writes to the battery. The second time, a minute after starting the day's charge, it rebooted, replayed its last saved state of "off", and the battery went back to self-consumption two minutes into the free window. No free charge that day, and the noon air-con ran the battery down instead. I only found out because I was looking.
So there are now two guards. The board no longer replays anything when it boots, and it saves the end of a charge window to flash within five seconds instead of a minute. And Home Assistant checks every five minutes during the window, re-arms the charge if the switch is off, and sends a notification to my phone:
# Trimmed. Runs every 5 minutes from 12:03 to 15:31.
alias: Battery - charge watchdog
triggers:
- trigger: time_pattern
minutes: "/5"
conditions:
- condition: time
after: "12:03:00"
before: "15:31:00"
- condition: state
entity_id: switch.battery_charge_from_grid_now
state: "off" # unavailable is not off: skip a reboot
actions:
- action: number.set_value # only the time left until 16:00,
target: { entity_id: number.battery_charge_hours }
data: # so a late start can't run into peak
value: "{{ [((16 - now().hour - now().minute / 60) * 2) | round / 2, 0.5] | max }}"
- action: switch.turn_on
target: { entity_id: switch.battery_charge_from_grid_now }
- action: notify.mobile_app_phone # last, so a failed notify can't
data: # stop the charge
message: "Battery charge re-armed by the watchdog"
mode: singleThe vendor's system has the same kinds of faults. The difference is that here they show up on a dashboard and in a log within minutes, not two years later in a phone call trying to sell me another battery.
What I'd tell anyone with a battery
- Have an electrician clamp the battery circuit, along with solar and grid. A clamp measures what goes in and out, whatever the battery's screen says. It is the cheapest part of all this and the part that caught the fault.
- Compare a month against the spec sheet. If the battery never takes close to its usable capacity on a sunny day with spare solar, ask why, in writing.
- Keep your own history, in a database you control, starting now. The vendor's copy is tied to a serial number and their terms.
- Don't take "a firmware update will fix it" on trust. Measure before and after.
- Only then think about control. Watching the numbers is useful on its own. Controlling the battery means owning the failures, so build the watchdog before the clever parts.
If your battery's app is the only place its numbers live, I can set up the monitoring side for you as a small job, quoted before I start, at $90 an hour. The clamps themselves are fitted by a licensed electrician. More of how the house uses the free window is on the household stack page, and the first conversation is free: get in touch.