Summary
The published Sigenergy "mode-bridge" automation template (https://springfall2008.github.io/batpred/inverter-setup/) sets, for Freeze Charging:
number.sigen_plant_ess_charge_cut_off_state_of_charge → 100
number.sigen_plant_ess_discharge_cut_off_state_of_charge → 100
number.sigen_plant_grid_import_limitation → 0
On a real system (inverter mode Maximum Self Consumption, Predbat v8.46.9), this caused the battery to actively force-import from the grid at full peak price to chase the 100% discharge-cutoff floor, instead of just holding SoC in place as "Freeze Charging" implies. This happened twice in one evening, the second time for ~45 minutes at ~8-9kW import while the export rate was still one of the best of the day — a real, quantifiable financial loss, not a cosmetic bug.
Reproduction / evidence
input_select.predbat_requested_mode transitioned Demand → Freeze Charging (confirmed via automation_trace).
- Within ~5s,
discharge_cut_off_state_of_charge was set to 100 and predbat.status showed Hold for car.
sensor.<plant>_battery_power flipped from ‑8.0kW (discharging/exporting) to +8.0kW (charging) within 10 seconds of that write, and grid power flipped from ‑7.0kW (exporting) to +9.0kW (importing) — and held there continuously for the duration of the Freeze Charging state.
- Add-on log: repeating
Completed run status Hold for car / record_status Hold for car entries, one per ~5 min planning cycle, for the full duration.
- Reverting only
discharge_cut_off_state_of_charge (leaving everything else alone) immediately dropped the battery back to idle (‑0.004kW) — confirming the 100% discharge floor alone is sufficient to cause forced grid-charging in Maximum Self Consumption mode, independent of any import-limit setting.
Relation to #2872
This is a related but distinct symptom to #2872 ("Freeze Charge not working as expected - Sigenergy"). That issue found Maximum Self Consumption mode doesn't properly action ess_max_discharging_limit (a kW cap) — the inverter needs to be in a Command Charging/Discharging state for that write to take effect. Our system shows the opposite problem: the SoC cutoff register is honored in Maximum Self Consumption mode, and setting it to a hardcoded 100% (above current SoC) actively drives the inverter to import from the grid to reach it. #2872 was closed, but the published docs template still contains this exact pattern — the discussed workaround (switching EMS mode to Command Discharging (PV First) for Freeze Charging, and using the kW limit instead of the SoC cutoff) never made it into the docs page.
Suggested fix
Rather than switching EMS modes (which has its own state-machine caveats per #2872, and appears to need extra config enabled on the Sigenergy integration side), we fixed this by keeping Maximum Self Consumption mode and pinning both cutoffs to the battery's current SoC instead of a hardcoded extreme:
# Freeze Charging: hold current SoC as the charge ceiling, normal discharge floor
- conditions: [{condition: state, entity_id: input_select.predbat_requested_mode, state: "Freeze Charging"}]
sequence:
- action: number.set_value
data_template:
entity_id: number.sigen_plant_ess_charge_cut_off_state_of_charge
value: "{{ states('sensor.sigen_plant_battery_state_of_charge') | float(0) }}"
- action: number.set_value
data_template: {entity_id: number.sigen_plant_ess_discharge_cut_off_state_of_charge, value: 0}
# Freeze Discharging: hold current SoC as the discharge floor, normal charge ceiling
- conditions: [{condition: state, entity_id: input_select.predbat_requested_mode, state: "Freeze Discharging"}]
sequence:
- action: number.set_value
data_template: {entity_id: number.sigen_plant_ess_charge_cut_off_state_of_charge, value: 100}
- action: number.set_value
data_template:
entity_id: number.sigen_plant_ess_discharge_cut_off_state_of_charge
value: "{{ states('sensor.sigen_plant_battery_state_of_charge') | float(100) }}"
This directly implements "freeze at current level" semantics with a one-line template change per branch, no EMS mode switching required, and has been running live for several hours without recurrence of the forced-import behaviour. We think it may be a simpler and more robust fix than the #2872 workaround, but haven't tested that alternative ourselves — flagging both here for the maintainer to weigh in on which (or both) should go into the published template.
Also worth checking
The published template also sets number.sigen_plant_grid_import_limitation. That entity does not exist at all in our Sigenergy integration (confirmed via HA entity registry search and direct state lookup — 404). Our real number.sigen_plant_ess_* entities are only: ess_backup_state_of_charge, ess_charge_cut_off_state_of_charge, ess_discharge_cut_off_state_of_charge, ess_max_charging_limit, ess_max_discharging_limit. Not sure if this is integration-version drift, a naming difference (grid_export_limitation vs grid_import_limitation — #2872 uses the former), or an optional entity that needs enabling — but as written those number.set_value calls are silent no-ops for us, which could mask real problems for anyone else copying the template.
Environment
- Predbat: v8.46.9
- Inverter: Sigenergy SigenStor (
sigen integration)
- EMS mode used throughout:
Maximum Self Consumption
Summary
The published Sigenergy "mode-bridge" automation template (https://springfall2008.github.io/batpred/inverter-setup/) sets, for
Freeze Charging:number.sigen_plant_ess_charge_cut_off_state_of_charge→ 100number.sigen_plant_ess_discharge_cut_off_state_of_charge→ 100number.sigen_plant_grid_import_limitation→ 0On a real system (inverter mode
Maximum Self Consumption, Predbat v8.46.9), this caused the battery to actively force-import from the grid at full peak price to chase the 100% discharge-cutoff floor, instead of just holding SoC in place as "Freeze Charging" implies. This happened twice in one evening, the second time for ~45 minutes at ~8-9kW import while the export rate was still one of the best of the day — a real, quantifiable financial loss, not a cosmetic bug.Reproduction / evidence
input_select.predbat_requested_modetransitionedDemand→Freeze Charging(confirmed viaautomation_trace).discharge_cut_off_state_of_chargewas set to 100 andpredbat.statusshowedHold for car.sensor.<plant>_battery_powerflipped from ‑8.0kW (discharging/exporting) to +8.0kW (charging) within 10 seconds of that write, andgrid powerflipped from ‑7.0kW (exporting) to +9.0kW (importing) — and held there continuously for the duration of the Freeze Charging state.Completed run status Hold for car/record_status Hold for carentries, one per ~5 min planning cycle, for the full duration.discharge_cut_off_state_of_charge(leaving everything else alone) immediately dropped the battery back to idle (‑0.004kW) — confirming the 100% discharge floor alone is sufficient to cause forced grid-charging inMaximum Self Consumptionmode, independent of any import-limit setting.Relation to #2872
This is a related but distinct symptom to #2872 ("Freeze Charge not working as expected - Sigenergy"). That issue found
Maximum Self Consumptionmode doesn't properly actioness_max_discharging_limit(a kW cap) — the inverter needs to be in a Command Charging/Discharging state for that write to take effect. Our system shows the opposite problem: the SoC cutoff register is honored inMaximum Self Consumptionmode, and setting it to a hardcoded 100% (above current SoC) actively drives the inverter to import from the grid to reach it. #2872 was closed, but the published docs template still contains this exact pattern — the discussed workaround (switching EMS mode toCommand Discharging (PV First)for Freeze Charging, and using the kW limit instead of the SoC cutoff) never made it into the docs page.Suggested fix
Rather than switching EMS modes (which has its own state-machine caveats per #2872, and appears to need extra config enabled on the Sigenergy integration side), we fixed this by keeping
Maximum Self Consumptionmode and pinning both cutoffs to the battery's current SoC instead of a hardcoded extreme:This directly implements "freeze at current level" semantics with a one-line template change per branch, no EMS mode switching required, and has been running live for several hours without recurrence of the forced-import behaviour. We think it may be a simpler and more robust fix than the #2872 workaround, but haven't tested that alternative ourselves — flagging both here for the maintainer to weigh in on which (or both) should go into the published template.
Also worth checking
The published template also sets
number.sigen_plant_grid_import_limitation. That entity does not exist at all in our Sigenergy integration (confirmed via HA entity registry search and direct state lookup — 404). Our realnumber.sigen_plant_ess_*entities are only:ess_backup_state_of_charge,ess_charge_cut_off_state_of_charge,ess_discharge_cut_off_state_of_charge,ess_max_charging_limit,ess_max_discharging_limit. Not sure if this is integration-version drift, a naming difference (grid_export_limitationvsgrid_import_limitation— #2872 uses the former), or an optional entity that needs enabling — but as written thosenumber.set_valuecalls are silent no-ops for us, which could mask real problems for anyone else copying the template.Environment
sigenintegration)Maximum Self Consumption