Releases: ffunes/Omnibattery
Releases · ffunes/Omnibattery
Release list
v1.0.0b1
[1.0.0b1] - 2026-06-29
⚠️ Major change — new repository, integration renamed to “Omnibattery”This is the continuation of Marstek Venus Energy Manager (
ffunes/marstek-venus-energy-manager), now living in a new repository —ffunes/omnibattery— and multi-brand (Marstek + Zendure). The HA domain also changed (marstek_venus_energy_manager→omnibattery). Because HACS cannot rename a custom integration's domain/folder in place, this is not an in-place update from the old repo: you install the new repo and migrate across to it. Everything is preserved — configuration, entity IDs (they staymarstek_venus_*), recorder history, long-term statistics, dashboards and automations.How to migrate (take a Home Assistant backup first; your data is safe at every step):
- Update the old integration to its final release first. That build writes a recovery snapshot of your full configuration to disk, so nothing is lost even if the old integration is later removed.
- In HACS → ⋯ → Custom repositories, add
https://github.com/ffunes/omnibattery(type: Integration) and install it. Leave the oldmarstek-venus-energy-managerrepository in place for now.- Restart Home Assistant, then go to Settings → Devices & Services → Add Integration → Omnibattery.
- Confirm the migration when prompted. If your old config is still present it migrates seamlessly; if you had already removed the old integration, it offers to restore from the snapshot written in step 1. Either way it recreates your config on the new domain and re-links every entity, its history and stored state.
- Once Omnibattery is running, remove the old
marstek-venus-energy-managerintegration and repository from HACS.- Hard-refresh the browser (Ctrl+F5) so the renamed sidebar panel loads.
This is a beta — please report anything odd on GitHub.
Added
- Modbus serial / RTU support (#350): a Marstek battery wired over RS485 (USB adapter) instead of WiFi can now be added by entering a serial port path (e.g.
/dev/ttyUSB0) instead of an IP. Fixed at 115200 8N1; leave the path empty for the usual Modbus TCP.infra/modbus_client.py,config_flow.py. - Zendure SolarFlow support: the integration now drives Zendure batteries (2400 AC / AC Pro / AC+) over local HTTP, auto-detecting the model. Capacity, soft-max charge and force-mode are configured from the setup/options flow. Built on the new driver layer, so Zendure and Marstek share the same control loop, sensors, dashboard and translations.
drivers/zendure.py. - Tibber price provider for dynamic pricing: select Tibber as the price integration — no price sensor needed. The engine polls the
tibber.get_pricesservice (today's 15-minute prices, tomorrow's after ~13:00), caches the slots and refreshes hourly.pricing/engine.py,pricing/calculations.py. - Per-device exclusion % slider: each excluded device gets a runtime slider (0–100%, default 100 = fully excluded) controlling how much of its demand stays off the battery, so the battery can cover part of a big load instead of all-or-nothing.
number.py,infra/external_loads.py. - No-PD direct-tracking mode (opt-in switch): the battery follows the consumption sensor 1:1 in a single cycle — no integral, derivative, smoothing, rate limiter or hysteresis — instead of the PD control law. Each cycle it reconstructs the home load from the battery's measured AC power (
new = measured − error), so it stays stable across the multi-second inverter ramp instead of oscillating rail-to-rail. Reuses the deadband, min charge/discharge power, relay min-ON and grid-setpoint sliders, plus a new No-PD Command Delay slider that debounces fast meters (collapses a burst into one command on the latest value). Off by default; the PD controller is unchanged.__init__.py,switch.py. - System power limits toggle: a runtime switch on the Control tab turns the combined system charge/discharge caps on/off without entering the options flow.
switch.py. - Delay weekly full charge toggle: a runtime switch (Weekly full charge card) lets the weekly 100% charge wait for the solar charge delay instead of charging immediately on its target day. Off by default, so the historic always-bypass behaviour is unchanged.
switch.py. - Re-evaluate dynamic pricing button: a system button that rebuilds today's dynamic-pricing charge schedule on demand (same evaluation as the 00:05 daily run). Shown only in dynamic-pricing mode.
button.py. - Separate discharge price floor (#408, dynamic pricing): optional second threshold so charge and discharge use different prices, opening an idle band between them (no grid charge, no discharge; solar-surplus charging still works) to avoid marginal cycles. Both thresholds are also exposed as live
numberentities so automations can rewrite them, and the floor is validated to stay at or above the charge ceiling. Empty = reuse the max price threshold for both (unchanged for existing installs).pricing/engine.py,number.py,config_flow.py. - Guaranteed minimum SOC floor (#417, predictive charging): a Guaranteed Minimum SOC slider (Control tab, 0 = off) forces an overnight grid charge to reach at least that SOC by the end of the charging window, even when the whole-day solar forecast nets to zero deficit — covering the morning gap before solar ramps up. Sizes the deficit to the floor, so it flows through the per-battery target SOC and dynamic-pricing slot sizing unchanged.
__init__.py,number.py. - Up to 3 predictive charging windows (Time Slot mode): configure 1, 2 or 3 charging windows, each with its own start/end and days. Fill only window 1 for the previous single-window behaviour. The consumption-window math now treats the union of all windows.
config_flow.py,__init__.py,tracking/consumption_tracker.py.
Changed
- Voltage taper power raised from 95 W to 200 W: at 95 W the cell did not sustain enough excitation to hold voltage in the taper zone for some batteries; 200 W keeps the cell more stable in the CV-like region without rushing to the BMS cutoff.
const/integration_const.py. - Slow actuators skip the hot-path readback: a slow actuator (Zendure HTTP, ~2.5 s settle) no longer blocks the shared control loop with a multi-second setpoint readback — its non-delivery is judged at poll time instead. The shared loop cadence and grid smoothing are NOT slowed to the fleet's slowest battery (that throttled fast Marstek tracking for the whole fleet); per-battery pacing belongs in the power distribution.
__init__.py,drivers/base.py. - Rebranded to Omnibattery (moved to the new
ffunes/omnibatteryrepo; domainmarstek_venus_energy_manager→omnibattery). Existing installs migrate the first time you add “Omnibattery”: if the legacy config entries are still present it detects them and, on confirm, recreates each one on the new domain, repoints the entity registry without changing any entity ID or unique ID (they staymarstek_venus_*, so recorder history and long-term statistics survive untouched), and copies the integration's.storagestate (daily energy totals, accumulators, balance history). If the old integration was already removed (HACS can't rename the domain in place across repos), it restores instead from a recovery snapshot the old build saved to disk. Nothing in your dashboards or automations breaks.domain_migration.py,migration_flow.py,config_backup.py. - Charge hysteresis is now mandatory (min 2%): the per-battery enable toggle is gone — hysteresis is always on. Existing batteries keep their configured percent; those that had it off get the 2% floor, which keeps the deadband wider than SOC-reading drift and prevents charge chatter at the top. Migrated on upgrade (config entry v7 → v8).
__init__.py,number.py. - Opt-in rename of system entities to
omnibattery_*: system entities now suggest anomnibattery_*entity ID while keeping their legacyunique_id(so recorder history and statistics stay linked). Existing installs are untouched until you trigger HA's built-in Settings → Devices & Services → Omnibattery → ⋯ → Recreate entity IDs, which renamessensor.marstek_venus_system_*→sensor.omnibattery_*in place (history preserved); new installs get the Omnibattery IDs from the start. The dashboard matches by translation_key, so it keeps working through the rename.⚠️ Your own automations/templates/Energy-dashboard config that r...