From 3dd1fadc7ddff4d5f3723ebbc8507fbf11d375a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Diego=20Rodr=C3=ADguez=20Royo?= <jdrr1998@hotmail.com> Date: Fri, 7 Mar 2025 01:50:06 +0100 Subject: [PATCH] Check operation state on Home Connect program sensor update (#140011) Check operation state on program sensor update --- .../components/home_connect/sensor.py | 7 ++ tests/components/home_connect/test_sensor.py | 82 ++++++++++++++++++- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/home_connect/sensor.py b/homeassistant/components/home_connect/sensor.py index 924744ded56..c12e1b7b6e4 100644 --- a/homeassistant/components/home_connect/sensor.py +++ b/homeassistant/components/home_connect/sensor.py @@ -386,6 +386,13 @@ class HomeConnectProgramSensor(HomeConnectSensor): def update_native_value(self) -> None: """Update the program sensor's status.""" + self.program_running = ( + status := self.appliance.status.get(StatusKey.BSH_COMMON_OPERATION_STATE) + ) is not None and status.value in [ + BSH_OPERATION_STATE_RUN, + BSH_OPERATION_STATE_PAUSE, + BSH_OPERATION_STATE_FINISHED, + ] event = self.appliance.events.get(cast(EventKey, self.bsh_key)) if event: self._update_native_value(event.value) diff --git a/tests/components/home_connect/test_sensor.py b/tests/components/home_connect/test_sensor.py index 31fc9ea6d3f..04f5e056aa5 100644 --- a/tests/components/home_connect/test_sensor.py +++ b/tests/components/home_connect/test_sensor.py @@ -27,7 +27,7 @@ from homeassistant.components.home_connect.const import ( DOMAIN, ) from homeassistant.config_entries import ConfigEntryState -from homeassistant.const import STATE_UNAVAILABLE, Platform +from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr, entity_registry as er @@ -302,7 +302,7 @@ ENTITY_ID_STATES = { ) ), ) -async def test_event_sensors( +async def test_program_sensors( client: MagicMock, appliance_ha_id: str, states: tuple, @@ -313,7 +313,7 @@ async def test_event_sensors( integration_setup: Callable[[MagicMock], Awaitable[bool]], setup_credentials: None, ) -> None: - """Test sequence for sensors that are only available after an event happens.""" + """Test sequence for sensors that expose information about a program.""" entity_ids = ENTITY_ID_STATES.keys() time_to_freeze = "2021-01-09 12:00:00+00:00" @@ -358,6 +358,82 @@ async def test_event_sensors( assert hass.states.is_state(entity_id, state) +@pytest.mark.parametrize("appliance_ha_id", [TEST_HC_APP], indirect=True) +@pytest.mark.parametrize( + ("initial_operation_state", "initial_state", "event_order", "entity_states"), + [ + ( + "BSH.Common.EnumType.OperationState.Ready", + STATE_UNAVAILABLE, + (EventType.STATUS, EventType.EVENT), + (STATE_UNKNOWN, "60"), + ), + ( + "BSH.Common.EnumType.OperationState.Run", + STATE_UNKNOWN, + (EventType.EVENT, EventType.STATUS), + ("60", "60"), + ), + ], +) +async def test_program_sensor_edge_case( + initial_operation_state: str, + initial_state: str, + event_order: tuple[EventType, EventType], + entity_states: tuple[str, str], + appliance_ha_id: str, + hass: HomeAssistant, + config_entry: MockConfigEntry, + integration_setup: Callable[[MagicMock], Awaitable[bool]], + setup_credentials: None, + client: MagicMock, +) -> None: + """Test edge case for the program related entities.""" + entity_id = "sensor.dishwasher_program_progress" + client.get_status = AsyncMock( + return_value=ArrayOfStatus( + [ + Status( + StatusKey.BSH_COMMON_OPERATION_STATE, + StatusKey.BSH_COMMON_OPERATION_STATE.value, + initial_operation_state, + ) + ] + ) + ) + + assert config_entry.state == ConfigEntryState.NOT_LOADED + assert await integration_setup(client) + assert config_entry.state == ConfigEntryState.LOADED + + assert hass.states.is_state(entity_id, initial_state) + + for event_type, state in zip(event_order, entity_states, strict=True): + await client.add_events( + [ + EventMessage( + appliance_ha_id, + event_type, + ArrayOfEvents( + [ + Event( + key=event_key, + raw_key=event_key.value, + timestamp=0, + level="", + handling="", + value=value, + ) + ], + ), + ) + for event_key, value in EVENT_PROG_RUN[event_type].items() + ] + ) + await hass.async_block_till_done() + assert hass.states.is_state(entity_id, state) + + # Program sequence for SensorDeviceClass.TIMESTAMP edge cases. PROGRAM_SEQUENCE_EDGE_CASE = [ EVENT_PROG_DELAYED_START, -- GitLab