mirror of
https://github.com/home-assistant/core.git
synced 2026-09-25 07:51:46 -05:00
Gate the Sofar waiting-ends sensor on an active countdown (#180605)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user