Custom Home Assistant integration that controls a Marstek Venus E home battery for self-consumption, peak consumption compensation with optional pre-peak grid charging, and full manual control. It's meant as a more robust replacement for the default Marstek control, which can be spotty, also offering additional features like preserving some energy to avoid consumption peaks (e.g. during the evening, where under normal control the battery could already be empty).
This integration leverages the marstek_modbus integration by ViperRNMC, which takes care of the Modbus communication to the Marstek battery.
Currently, this integration is just a fancy scheduler. Everything it does can also be done using automations and template sensors, or NodeRED. However if you're looking for an easy solution and are using HACS, this integration is perhaps for you. Click, install, it works.
In Flanders, many households pay a capacity tariff: your bill depends not only on energy (kWh) but on the highest 15-minute average power each month, then averaged over 12 months. A single short spike can cost on the order of €50 per kW per year — so shaving peaks saves real money.
The stock Marstek control aims at self-consumption but does not know your capacity-tariff budget or anticipates daily peaks (evening or morning). This integration adds capacity-tariff awareness and optional boost charging (grid pre-charge before your peak window) or reserve (hold SoC from solar only).
You can use it outside Flanders too: turn off the capacity-tariff guard and run plain self-consumption or timed boost/reserve behaviour in any region.
- Home Assistant
2025.9or later - HACS installed (for HACS install path)
- The ViperRNMC
marstek_modbusintegration installed and connected to your Marstek Venus E - A grid power measurement (see A note on grid-power update rates below)
Recommended:
- A P1 dongle or other grid power sensor with an update rate of at least 1 HZ. See note and recommendations below
- Marstek Venus E firmware v144 or later (Modbus over wired Ethernet, no RS-485 converter required)
- Marstek Venus E connected over wired Ethernet
Home Assistant does not allow official integrations to have a polling rate faster than 5 seconds. As such, many digital-meter integrations only update every 5–10 seconds or so. That is often too slow for smooth battery control: the controller reacts to load changes that are already seconds old, leading to overshoot and oscillations.
This integration addresses the battery side by offering, during config flow, to enable required Marstek Modbus control entities (disabled by default on many installs) and set high-priority polling to 2 seconds — in one reload. You can change polling later in the marstek_modbus integration's options.
For the grid side you have three practical options:
-
HomeWizard P1 dongle. The integration can auto-detect HomeWizard P1 devices during setup and poll the dongle's local HTTP API at 1 Hz, bypassing Home Assistant's sensor polling. Best behaviour with minimal setup.
-
Push-based meter dongles. Dongles that push readings over MQTT (or similar) can deliver sub-second or 1 Hz updates without HA's polling limit. The plan-d P1 dongle is one example (1 Hz over MQTT).
-
A self-built fast sensor. E.g. a REST-based template sensor in
configuration.yamlwithscan_interval: 1hitting your meter's local API can produce 1-second updates; select that entity as the grid power sensor.
If you only have a 5–10 s grid sensor, the integration still works, but expect more setpoint movement. Widening the smoothing windows (e.g. 10 s) reduces noise at the cost of slower response.
Make sure you have ViperRNMC marstek_modbus integration installed first!
- Open HACS → Integrations → ⋮ → Custom repositories.
- Add
https://github.com/plan-d-io/Marstek-battery-controlleras category Integration. - Install Marstek Battery Controller and restart Home Assistant.
Copy the folder custom_components/marstek_battery_controller/ into your Home Assistant config/custom_components/ directory, restart HA, then add the integration from the UI.
- Go to Settings → Devices & services → Add integration.
- Search for Marstek Battery Controller and start the configuration flow.
| Step | What it asks | What to choose |
|---|---|---|
| Marstek battery | Which Marstek Venus E to control | Pick the one detected via marstek_modbus, or enable manual entity setup if discovery doesn't work |
| Prepare Marstek Modbus | Enable required control entities and/or set 2 s high-priority polling on marstek_modbus |
Recommended: enable both when offered. Applies in one reload (may take 1–2 minutes). Change later in Marstek Modbus settings |
| Grid power source | Where to read household grid power from | If you have a HomeWizard P1, pick that (recommended). Otherwise pick an existing power sensor or enter a HomeWizard IP manually |
| Optional sensors | Two extra inputs for capacity tariff handling | The current quarter-hour average power sensor (typical name: peak demand, kwartiervermogen) and optionally a monthly peak sensor. Both optional — leave empty if you don't have them |
| Initial parameters | Starting values for SoC limits, peak window time, etc. | Defaults are reasonable; everything is editable later via the device page |
These are the parameters most users adjust occasionally:
- Mode — switch between modes as your needs change (e.g. enable boost during winter, switch back to plain self-consumption in summer)
- Minimum SoC / Maximum SoC — battery operating range
- Peak window start — when your evening (or morning) peak typically begins
- Reserve target SoC — how much battery you want available before the peak window starts
- Boost charge power — how fast the battery can charge from the grid in boost mode
- Capacity tariff limit — the maximum peak power this integration should respect:
- when charging from the grid in boost mode, it will never exceed this limit (meaning the battery will charge slower if other energy consumption is present)
- when storing reserve energy for a later peak in passive boost mode, the battery will start to discharge if it dectects peak consumption will exceed this value
The remaining parameters (smoothing windows, send interval, battery capacity) are advanced and are filed under Configuration on the device page.
Minimum SoC must be less than maximum SoC; boost charge power and manual power must not exceed maximum battery power (enforced in the options flow). If reserve protection start is the same time as peak window start, the reserve protection window is empty and a warning is logged.
- Released — relinquishes control back to the Marstek app / native logic.
- Self-consumption — textbook self-consumption: charge with surplus solar that would otherwise be exported, discharge to cover household consumption, all within configurable SoC limits.
- Self-consumption + boost — like self-consumption, but also actively charges the battery from the grid before your configured peak window if it can't reach the reserve target SoC from solar alone. Useful in regions with capacity tariffs to ensure the battery is loaded before the daily consumption peak.
- Self-consumption + reserve — like self-consumption, but stops discharging below the reserve target SoC during the protection window. Charges from solar surplus only; never from the grid. Useful when you want to keep some battery in reserve for the evening but don't want to pay grid-charge costs.
- Manual — directly charge or discharge to a target SoC at a chosen power. Auto-exits to the previously active mode when the target is reached.
- I just want maximum solar self-use, no capacity tariff to worry about → Self-consumption
- I have a capacity tariff and I'm OK pre-charging the battery from the grid before my peak window if needed (max captar is respected) → Self-consumption + boost
- I have a capacity tariff but I want the battery to charge from solar only — never from the grid → Self-consumption + reserve
- I want to manually charge or discharge to a specific SoC → Manual
- I want the Marstek app / Marstek's own logic to control the battery → Released
The integration creates a single device with the following entities, organised by where they appear on the device page.
| Entity | Purpose |
|---|---|
| Mode | The active operating mode |
| Minimum SoC | Battery won't discharge below this (note that Marstek enforces a minimum SoC of 12%) |
| Maximum SoC | Battery won't charge above this |
| Maximum battery power | Hard ceiling on battery power, both directions |
| Capacity tariff enabled | Whether capacity-tariff logic is active |
| Capacity tariff limit | Your monthly peak budget in watts |
| Reserve target SoC | The SoC the boost / reserve modes try to ensure for the peak window |
| Boost charge power | How fast to charge from the grid in boost mode |
| Peak window start | When your daily peak window begins (HH:MM, time of day) |
| Reserve protection start | When the reserve mode starts protecting the SoC floor (HH:MM) |
| Manual target SoC | Target SoC for manual mode |
| Manual power | Power to apply in manual mode |
| Manual trigger | Press to activate manual mode with the configured target / power |
| Entity | Purpose |
|---|---|
| Status | High-level mode the integration is currently in (Self-consumption, Boost charging, Reserve held, etc.) |
| Last sent setpoint | The actual signed-watts command the integration last wrote to the battery (positive = discharge, negative = charge) |
These are useful for understanding behaviour but most users never need to look at them. They live in the Diagnostic section of the device page.
| Entity | Purpose |
|---|---|
| Detail | More specific reason the controller is at its current setpoint (e.g. At minimum SoC, Peak limit reached) |
| Target setpoint | The setpoint the calculator wants — usually equal to Last sent setpoint, can briefly differ |
| Active capacity tariff limit | Effective threshold (max of your set limit and the current monthly peak, when known) |
| Boost must start by | Time at which the boost mode must start charging to reach the reserve target by the peak window |
| Minutes to peak window | Countdown to the next peak window start |
| Energy needed for reserve | Wh required to reach the reserve target SoC from current SoC |
| Grid power smoothed | Internal smoothed value used by the calculator |
| Battery power smoothed | Internal smoothed value used by the calculator |
| Grid power fast (HomeWizard) | Real-time grid power from the HomeWizard fast-poll, when active |
These appear under the Configuration section of the device page. They're advanced tuning parameters — change carefully.
| Entity | Purpose |
|---|---|
| Battery command send interval | How often the integration writes to the battery (default 5 s) |
| Grid power averaging window | Smoothing window for the grid input (default 5 s) |
| Battery power averaging window | Smoothing window for the battery input (default 5 s) |
| Battery capacity | Total capacity in Wh used for energy/time calculations |
Marstek firmware exposes Modbus register 42011 (charge_to_soc) as a built-in way to charge to a target SoC. This integration does not use that register; manual mode and auto-exit are implemented explicitely to retain full visibility of what the battery is doing.
UI strings for the integration (config flow, entity names, mode states, issues) are provided in English, English (GB), Dutch, French, and German under custom_components/marstek_battery_controller/translations/.
This work is licensed under a Creative Commons (4.0 International License): Attribution