Electricity reaches the house from four places at once
My house runs on off-grid and backup power. During the day the main source is the solar panels. The city grid is used when it is available and the night tariff pays off. The generator stays in reserve for periods without sun or grid. A large lithium battery bank ties these sources together across time: it stores energy and releases it to the house later.
The goal is not maximum autonomy on a pretty chart, but electricity when any single source fails. Night takes away the sun, the grid can disappear, the generator needs fuel and maintenance, the battery has a finite charge. Resilience appears only when they pick up the slack for each other.
I assembled and configured the hardware for my own house myself. I dug into more than just the inverter's interface: I got to know how the station is built - the grounding, how the panels behave under different light, the batteries and the real output. So the software layer grew on top of a system whose construction I know physically, not only from the manufacturer's documentation.
Three manufacturers each showed a different part of the picture
The inverter, the battery management system and the consumption meters are made by different companies. The inverter speaks Modbus, the battery speaks Bluetooth, the meters speak over the local network. Each manufacturer's stock app sees only its own device.
From three screens it is impossible to understand what was happening at one and the same moment. The inverter shows the flow through itself, the battery shows its own state, the meter shows the load. For questions like "will the charge last until morning" or "how much did the kilowatt-hour stored from the sun cost," the data has to be lined up on a single timeline.
Vendor clouds and Wi-Fi modules were not a fit for this. They update data rarely, depend on the internet, do not let you work freely with the raw history, and remain the manufacturer's closed loop. So a custom layer for collection, storage and control appeared on top of the equipment.
The battery got its own dedicated translator
The main collector runs on a Raspberry Pi as a Python script. It polls the inverter over Modbus and reads the network meters. The battery's Bluetooth is handled by a separate node on an ESP32 with its own firmware.
The ESP32 sits next to the battery banks, reads their management system, and passes the data to the Raspberry Pi. This made it possible to avoid running a wire across the whole site and to separate the battery channel from the main controller. With several independent banks, the equipment gains a local translator, and a problem with one node does not stop the other sources.
Three protocols turn into a single stream. After that, a new calculation can use the battery charge, the inverter mode and the house consumption all at once, without trying to sync exports from different apps by hand.
A reading lands on disk first and only then on the server
Connectivity and power drop out at exactly the moments that matter most for analyzing an energy system. If a sensor writes only to the cloud, a blackout leaves an empty gap in the history and hides how the equipment behaved at the critical moment.
The Raspberry Pi first saves every value to a local database. When the server is reachable, what has accumulated goes off to QuestDB. If the connection is gone, recording continues on-site, and once it is restored the data is backfilled without duplicates.
Local collection does not depend on the internet. Readings stay on the Raspberry Pi and move into the central database once the connection is restored.
A separate check watches over sensor updates. If a source stops sending new values, the system first reconnects to it. Part of a gap can be reconstructed from neighboring measurements, because the equipment's streams partly overlap. Redundancy here helps detect a fault and close off individual gaps.
This approach delivered 98% collection uptime through connectivity and power outages. The remaining limits are not hidden: if the source itself did not measure a value and there is not enough data nearby, an exact reading will not appear out of nothing.
Second-by-second telemetry lives apart from ordinary data
The stream from all the sensors over the years turns into billions of points. A single battery bank produced more than two million records in just a few months. Storing this history as ordinary application rows and building long charts from it would be expensive and slow.
Telemetry is therefore sent to QuestDB, a database specialized for time series. It builds charts spanning months quickly on affordable hardware. Settings, reference data and other application data are not mixed in with the second-by-second measurements.
Visualization is also moved into a separate layer. The collector is responsible for capture and storage, QuestDB for the history, the dashboard for presentation. Changing a chart does not interfere with polling the equipment, and a new sensor does not require reworking the entire interface.
| Capability | Custom loop | Manufacturer cloud |
|---|---|---|
| Data frequency | Second resolution | Updates every few minutes |
| Working without internet | Local recording continues | Depends on external connectivity |
| Ownership of history | Raw data stays with the owner | The vendor decides access |
| Cross-device correlation | Inverter, battery and meters on one timeline | Each app sees only its own device |
| Control | Commands go back to the inverter | Mostly viewing the stock readings |
At night the battery makes the decision, not the inverter's voltage
Charts on their own do not make a house autonomous. On top of the history runs a night top-up rule. As long as the actual charge is below 70%, the system lets the inverter draw energy from the grid on the cheap tariff. Once the threshold is reached, top-up switches off, and the house uses the sun and the battery again.
That way the bank tops up what it lacks at night and meets the morning with a reserve, while during the day expensive grid energy is not spent without need. The command is sent to the inverter over Modbus - the same channel through which its state is read.
The key detail is in the source of the charge level. The decision uses data from the battery management system and its coulomb counter, not the voltage the inverter sees.
Judging a lithium iron phosphate battery's charge by voltage is like gauging the fuel level by the sound of the engine.
For a LiFePO4 cell, most of the working range looks like an almost flat voltage plateau:
Between 20% and 90% the difference is measured in hundredths of a volt. From such a signal it is hard to tell a half-charged battery from an almost empty one. The inverter knows precisely the flow of energy that passed through it, but the remainder inside the battery is estimated more reliably by the BMS, and this division of roles protects the automation from an error every single night.
The 70% threshold is a setting in itself. The engineering meaning lies in what it is compared against.
The stored energy gained an origin and a price
When all the flows are in one system, you can build your own calculations on top of them. That is how the "energy warehouse" appeared: charge from the sun and charge from the grid are accounted for separately, and the reserve in the battery keeps information about its origin.
This makes it possible to estimate the share of solar energy in the current bank and the honest cost of a kilowatt-hour that passed through the battery buffer. No single device sees such a picture, because it comes together at the junction of generation, charge and consumption.
A new calculation or rule is added as a small script on top of the shared telemetry. There is no need to wait for a feature in the manufacturer's cloud or to change the core of the collection. Your own history becomes material for answering practical questions: is the bank enough until morning, are additional panels needed, and how does the economics of the modes change.
A home system shows more than just a pretty dashboard
The most important decisions turned out to be trusting the BMS coulomb counter instead of the convenient voltage, and local recording instead of sending straight to the cloud. Both are almost invisible in the interface, yet they are exactly what determines whether the automation makes the right decision and whether the history survives a failure.
The house got a continuous, shared picture of sources and load. The mode switches automatically, decisions about expanding the panels and the bank rest on measurements, and the difference in the night tariff becomes an additional saving. At the same time the system stays with the owner and allows new rules without depending on the vendor's roadmap.
This is a personal testbed, but its technical parts apply beyond the home too: a Python collector, heterogeneous protocols, a local buffer, time series and a control feedback loop. On industrial equipment the devices, the scale and the cost of a mistake change, while the questions of trust in the data and behavior without connectivity stay familiar.
The next rule no longer needs a new platform
Night top-up at 70% is one scenario on a ready-made "data, decision, command" chain. On top of it you can add a schedule of inverter modes, email alerts and local signaling through the ESP32.
A small screen or indicator can be connected to the equipment for on-site monitoring. Temperature sensors inside and outside the house and a light sensor would make it possible to look for links with output and consumption. On the accumulated history a savings counter, a generation forecast, an estimate of bank wear by cycles and anomaly detection all become possible.
This is a foundation, not a list of already finished features. The base makes it possible to connect new hardware and rules without replacing the collection, the buffer, QuestDB and the control.
There is also a practical boundary to my work. I built this station for myself, to understand the system from the inside, but I do not offer the installation of power systems as a service. My professional part here is the software data collection, monitoring, calculations and automation on top of existing equipment.
This is our own project, so we show how it's built with nothing held back - down to the architecture and the code.

