Repository navigation
Home
A standalone background service that manages a SolaX X3-HYB-G4 PRO hybrid inverter and an X1/X3-HAC EV charger entirely over your local network — no cloud account, no vendor API, no telemetry leaving the LAN.
| Runtime | .NET 10 Worker Service |
| Protocol | Modbus TCP, local only |
| Platforms |
linux/amd64, linux/arm64, Windows Nano Server ltsc2022
|
| Images | ghcr.io/mpospisil/solax-controller |
The controller polls your inverter and charger directly over Modbus TCP on the local network, then applies decision logic to route surplus household energy into the car and the home battery. Because nothing round-trips through a vendor cloud, control keeps working during an internet outage and the decision cycle runs at LAN speed rather than cloud latency.
The simplest way to run it is to clone the repository, set your two device addresses and
dotnet run — that alone gives you live telemetry and the controller's own web UI, with no broker,
no Home Assistant and no Docker involved. See Get started.
For unattended operation it runs as a long-lived process; the reference installation is Docker containers on a Raspberry Pi — the controller (with its own web UI) alone on a 1 GB board, or alongside Home Assistant and an MQTT broker where there is 2 GB or more. Both control surfaces are first-class; run either, both, or neither. See Deployment for the two workflows and which your hardware fits.
- Real-time polling of PV generation, battery state of charge, grid import/export and charger status.
- Surplus-aware EV charging — ramps charge current up and down to track available household surplus.
- Battery discharge hold — stops the home battery serving house load, so the car charges from PV and grid while the battery still absorbs surplus.
-
Fast charge without the battery — a "I leave in an hour" mode that pulls maximum current from PV and grid, holds the battery out of it, and returns to
Offby itself when the car is full. You can also say how much — an amount in kWh, or a battery target like 80% — and it stops there instead. And when you leave: given a departure it waits, starting as late as it can and still finish, so a car charged above 80% sits at that state of charge for minutes rather than all night. It still charges flat out; only the start moves. -
Targeted charging — "15 kWh in the car by 17:00, and use as little grid as you can". The car is paced across the whole window at the rate the deadline needs, taking every watt of sun above that rate for free, because the charger can only use the sun that shines while it runs. On a forecast the sun can cover, a target set at 02:00 buys nothing overnight and starts when the surplus first clears the charger's minimum. It returns itself to
Offonce the energy is delivered. - Solar forecasting via a cached Solcast forecast, logged against actual generation.
- The weather each session ran in — optional, via OpenWeatherMap: the conditions at each end of a session and the day's daylight window, so a finished session can be read against the day it happened on rather than only against the forecast.
-
Self-hosted web UI — a dashboard served by the controller itself on
:8090, on by default and needing no configuration: live telemetry, every control, charging-session history, the energy history, the solar forecast for today and tomorrow, and the forecast plan, no Home Assistant or broker required. A password is an optional extra, not a prerequisite. See Deployment. - Home Assistant integration over MQTT discovery, with runtime mode control and full telemetry.
- Charging session history — every controlled session recorded to local SQLite: when it ran, which strategy drove it, and how much energy came from solar, grid and battery.
- A graceful stop from either surface — stopping the service from the web UI or Home Assistant releases the charger, closes the open session and flushes the store, none of which happens if the process is killed. It then stays stopped until you start it again, while a reboot or power cut still brings it straight back. See Deployment.
| Device | Model | Interface |
|---|---|---|
| Hybrid inverter | SolaX X3-HYB-G4 PRO | Modbus TCP |
| EV charger | SolaX X1/X3-HAC | Modbus TCP |
| Home battery | SolaX T-BAT H 2.5 + BMS | via the inverter — no direct connection |
Warning
Read before enabling anything. Two features write to your hardware: ChargeControl (the
charger) and BatteryHold (the inverter). Both ship disabled, and BatteryHold additionally
defaults to dry-run. Register addresses vary between SolaX generations and firmware revisions —
verify them against your own device before turning either on. A wrong address writes to a real
inverter.
Note
A first run is safe by default. Starting the controller writes nothing to your hardware. Charge
control always boots in mode Off — whatever the config says — and takes control only when you
pick a mode, in the web UI or in Home Assistant. No mode persists across a restart, so after a
crash, power cut or redeploy the charger is left exactly as its owner set it.
Start here — clone, configure, build, run. That is the whole first pass; nothing in the Advanced table below is needed for it.
| Page | What's on it |
|---|---|
| Get started | Clone the repository, point it at your devices, build and run it |
| Configuration | Every setting, in both its file and environment form |
| Solcast | Optional solar forecasting — when to bother, and how to get a key |
| Weather | Optional weather on each recorded session — what it answers, and how to get a key |
| Troubleshooting | Symptom → cause → fix |
Advanced — for unattended operation, or a second control surface.
| Page | What's on it |
|---|---|
| Docker | Image tags, and running the controller as a container |
| Platforms | Linux x64, Raspberry Pi and Windows Nano Server — and what differs |
| Deployment | Controller, Home Assistant and MQTT broker via Compose |
| MQTT | How the controller and Home Assistant actually talk |
Runs entirely on your LAN · Full configuration reference in README.md · Pi preparation and backup in deploy/README.md
- Home
- Get started — build & run
- Configuration
- Solcast
- Weather
- Troubleshooting
Advanced
- Docker
- Platforms
- Deployment — Pi, two workflows
- MQTT
Images: ghcr.io/mpospisil/solax-controller