From b859d9eb4cc6129c14c4b8b0908806da169c12b4 Mon Sep 17 00:00:00 2001 From: Andrew Blackburn Date: Thu, 8 Oct 2026 16:30:49 +0100 Subject: [PATCH] fix: refresh system binary sensor states --- custom_components/wiser/binary_sensor.py | 11 +++-- tests/test_sensor.py | 60 ++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/custom_components/wiser/binary_sensor.py b/custom_components/wiser/binary_sensor.py index 1bf87af9..60d87fab 100644 --- a/custom_components/wiser/binary_sensor.py +++ b/custom_components/wiser/binary_sensor.py @@ -404,10 +404,13 @@ def __init__(self, coordinator, device_id=0, sensor_type="") -> None: def _handle_coordinator_update(self) -> None: """Handle updated data from the coordinator.""" _LOGGER.debug(f"{self._sensor_type} device update requested") - HeatHub = self._data.wiserhub.system.name - HeatHub = HeatHub.replace("WiserHeat","HeatHub") - return f"{HeatHub} {self._sensor_type}" - + self._state = getattr( + self._data.wiserhub.system, + self._sensor_type.replace(" ", "_").lower(), + None, + ) + self.async_write_ha_state() + @property def is_on(self): """Return the state of the sensor.""" diff --git a/tests/test_sensor.py b/tests/test_sensor.py index f46320db..37b13a69 100644 --- a/tests/test_sensor.py +++ b/tests/test_sensor.py @@ -536,6 +536,66 @@ def guard_for(function_name: str) -> ast.If: self.assertIsNotNone(cleanup_call) +class WiserSystemBinarySensorUpdateTest(unittest.TestCase): + """Tests for coordinator updates to system binary sensors.""" + + @classmethod + def setUpClass(cls) -> None: + source = BINARY_SENSOR_SOURCE_PATH.read_text().split( + "class RoomBinarySensor", 1 + )[0] + tree = ast.parse(source) + system_class = next( + node + for node in tree.body + if isinstance(node, ast.ClassDef) + and node.name == "SystemBinarySensor" + ) + update_method = next( + node + for node in system_class.body + if isinstance(node, ast.FunctionDef) + and node.name == "_handle_coordinator_update" + ) + update_method.decorator_list = [] + namespace = {"_LOGGER": Mock()} + exec( + compile( + ast.Module(body=[update_method], type_ignores=[]), + BINARY_SENSOR_SOURCE_PATH.name, + "exec", + ), + namespace, + ) + cls.handle_update = staticmethod(namespace["_handle_coordinator_update"]) + + def setUp(self) -> None: + self.sensor = SimpleNamespace( + _data=SimpleNamespace( + wiserhub=SimpleNamespace( + system=SimpleNamespace(summer_comfort_available=False) + ) + ), + _sensor_type="Summer Comfort Available", + _state=True, + async_write_ha_state=Mock(), + ) + + def test_coordinator_update_refreshes_state(self) -> None: + self.handle_update(self.sensor) + + self.assertFalse(self.sensor._state) + self.sensor.async_write_ha_state.assert_called_once_with() + + def test_missing_property_sets_unknown_state(self) -> None: + self.sensor._data.wiserhub.system = SimpleNamespace() + + self.handle_update(self.sensor) + + self.assertIsNone(self.sensor._state) + self.sensor.async_write_ha_state.assert_called_once_with() + + class WiserDeviceSignalSensorNameTest(unittest.TestCase): """Tests for controller and device signal sensor names."""