GitHub Release Tests GitHub Activity License hacs Sponsor
Smart orchestration for solar, battery, EV & home loads in Home Assistant — maximize self-consumption, automate EV charging, optimize tariffs, and manage peak loads automatically.
SEM monitors your solar production, battery, grid, EV charger, and household devices every 10 seconds and distributes surplus power by priority. No cloud, no subscription — everything runs locally inside Home Assistant.
- Smart EV charging — dynamic 6-32A current control based on real-time solar surplus
- Five charging modes — Solar only, Solar + cheapest hours, Min + Solar, Always (max), Off
- Auto mode — automatically switches between self-consumption and fast charging based on solar forecast vs EV need
- 1↔3-phase switching (#804) — for wallboxes with a phase-switch entity (go-e, KEBA X-series, openWB): SEM measures the active phases from the real draw, offers a per-charger Phase Mode (Auto / 1-phase / 3-phase), and switches through a safe stop → switch → settle → start sequence with hysteresis and hard interval/session caps. Auto scales the charger to fit the surplus; manual winter-pins 1-phase for low sun. See docs/EV_CHARGING_LOGIC.md
- Battery-aware — four-zone SOC strategy decides when battery helps the EV and when it charges first
- Min/Max charge-target range — a per-charger dual-handle slider (kWh or SOC %): Min is the guaranteed amount (night/grid tops up to it), Max is the solar ceiling (surplus charges up to it, then stops). E.g. Min 50% / Max 80% — always keep 50% from the grid, let solar add up to 80% for battery longevity. Max defaults to full (charge freely from sun)
- Charge-by deadline — set a per-charger "be ready by HH:MM" time and SEM scales the night current to reach Min by then (overriding the gentle ramp when time is short), and warns if the target can't physically be met in time. "Set as default" copies a charger's target + deadline to the global defaults
- Tariff-optimized charging — opt-in per charger: defer night charging to the cheapest contiguous price window (Min still guaranteed by the deadline) and pause daytime grid top-up during expensive hours — surfaced live as the next-cheap-window on the EV card
- Night charging with battery protection — charges EV from grid overnight without draining home battery
- Battery export arbitrage — on a dynamic/spot tariff, opt-in sell the home battery to the grid when the export price beats the cost of recharging later (round-trip + wear accounted for); never below your reserve SOC, brand-agnostic, shown live as a "Selling to grid" state. See docs/BATTERY_EXPORT_ARBITRAGE.md
- Hot water solar boost — SEM supplements your existing heating system with solar surplus (does not replace your boiler/heat pump), with mandatory Legionella prevention cycle (DVGW W 551, SIA 385/1, ÖNORM B 5019)
- Multi-device surplus distribution — EV, heat pump, hot water, appliances — each gets surplus by priority, with appliance dependency chains (e.g. heater only runs when pump is active)
- Daily runtime goals for household loads (#620) — give any switch a Min / Max runtime window (e.g. pool pump ≥ 4 h, ≤ 8 h/day) via a dual-handle slider, a daytime mode (Off / Peak-only / Solar only / Solar + battery assist), and a "Finish overnight from" picker — Off / Battery / Grid (cheap-tariff window) — for completing the runtime when the sun runs short. Plus an optional stop condition picked with an entity search (e.g. water-temp ≥ 28 °C, car SOC ≥ 80 %). No forced grid deadlines. The load is prioritised in the one device list and exposes a surplus-event interface for your own automations. See
docs/LOAD_PRIORITY.md. - Peak load management — automatic device shedding to stay under your grid limit
- Solar forecast integration — Solcast, Forecast.Solar or Open-Meteo Solar Forecast for smart charging decisions
- Dynamic tariff support — Tibber, Nordpool, aWATTar, Amber Electric, Octopus Energy price-responsive charging
- 200+ sensors and entities — power, energy, flows, costs, performance, forecasts, and more
- Per-PV-string visibility — auto-discovered per-string power + daily-energy sensors and a chip strip on the system diagram + flow cards (when your inverter exposes per-string data). Works on Huawei, GoodWe, Growatt, Kostal, Sungrow, Fronius, SolarEdge, SolaX, with V·I synthesis fallback for inverters that expose voltage + current separately.
- Built-in dashboard — theme-aware styling (works on both dark and light HA themes), animated system diagram, Sankey, and native HA energy cards
- PV performance analytics — specific yield, forecast accuracy, degradation tracking
- Smart recommendations — forecast-aware tips ("Best window for appliances: 11:00-14:00", "Low solar tomorrow — charge EV tonight")
- Consumption/solar predictor — learns hourly patterns (weekday/weekend), predicts next-hour power and daily consumption
- Push notifications — battery full, daily summary, forecast alerts, EV charging events (with Android channels and action buttons)
- Brand icons — native HA 2026.3+ brand support (no submission to home-assistant/brands needed)
- EV Intelligence — detects BMS charge tapering, estimates SOC without car API, learns daily consumption per weekday, temperature-corrected predictions, smart night charge skip
- Smart night charging — in the
Min + SolarandSolar + cheapest hoursmodes, automatically skips or reduces night charges when SOC is sufficient, with solar forecast credit, daily SOC decay, and 3-skip safety net - EV battery health — tracks capacity degradation from partial charge sessions over months
- Hardware compatibility test suite — 150+ automated tests covering all supported hardware — every inverter + charger combination verified in CI
- Transparent auto-detection (#814) — the dashboard Configuration → Detected hardware section shows every device SEM found with the evidence for each role, and names near-misses (a brand almost supported) instead of silently detecting nothing. The full support matrix with an honest per-brand status is generated and CI-guarded: docs/SUPPORTED_HARDWARE.md
One integration, your whole energy system. Install SEM and you get EV charging, battery strategy, multi-device surplus distribution, tariff optimization, peak-load management, cost analytics, and a full dashboard — all from a single HACS download.
- Local-first — everything runs inside Home Assistant. No cloud, no subscription, no account.
- No extra moving parts — no separate services, no Docker containers, no YAML config files, no AppDaemon.
- Works out of the box — SEM auto-detects your inverter, battery, grid, and charger from the Energy Dashboard, then exposes every knob on its own dashboard when you want to tune it.
- Built for real hardware — every supported inverter and charger combination is verified in CI, and the whole system is designed around locally-controlled devices.
If you can see it in your Home Assistant Energy Dashboard, SEM can orchestrate it.
New to Home Assistant integrations? See the Step-by-Step Setup Guide for a beginner-friendly walkthrough with checklist and FAQ.
SEM is in the default HACS store — no custom repository needed.
Open your Home Assistant instance and open the SEM repository inside HACS.
- Open HACS and search for Solar Energy Management
- Click Download
- Restart Home Assistant
- Go to Settings → Devices & Services → + Add Integration and add Solar Energy Management
(Or click the button above to jump straight to it in HACS.)
Want to help test new features before they go stable? Enable beta updates in HACS:
- Open HACS > Integrations > find Solar Energy Management
- Click the three-dot menu > Redownload > enable Show beta versions
- Select the latest beta and install
Beta releases are tested on real hardware before publishing but may contain rough edges. Your feedback helps us ship stable releases faster — report issues on GitHub.
- Download the latest release
- Copy the
custom_components/solar_energy_management/folder to your Home Assistantconfig/custom_components/directory - Restart Home Assistant
Before setting up SEM, make sure you have:
- Home Assistant 202620 or newer
- Energy Dashboard configured — SEM reads your solar and grid sensors from the HA Energy Dashboard (Settings > Energy). You need at least:
- A solar production sensor (W)
- A grid consumption sensor (W)
- Battery capacity is auto-detected from your inverter (v1.2.1+)
- Optional but recommended:
- Battery SOC (%) and power (W) sensors
- An EV charger controllable via HA (KEBA, Wallbox, go-eCharger, Easee, Zaptec, ChargePoint, Heidelberg, etc.)
- Solcast PV Solar, Forecast.Solar or Open-Meteo Solar Forecast for solar forecasts
- Tibber, Nordpool, or aWATTar integration for dynamic tariffs
- Go to Settings > Devices & Services > Add Integration
- Search for Solar Energy Management
- Follow the setup wizard
SEM auto-detects your solar, grid, and battery sensors from the HA Energy Dashboard. If they are not configured yet, the wizard will ask you to set up the Energy Dashboard first.
SEM also uses the Energy Dashboard's import/export energy counters to automatically detect your grid and battery power sensor sign conventions — no manual configuration needed. This works with all inverter brands regardless of whether they use positive-for-export or positive-for-import conventions.
Select the sensors for your EV charger:
| Setting | Description |
|---|---|
| Connected sensor | Binary sensor showing if the EV is plugged in |
| Charging sensor | Binary sensor showing if charging is active |
| Charging power sensor | Power sensor (W) for current charging power |
| Charger service | Service to set charging current (e.g., keba.set_current) |
| Total energy sensor | Cumulative energy sensor (kWh) — optional |
SEM auto-detects chargers from the entity registry: KEBA, Wallbox Pulsar, go-eCharger (HTTP + MQTT), Easee, Zaptec, ChargePoint, Heidelberg, OpenWB 2.x, OCPP-compatible, Ohme, Peblar, V2C Trydan, Alfen Eve, Blue Current, OpenEVSE. Any other charger that exposes power/connected/charging sensors in HA can be configured manually.
- Charger display messages — show charging status on the charger's built-in display (KEBA, Easee, Wallbox, etc.)
- Notifications — push notifications via HA Companion App (
notify.mobile_app_*), REST webhooks (rest_command.*), or anynotify.*service (Matrix, Slack, Telegram, etc.)
Key settings you can adjust (all have sensible defaults):
| Setting | Default | Description |
|---|---|---|
| Update interval | 10s | How often SEM reads sensors and adjusts |
| Daily EV target | 10 kWh | How much energy to charge overnight |
| Battery priority SOC | 30% | Below this, all solar goes to battery first |
| Battery buffer SOC | 70% | Above this, battery can help charge the EV |
| Battery auto-start SOC | 90% | Above this, EV starts even without solar surplus |
| Min solar power | 500W | Minimum surplus before solar EV charging starts |
| Observer mode | Off | Read-only mode for test systems (no hardware control) |
For detailed explanations of all settings, see the Setup Guide.
Enable peak load management if your utility bills based on peak demand. Tune the target peak limit from the Control tab's slider (1–80 kW, or drag to Uncapped if your connection has no limit worth defending) — warning (90%) and emergency (120%) are derived from it automatically and sit behind an Advanced disclosure on the Configuration tab. See Load Management Settings for the full reference.
SEM is designed to be mostly automatic. The controls that matter (v1.6.3 — toggle-soup replaced by a single named selector, #277):
| Entity | Default | What it does |
|---|---|---|
switch.sem_observer_mode |
OFF | Read-only mode — SEM monitors but doesn't control hardware (global) |
select.sem_charger_<id>_charge_mode |
Min + Solar |
Per-charger. One named selector carries the night-charging, smart-night, and tariff-window intent that used to live on three separate switches. Options: Solar only / Solar + cheapest hours / Min + Solar / Always (max) / Off. |
EV charge targets, currents, phases and consumption are all per-charger entities too (number.sem_charger_<id>_..., select.sem_charger_<id>_...) — the global EV settings were removed in #255 (per-charger is the source of truth; globals are read-only summaries). Everything else — solar charging, surplus distribution, battery protection, peak management — is fully automatic.
The per-charger Charge mode selector replaces the four-toggle soup with five named modes. Each mode composes with the existing Charge Target range (Min / Max) and the Charge by HH:MM deadline.
Pure surplus. With the "At least" floor at 0 — the default — it never touches the grid, day or night. Set a floor on this charger and SEM tops that shortfall up overnight by the Charge-by time, which is how you keep the solar-first mode and still guarantee a minimum (#634/#679). Pick this if you only ever want to charge from sun.
Surplus by day, grid only in the cheapest contiguous tariff window at night (Min still guaranteed by the deadline). Hidden if no dynamic tariff is configured. This is the only mode that consults the tariff.
Guarantees Min by deadline, solar adds up to Max. Zone-adaptive during the day — the Min guarantee comes from NIGHT charging top-up, not forced grid pull at noon. During the day the strategy machine still consults the SOC zone (battery priority when low, surplus when high, battery-assist in Zone 4). Most users want this.
Charge at maximum regardless of source. Strict "Min from grid at all times" behaviour — equivalent to the legacy minpv mode.
No charging. SEM monitors but issues no commands to the charger.
Battery discharge protection prevents the home battery from powering the EV overnight regardless of mode.
When the battery SOC is above the buffer threshold (default 70%), SEM supplements solar with battery power to maintain EV charging during cloudy moments. This is automatic — no switch needed.
SEM includes a built-in dashboard with 8 views and a unified glassmorphism dark theme:
| View | Description |
|---|---|
| Home | Illustrated system diagram with SVG component drawings, spark flow animations, sun arc, solar summary, 7-day chart, weather, smart recommendations |
| Energy | Sankey diagram, self-consumption/autarky gauges, donut chart, 24h power, CO2 avoided, trees saved |
| Battery | SOC radial gauge, 24h charge/discharge chart, zone configuration |
| EV | Charging status, session stats, solar share gauge, lifetime totals, EV Intelligence (taper trend, virtual SOC, charge skip reasoning, battery health) |
| Control | Live surplus allocation, load-priority drag-and-drop, per-device control modes, today's schedule |
| Configuration | All post-setup configuration in one place — staged Apply/Revert per section (nothing saves on an accidental tap), a i on every setting with its explanation, factory default and one-tap ↺ reset, an Explain settings toggle that opens all help at once, and a 📖 link on each section header straight to the matching docs chapter. Rarely need HA's native config flow |
| Costs | Today/month/year KPIs, period selector, cost & savings charts, demand charge, tariff rates |
| System | Health diagnostics, sensor status, charging state, peak management |
| Energy | Costs |
| Battery | EV |
| Control | System |
| Configuration |
- Glassmorphism styling — frosted glass cards with dot grid backgrounds, radial gradients, hover effects
- Illustrated system diagram — sem-system-diagram-card with detailed SVG illustrations (solar panels, house, battery, grid pole, EV charger), K-Flow-inspired spark flow animations, time-based sun arc with golden sine wave particles, clickable nodes, individual device display on desktop, responsive layouts. Optional K-Flow card via
diagram_style: "kflow"config - Animated energy flow — sem-flow-card with real-time power flows, daily energy totals, autarky gauge, config editor, tap/hold/double-tap actions
- Custom SEM cards — flow card, solar summary (glow ring), weather (clock + forecast), chart card (Chart.js), period selector
- Drag-and-drop load priority — reorder device shedding priorities visually
- Environmental impact — CO2 avoided and trees-equivalent with growing icon (sprout/tree/pine/forest)
- Yearly KPIs — year-to-date costs, savings, revenue on the Costs tab (auto-seeded from HA recorder on mid-year install)
For dashboard setup instructions, see the Dashboard Guide.
SEM creates 70+ sensors organized by category:
| Category | Examples |
|---|---|
| Power | Solar, grid, battery, EV, home consumption (W) |
| Energy | Daily/monthly totals for all sources (kWh) |
| Flows | Solar-to-home, solar-to-EV, grid-to-EV, battery-to-home (W and kWh) |
| Costs | Daily/monthly import costs, export revenue, savings |
| Performance | Self-consumption rate, autarky rate, solar efficiency (%) |
| Charging | State, strategy, available power, calculated current |
| Surplus | Total, distributable, allocated, active devices |
| Forecast | Today/tomorrow kWh, remaining today, peak time, next hour, surplus window |
| Tariff | Current import/export rate, price level, next cheap window |
| PV Analytics | Specific yield, forecast accuracy, degradation trend |
| Smart Tips | Optimization score, forecast-aware recommendations, best surplus window |
| Load Mgmt | Peak margin, 15-min average, devices shed, trend |
| EV Intelligence | Taper trend/ratio, virtual SOC, minutes to full, charge needed, skip reason, battery health, predicted consumption |
| Notifications | Battery full, high grid import, daily summary, forecast alerts |
The full, generated matrix — brand, integration, sign pattern, control method and how sure we are (tested live / implemented / requested) — lives in docs/SUPPORTED_HARDWARE.md. It is rendered from one data table and CI keeps it from drifting. It also lists the vehicles used as SOC sources and the heat pumps, hot-water relays, metered loads and grid meters people run SEM with — every ✅ row cites the issue or discussion it was proven in.
Solar Inverters: Huawei Solar, SolaX, DEYE/Sunsynk, Growatt, Sofar, Solis, Fronius, SMA, SolarEdge, Enphase, GoodWe, Tesla Powerwall, Kostal Plenticore, Sungrow, Victron, Sonnenbatterie, E3DC, GivEnergy, Fox ESS, Alpha ESS, Senec, RCT Power, KSTAR, FENECON Home — or any inverter with HA sensors. SEM reads from the HA Energy Dashboard and auto-detects both grid and battery sign conventions.
Batteries: Any battery exposed through a supported inverter integration, plus standalone systems: Sessy (NL), Huawei LUNA2000, Tesla Powerwall, Sonnen, BYD, Pylontech, and others work automatically. Battery capacity is auto-detected from the inverter.
Battery discharge control auto-detected for: Huawei Solar, SolaX (solax-modbus), DEYE/Sunsynk (ha-solarman), Growatt, Sofar, Solis, GoodWe, SolarEdge (solaredge-modbus-multi), Enphase (IQ Battery), Tesla Powerwall, Victron, Kostal Plenticore, Sungrow
EV Chargers (auto-detected): KEBA P30, Wallbox Pulsar, go-eCharger (HTTP + MQTT), Fronius/go-e Wattpilot, Easee, Zaptec, ChargePoint, Heidelberg Energy Control, OpenWB 2.x, OCPP-compatible (ABB Terra, Vestel, Grizzl-E, etc.), Ohme, Peblar Rocksolid, V2C Trydan, Alfen Eve, Blue Current, OpenEVSE
EV Chargers (manual config): Any charger exposing power/connected/charging sensors in HA. Proven live this way (not brand-detected yet): GARO wallbox and JuiceBox 48 — see the matrix for the threads.
Note: KSTAR inverters are supported via the ha-solarman integration with KSTAR YAML profiles, not via a dedicated KSTAR integration.
Note: Fronius and SMA core integrations are read-only for battery control. Battery discharge protection requires the Modbus variant (e.g.,
fronius_modbus) or works without discharge limiting.
Note: DSMR/P1 smart meters (NL/BE) are auto-detected for grid power. If your grid is metered by a separate smart meter (not by the inverter), SEM discovers the split import/export power sensors automatically.
Hot Water: Any hot water system exposed as a water_heater, climate, or switch entity in HA. Includes automatic Legionella prevention cycling per DVGW W 551 / SIA 385/1 / ÖNORM B 5019.
Heat Pumps: Any SG-Ready compatible heat pump controllable via HA
Smart Meters: Shelly EM/Pro, Discovergy, or any HA-compatible meter
SEM learns your EV's charging behavior and makes smart decisions about when to charge. Implicit in the Min + Solar and Solar + cheapest hours Charge modes (v1.6.3); was the standalone smart_night_charging switch in v1.6.x.
How it works:
-
Taper detection — SEM detects the characteristic power staircase when your car's BMS reduces current near full charge (CC→CV transition). This is the most accurate SOC anchor (100% confirmed).
-
Virtual SOC — Tracks estimated battery level without a car API by monitoring energy in (charging) and out (predicted daily consumption). Calibrates from real
vehicle_soc_entitywhen available. -
Daily consumption learning — EWMA predictor learns per-weekday patterns: "Monday 8 kWh, Wednesday 0 kWh (WFH), Saturday 15 kWh". Adapts over 7 days.
-
Temperature correction — Adjusts consumption predictions for seasonal variation: winter (-5°C) = +72% consumption, summer (30°C) = +9%. Based on Recurrent Auto fleet data (30,000+ vehicles).
-
Smart night charge skip — If estimated SOC is sufficient for tomorrow's predicted consumption (with 30% safety margin and solar forecast credit), SEM skips the night charge. Max 3 consecutive skips as safety net.
-
Session-based anchoring — Works from day one without needing a full charge. First charge session bootstraps the SOC estimate. Taper detection and car API override with more accurate values when available.
Sensors: ev_estimated_soc, ev_taper_trend, ev_nights_until_charge, ev_charge_needed, ev_predicted_daily_consumption, ev_battery_health, and more.
automation: - alias: "SEM: Daily solar target reached" trigger: - platform: numeric_state entity_id: sensor.sem_daily_solar_energy above: 30 # kWh action: - service: notify.mobile_app data: title: "Solar Target Reached" message: > Daily solar production exceeded 30 kWh ({{ states('sensor.sem_daily_solar_energy') }} kWh)
automation: - alias: "SEM: Cheap price EV charging" trigger: - platform: state entity_id: sensor.sem_tariff_price_level to: "cheap" condition: - condition: state entity_id: binary_sensor.sem_ev_connected state: "on" action: - service: select.select_option target: entity_id: select.sem_charger_ev_charger_charge_mode data: option: always_max
Switch the mode back to min_plus_solar when the price level leaves "cheap" to return to normal solar-prioritized behaviour.
automation: - alias: "SEM: Peak alert" trigger: - platform: numeric_state entity_id: sensor.sem_peak_margin below: 0.5 # kW remaining before target action: - service: notify.mobile_app data: title: "Peak Protection" message: > Grid peak approaching limit ({{ states('sensor.sem_peak_margin') }} kW margin)
Maximize solar self-consumption for EV charging — Plug in during the day and SEM adjusts current to match surplus. Battery priority ensures the home battery charges first, then the EV gets the rest.
Reduce peak load charges — SEM monitors rolling 15-minute averages and sheds non-critical loads to stay under your target peak limit.
Battery-assisted EV charging on cloudy days — When forecast shows insufficient production but battery SOC is above the buffer, SEM supplements solar with battery discharge.
Price-optimized night charging — With dynamic tariff integration, SEM charges the EV during the cheapest overnight hours while protecting the home battery.
| Guide | Description |
|---|---|
| Quick Start | 5-minute setup guide |
| Setup Guide | Detailed configuration and tuning |
| Dashboard Guide | Dashboard tabs, cards, and multi-language support |
| Multi-Device Guide | Multi-inverter, multi-charger, and brand-specific setup |
| Architecture | Developer and contributor documentation |
- Go to Settings > Devices & Services > Solar Energy Management
- Click the three-dot menu and select Delete
- Restart Home Assistant
- If installed via HACS: open HACS > Integrations, find SEM, click Remove
- If installed manually: delete the
custom_components/solar_energy_management/directory
All SEM entities are removed automatically. Your Energy Dashboard and hardware sensors are not affected.
The 2.0 line adds almost nothing you have to learn. It makes what SEM already did believable: the same decisions, no longer changing their mind for reasons nobody can see.
- SEM stops shouting in your log and your database — its recorder footprint fell from 25 % to 6.1 % of Home Assistant's state writes, and at the default log level SEM is quiet. A stop repeated 1800 times, a debug firehose, and a battery setpoint your inverter refuses are all gone.
- The numbers reconcile — the energy diagram balances, per-device breakdowns agree with the fleet total, the Costs tab's year and months agree, and an estimate is never recorded as a measurement. Exported battery energy is attributed and paid once; a bought kWh does not become free by sitting in the battery.
- SEM stops fighting hardware it cannot win against — the stop-war ceasefire holds even against slow-retrying cars, a charger that undoes SEM's stop on a timer is named rather than fought, and a missed poll is no longer read as an unplug.
- Setup tells the truth — every setting has an explanation, settings ranges are declared once, the first-run welcome describes your install, and the setup checklist can actually be completed. Hardware detection matches what integrations really publish, so a charger named in your own language is still found.
- Repairs offer the next step — every notice links either the exact troubleshooting section or a bug report with your versions already filled in.
- Nothing switches on silently on upgrade, and a fresh install no longer wakes up observing.
- The charger does what you told it — a stop no longer starts the charger (on a KEBA, SEM's "stop" used to enable the box with a 1 kWh energy target so it would charge into a stop, putting ~1 kWh into the car on every plug-in against a zero ask, #854); Mode = Off no longer switches off a load you had running (#847); the box is parked when the car leaves so the next plug-in cannot auto-start behind SEM's back (#846); and a stop that cannot reach the hardware now says so instead of failing silently (#852). 1↔3-phase switching ships off by default while it is reworked (#804).
- Requires Home Assistant 202620 or newer (#836), and the suite runs against the HA versions that matter rather than one.
Why the major number: this release changes what an existing install does without the user changing anything. Night actuation is on by default (the migration writes the choice down and points at the kill-switch; an install that already turned it off is never touched), and the private cheap-window pickers are gone — a solar_plus_cheap install's night timing now comes from the joint plan rather than the code path it has been running. Same intent, different decision-maker.
The planner that started the line — what v2.0's first beta shipped, and the reason for the major number:
- The joint energy planner is the only scheduler (#638) — EV, deferrable loads, comfort bands and the battery are packed into one schedule under the shared peak limit, the real price curve and your device priority order. The EV's own cheap-hour pick and the battery scheduler's own window pick are deleted; a CI ratchet keeps them deleted.
- Plan owns WHEN, live economics own WHETHER, your settings own MAY. When a demand runs outside the plan it says so — a translated "reactive — why" chip on the card, in 16 languages, never silence.
- "Not scheduled tonight" — every device the plan deliberately left out is named with its reason (mode excludes it, no car connected, car already full, yields to a higher priority).
- The plan checks its own homework (#755) — a per-demand outcome recorder writes what each demand actually did against what it was promised, and a morning verdict on the card tells you in one line whether your asks match your usage. An estimate is never recorded as a measurement.
- Self-consumption is an objective, not a side effect — a surplus slot is priced at the feed-in revenue it costs to consume it, so solar wins on the numbers instead of by fiat (and a genuinely cheaper grid hour is allowed to win).
- The energy ledger closes (#767–#776) — every kWh SEM moves now has a row, including exported battery energy (
sensor.sem_flow_battery_to_grid_power), grid-vs-solar provenance of stored energy, and a true-baseload figure that refuses to count an estimate as a measurement. - Battery → grid arbitrage is wired (#533 still stands: off on every default) — the plan says when, live economics say whether, per-battery mode says may. Check your grid connection agreement first — see Battery export arbitrage.
- Fresh installs no longer wake up observing (#777) — an old install's leftover switch state can no longer speak for a new one.
- EV charger state reconciler (#392) — the per-cycle imperative actuator (which spammed
keba.disableand dropped KEBA to 6 A) is replaced by a desired-vs-observed reconciler that issues the minimum commands to converge, then leaves the charger alone. Idempotent idle, heartbeat re-writes, failsafe armed once per session. Plus enable-switch reconciliation + backoff (#536) for switch-driven chargers (Wallbox etc.). - Solar Gate (#537) — the home battery only assists the EV when there's real solar surplus ≥ a configurable gate (default 1200 W), in any charging mode; set it to 0 W to allow battery support everywhere including overnight. Closes the overnight battery-drain-into-the-car class of bug.
- Multi-battery control + per-battery modes (#523) — per-battery control entities and five modes (
auto,self-consumption,force-charge,force-discharge,off), zero-config Huawei forcible discharge, corrected SG-Ready relay map. - Smarter EV control — no draining the battery to hold a dead solar session, no charging from expensive grid after the cheap window ends (#461/#524); EV target by daily kWh or vehicle SOC %; per-charger independent surplus vs shed priority (#470).
- Robust grid-sign autodetection + one-tap fix (#461) — solar-anchored detector with
Fix grid sign/Resetbuttons and aflip_grid_signservice; locks survive restarts (#476). - Battery-sign autodetection + one-tap fix (#588) — brand-seeded (deterministic for known inverters) + counter-correlation detector with a
Fix battery signbutton and aflip_battery_signservice, at parity with the grid-sign handling; per-battery on multi-battery installs, locks survive restarts. - Idempotent Huawei Modbus write (#538), dashboard time labels in the home timezone (#539), and full 15-locale dashboard translations (parity-tested).
- Battery → grid export arbitrage shipped in beta but remains deactivated pending more review and soak (#533; re-evaluation planned for a later v1.7.x release).
- HotWaterController fully wired (#454) — setting
hot_water_entitynow actually controls the boiler at runtime (the class existed from day one but was never instantiated). Live status block, Repair issues for unavailable temp sensor / boiler entity, fail-safe semantics (boiler is NOT activated on surplus when the temp sensor is broken), and orphan-repair sweep when the user reconfigures the boiler entity.
- Slim install flow (#442) — 3 steps → 2; users without an EV configured can now finish setup without quitting.
- In-dashboard Configuration tab (#442) — every OptionsFlow setting editable inline with
(?)help, auto-save, and per-section 🩺 Diagnose buttons (#432) that copy focused JSON to the clipboard for sharing in discussions. - EV
ev_target_typestrictly honoured (#451) — no silent fallback toestimated_socwhen the SOC sensor isn't configured. Fixes the IDLE-stuck-at-120W stall reported on Huawei+KEBA in PROD. - Bulletproof EV solar-path stability (#443) — hysteresis smoothing + delta-guard + heartbeat around
_set_currenton the daytimemin_plus_solarZone 3/4 path. Stops KEBA-side current oscillation on cloudy days. - HA Repairs integration (#440) — persistent sensor / forecast / recorder issues surface in Settings → Repairs instead of growing the log; transient sub-5-min flaps stay silent.
- Per-PV-string visibility (#312) — auto-discovered per-string power + daily-energy sensors plus a chip strip on the system diagram and flow cards. Works on Huawei, GoodWe, Growatt, Kostal, Sungrow, Fronius, SolarEdge, SolaX, with V·I synthesis fallback for inverters that expose voltage + current separately.
- Audit telemetry across 10 modules — decision-path enums published as sensor attributes (forecast_tracker, hot_water_controller, heat_pump_controller, pv_performance, time_manager, consumption_predictor, appliance_scheduler, load_management, forecast_reader) so you can self-diagnose without us reading a debug log.
- FleetCycleState refactor — single source of truth for fleet-level coordinator inputs; eliminates the class of fleet-vs-per-charger read bugs that produced four hotfixes between v1.6.0 and v1.6.6.
- 9 Architecture Decision Records committed under
docs/adr/(PerChargerContext, EVBudget, sign-convention boundary, home_consumption clamp, per-brand pipeline test, FleetCycleState, real-hass test framework, FleetEvPower newtype, multi-charger priority cascade). - v7 → v8 config schema migration (#359) — auto-flips legacy
tariff_classification_mode=statictopercentilefor dynamic-tariff users on first restart.
- v1.6.3 — Five named charge modes (#277) replace the four-toggle soup: Solar only / Solar + cheapest hours / Min + Solar / Always (max) / Off. Each mode composes with the per-charger Min/Max range and the Charge-by deadline.
- v1.6.0 — Canonical EV budget across publish path, state machine, actuator, and multi-charger distribution.
sensor.sem_available_powerandsensor.sem_calculated_currentnow publish the same value the state machine and actuator read. - v1.6.4 – v1.6.17 — Multi-charger correctness sweep —
PerChargerContext,FleetCycleStatefoundation, AST lint pinning fleet-vs-per-charger invariants in CI.
- Readings start automatically after an HA restart (#274) — SEM derives its real-time power sensors from the source integration's device. On a cold start it could run that derivation before the source integration (e.g. solax-modbus) had registered its entities, leaving every reading at 0 until you manually reloaded the integration. SEM now re-derives the power sensors each update cycle until they resolve, so the readings come up on their own within a cycle or two of the source loading — no reload needed. Bounded and a complete no-op for setups that already resolve normally.
- Night charging respects the peak limit (#268) — night-charge current is now sized from the house load alone, so grid import stays ≤ your configured peak limit regardless of battery behaviour. Previously battery discharge could inflate the EV current and push grid import well past the limit.
- Per-charger is canonical (#255) — duplicate global EV settings removed; per-charger entities (night charging, mode, phases, target, current) are the source of truth and globals become read-only summaries. Idempotent v3→v4 config migration.
- EV Min/Max range targets (#245) — set a guaranteed Min (grid/night) and a solar-only Max ceiling, in kWh or SoC % (SoC option appears when a vehicle SOC sensor is configured), with live driving-range display.
- Night-charging opt-in (#256) — night charging is per-charger opt-in; no charger charges overnight unless you enable it.
- Surfaced silent failures (#259) — dashboard generation, device mapping, and load-management errors now raise clear, translated messages instead of failing silently; a repair issue flags an unconfigured EV charger.
- Per-charger daily energy (#267) — per-charger daily kWh now persists across restarts and matches the global total.
- SolaX derivation fix (#250) — improved sensor derivation for the SolaX Modbus integration.
- Translations completed — exception/repair messages and the EV range-target help are now translated across all 15 languages.
- System diagram rewrite — detailed inline SVG illustrations replace abstract outlines; left-to-right desktop layout, vertical mobile layout
- Clickable diagram nodes — tap any component to open HA more-info statistics dialog
- Individual device display — top 3 devices by power consumption shown on desktop with arced connections to house
- SEM color scheme on flows — pink battery charge, teal discharge, purple grid export, blue import
- Time-based sun position — sun moves along arc from sunrise to sunset, moon + stars at night
- K-Flow option —
diagram_style: "kflow"config option to use K-Flow card instead - Self-consumption % added to home tab header as 4th stat
- Dynamic tariff cost fix (#218) — incremental cost accumulation instead of total ×ばつ rate
- Load management UX (#219) — translations, power formatting, HA entity icons for devices
- Enhanced diagnostics — system info, source sensors, sign convention in diagnostic dump
- Per-charger connected status — each charger reads its own plug sensor independently (no more all-connected when one car is plugged in)
- Per-charger vehicle SOC — configure
vehicle_soc_entityper charger for real car battery percentage - Per-charger night charging — independent targets, switches, start/min amps per charger
- Per-charger notifications — nearly full, skip, charge recommended fire per-charger with charger name
- Per-charger dashboard — EV status card shows connected status, SOC gauge, metrics per charger
- Surplus distribution — priority-based power allocation across chargers
- 759 translation keys across 15 languages (was 606)
- Cross-layer translation — Python sensor values with
{tomorrow}placeholders translated at card level - Peak management translated — status, recommendation, and zone names
- Chart period labels translated — "Last 24h", "This Week" etc.
- Grid mode translated — "combined"/"split" in system info card
- Tariff rates accept zero — import/export rates can be set to 0.00 for free electricity or net metering
- Switchable device count — only counts devices that are currently ON (was counting all configured)
- Peak time formatting — Solcast ISO timestamp converted to HH:MM local time
- Binary sensor prefix fix — 4 sensors (solar_active, battery_charging, etc.) were permanently False
- Strategy text readability — increased font size in EV card
- Contract tests — entity-key contract tests prevent future key mismatches
- N charger support — configure and control multiple EV chargers with priority-based surplus distribution
- Priority cascade — highest-priority charger gets power first, remainder flows to next if above minimum threshold
- Per-charger state — independent stall detection, enable/disable delays, session tracking, taper detection
- Night target split — overnight charging target distributed equally across connected chargers
- Config flow — add/remove chargers via options flow, auto-discovery of all charger brands
- Dashboard — per-charger status table when >1 charger, "(N chargers)" subtitle on flow diagram
- Backward compatible — single-charger configs auto-migrate with zero user effort
- "EV nearly full" — push notification when taper detection shows < 5 minutes to full
- "Night charge skipped" — notification when SOC is sufficient, showing estimated range
- "Charge recommended" — notification when SOC drops below 30% during night window
- All three use deduplication (fire once per event, reset automatically)
- SG-Ready 4-state control — BLOCKED (1:0), NORMAL (0:0), BOOST (0:1), FORCE_ON (1:1) via two relay entities. (This line originally documented a plain 2-bit count, 00/01/10/11, which is not the SG-Ready standard — corrected in #523 in the code and in #655 here.)
- Surplus-driven — BOOST mode activates on solar surplus, FORCE_ON on high surplus (configurable threshold)
- Temperature boost — optionally raises climate entity setpoint during surplus periods
- Config flow — new Heat Pump step in options flow (relay1, relay2, climate, power sensor, priority)
- All costs now use HA-configured currency — no more hardcoded CHF
- Dashboard JS cards, YAML templates, chart presets, and sensor definitions all read from
Settings > General > Currency
- Three tariff modes exposed in options flow: Static (fixed HT/NT), Dynamic (Tibber/Nordpool/aWATTar/Amber Electric/Octopus Energy), Calendar (time-based schedule)
- Auto-detection — SEM scans for Tibber/Nordpool/aWATTar/Amber Electric/Octopus Energy entities when dynamic mode is selected
- Price-responsive surplus — dynamic mode enables price-aware device activation during cheap/negative price windows
- Troubleshooting guide for GoodWe + Easee setup (Energy Dashboard configuration, sign convention auto-detection)
- Setup guide note for GoodWe inverters
- Added: Portuguese (pt), Polish (pl), Swedish (sv), Czech (cs), Danish (da), Finnish (fi), Hungarian (hu), Romanian (ro), Norwegian (no)
- Was 6 (de, en, es, fr, it, nl), now 15
- EV Intelligence: taper detection, virtual SOC, consumption learning, smart night charge skip, battery health
- Multi-device read aggregation: sum inverters, batteries, grid tariffs from Energy Dashboard
- Smart Night Charging rename, 1,000+ tests
- Dashboard Lumina redesign — glassmorphism theme, SVG glow icons, battery hero card, EV status card
- Auto card installation — JS files auto-installed to
/config/www/on restart - Device control modes —
off,peak_only,surplusper device - Tariff calendar — user-defined HT/NT time windows with Swiss provider presets
- Performance, stability, usability, accessibility, and code quality improvements (see v1.0.4 changelog)
SEM is free and open-source. If it saves you money on your energy bill, consider buying the developer a coffee:
Your support helps keep SEM maintained, tested on real hardware, and free for everyone.
Contributions are welcome! Fork the repo, branch, and open a PR against
develop. Read CONTRIBUTING.md first — the PR template's
checklist is exactly what the review holds you to.
Every open issue and PR carries a state label, mirrored onto a maintainer project board. The label is the source of truth — it is on the issue itself, so you can always see the state of anything you reported without needing access to the board.
| State | Meaning |
|---|---|
| Soaking | Fix released as a beta, running on real hardware pending confirmation |
| Queued | Diagnosed, scheduled for work |
| Awaiting reporter | Waiting on logs, data or a confirmation from the reporter |
| Parked | Enhancement held until after the next stable release |
| In review / Changes requested / Ready to merge | Pull request states |
- Bug reports are triaged, fixed and released as a beta; the reporter is then asked to confirm.
- Enhancement requests are labelled and scheduled by a maintainer.
- Pull requests are reviewed against the project's invariants. Merging is a maintainer decision.
- A comment on a closed issue reopens it.
- An issue awaiting a reporter is nudged after 3 days, and closed with an invitation to reopen after 7.
Soaking 2.0 on real hardware: bug fixes are reviewed and merged as usual; feature PRs are parked until the stable release is cut.
MIT License — see LICENSE for details.