From 0b284bda4d457e316add4daef446823eeaf5f888 Mon Sep 17 00:00:00 2001 From: Constantin Pascal Date: Mon, 11 May 2026 23:30:27 +0300 Subject: [PATCH] Fix relay not turning off after integration restart On restart, pv_state resets to IDLE so the computed decision is always False on the first recalculate. Comparing against self.decision (also False) meant relay_control was never called, leaving the relay physically ON past the PV target and cut-off temperature limits. - Compare decision against the actual relay_on state instead of the coordinator's previous self.decision, so any discrepancy (including one left by a restart or an external integration) is corrected immediately on every recalculate. - Call _recalculate() at the end of async_setup() so the relay is synced on startup without waiting for an external state-change event. Co-Authored-By: Claude --- custom_components/boiler_aux_heater_3phase/coordinator.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/custom_components/boiler_aux_heater_3phase/coordinator.py b/custom_components/boiler_aux_heater_3phase/coordinator.py index 3eefea5..4730317 100644 --- a/custom_components/boiler_aux_heater_3phase/coordinator.py +++ b/custom_components/boiler_aux_heater_3phase/coordinator.py @@ -174,6 +174,10 @@ class BoilerAuxHeaterCoordinator: # B4: Restore persisted boost state await self._async_restore_boost_state() + # Sync relay to current decision immediately, without waiting for a + # state change event (handles relay left ON before a restart). + self._recalculate() + async def _async_restore_boost_state(self) -> None: """Restore bath boost state from storage after HA restart.""" data = await self._store.async_load() @@ -431,7 +435,6 @@ class BoilerAuxHeaterCoordinator: allowed = hp_aux_off and allow_usage and boiler_temp_ok # F1: Compute decision reason - old_decision = self.decision if manual_override: self.decision = True self.decision_reason = "Manual override" @@ -463,7 +466,7 @@ class BoilerAuxHeaterCoordinator: self.decision = False self.decision_reason = "OFF: No heating demand" - if self.decision != old_decision: + if self.decision != relay_on: self.hass.async_create_task(self._async_control_relay(self.decision)) self._notify_listeners()