Gate the Sofar waiting-ends sensor on an active countdown (#180605)

This commit is contained in:
darkrain-nl
2026-08-29 13:10:56 +02:00
committed by GitHub
parent d8c3a5dd0b
commit 754691c5d6
2 changed files with 39 additions and 1 deletions
+9 -1
View File
@@ -7,6 +7,7 @@ from enum import IntEnum
from typing import cast, override
from sofar_modbus.modern.device import SofarInverter
from sofar_modbus.modern.enums import SystemState
from homeassistant.components.sensor import (
RestoreSensor,
@@ -142,6 +143,9 @@ class SofarSensor(SofarEntity, SensorEntity):
class SofarCountdownSensor(SofarSensor):
"""Defines a Sofar countdown, published as the moment it runs out."""
# A positive register alone doesn't mean the countdown is active.
_ACTIVE_STATES = (SystemState.WAITING, SystemState.CHECKING)
def __init__(
self,
runtime_data: SofarRuntimeData,
@@ -156,7 +160,11 @@ class SofarCountdownSensor(SofarSensor):
def native_value(self) -> datetime | None:
component = getattr(self.coordinator.device, self.entity_description.component)
seconds = getattr(component, self.entity_description.key)
if not isinstance(seconds, int) or seconds <= 0:
if (
not isinstance(seconds, int)
or seconds <= 0
or component.system_state not in self._ACTIVE_STATES
):
# A restart must not land inside the finished countdown's slack.
self._deadline = _deadline_filter()
return None
+30
View File
@@ -426,6 +426,7 @@ async def test_countdown_holds_its_deadline_until_it_restarts(
"""Test a countdown ticking with the clock keeps one deadline."""
mock_config_entry.add_to_hass(hass)
unit = mock_connection.for_unit(1)
unit.holding[0x0404] = 0 # Waiting
unit.holding[0x0417] = 300
with patch(
@@ -460,6 +461,34 @@ async def test_countdown_holds_its_deadline_until_it_restarts(
assert hass.states.get(entity_id).state != deadline
async def test_countdown_ignores_a_stale_register_while_grid_connected(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_connection: MockModbusConnection,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test a positive register is ignored once the inverter is connected."""
mock_config_entry.add_to_hass(hass)
unit = mock_connection.for_unit(1)
unit.holding[0x0404] = 2 # Grid connected
unit.holding[0x0417] = 60 # Left over from the last startup wait
with patch(
"homeassistant.components.sofar.async_get_unit",
side_effect=lambda hass, entry, params, unit_id: mock_connection.for_unit(
unit_id
),
):
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done(wait_background_tasks=True)
entity_id = entity_registry.async_get_entity_id(
SENSOR_DOMAIN, DOMAIN, f"{MOCK_SERIAL}_waiting_time"
)
assert entity_id is not None
assert hass.states.get(entity_id).state == STATE_UNKNOWN
async def test_countdown_restarting_after_idle_gets_a_new_deadline(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
@@ -470,6 +499,7 @@ async def test_countdown_restarting_after_idle_gets_a_new_deadline(
"""Test a finished countdown's deadline is not reused by the next one."""
mock_config_entry.add_to_hass(hass)
unit = mock_connection.for_unit(1)
unit.holding[0x0404] = 0 # Waiting
unit.holding[0x0417] = 10
with patch(