From ee7dd329f04c3fedc49a03e1821796a30c38aadb Mon Sep 17 00:00:00 2001 From: Galorhallen <12990764+Galorhallen@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:08:02 +0100 Subject: [PATCH] Update and fix govee light local (#166454) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../govee_light_local/coordinator.py | 2 +- .../components/govee_light_local/light.py | 14 ++++- .../govee_light_local/test_light.py | 62 +++++++++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/govee_light_local/coordinator.py b/homeassistant/components/govee_light_local/coordinator.py index a03e24fabb8..d64b95ea777 100644 --- a/homeassistant/components/govee_light_local/coordinator.py +++ b/homeassistant/components/govee_light_local/coordinator.py @@ -98,7 +98,7 @@ class GoveeLocalApiCoordinator(DataUpdateCoordinator[list[GoveeDevice]]): """Set light color in kelvin.""" await device.set_temperature(temperature) - async def set_scene(self, device: GoveeController, scene: str) -> None: + async def set_scene(self, device: GoveeDevice, scene: str) -> None: """Set light scene.""" await device.set_scene(scene) diff --git a/homeassistant/components/govee_light_local/light.py b/homeassistant/components/govee_light_local/light.py index c33b73e0d4a..0f6ec98814a 100644 --- a/homeassistant/components/govee_light_local/light.py +++ b/homeassistant/components/govee_light_local/light.py @@ -80,7 +80,6 @@ class GoveeLight(CoordinatorEntity[GoveeLocalApiCoordinator], LightEntity): super().__init__(coordinator) self._device = device - device.set_update_callback(self._update_callback) self._attr_unique_id = device.fingerprint @@ -194,9 +193,20 @@ class GoveeLight(CoordinatorEntity[GoveeLocalApiCoordinator], LightEntity): await self.coordinator.turn_off(self._device) self.async_write_ha_state() + async def async_added_to_hass(self) -> None: + """Register update callback when entity is added.""" + await super().async_added_to_hass() + self._device.set_update_callback(self._update_callback) + + async def async_will_remove_from_hass(self) -> None: + """Unregister update callback when entity is removed.""" + self._device.set_update_callback(None) + await super().async_will_remove_from_hass() + @callback def _update_callback(self, device: GoveeDevice) -> None: - self.async_write_ha_state() + if self.hass: + self.async_write_ha_state() def _save_last_color_state(self) -> None: color_mode = self.color_mode diff --git a/tests/components/govee_light_local/test_light.py b/tests/components/govee_light_local/test_light.py index b5e06e4fd69..6ea36766c82 100644 --- a/tests/components/govee_light_local/test_light.py +++ b/tests/components/govee_light_local/test_light.py @@ -631,6 +631,68 @@ async def test_scene_restore_temperature( assert light.attributes["color_temp_kelvin"] == initial_color +async def test_update_callback_registered_and_triggers_state_update( + hass: HomeAssistant, mock_govee_api: MagicMock +) -> None: + """Test that update callback is registered and triggers state update.""" + device = GoveeDevice( + controller=mock_govee_api, + ip="192.168.1.100", + fingerprint="asdawdqwdqwd", + sku="H615A", + capabilities=DEFAULT_CAPABILITIES, + ) + mock_govee_api.devices = [device] + + entry = MockConfigEntry(domain=DOMAIN) + entry.add_to_hass(hass) + + assert await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + assert device.update_callback is not None + + light = hass.states.get("light.H615A") + assert light is not None + assert light.state == "off" + + # Mutate device state and fire callback + await device.turn_on() + device.update_callback(device) + await hass.async_block_till_done() + + light = hass.states.get("light.H615A") + assert light is not None + assert light.state == "on" + + +async def test_update_callback_cleared_on_remove( + hass: HomeAssistant, mock_govee_api: MagicMock +) -> None: + """Test that update callback is cleared when entity is removed.""" + device = GoveeDevice( + controller=mock_govee_api, + ip="192.168.1.100", + fingerprint="asdawdqwdqwd", + sku="H615A", + capabilities=DEFAULT_CAPABILITIES, + ) + mock_govee_api.devices = [device] + + entry = MockConfigEntry(domain=DOMAIN) + entry.add_to_hass(hass) + + assert await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + assert device.update_callback is not None + + assert await hass.config_entries.async_remove(entry.entry_id) + await hass.async_block_till_done() + + assert device.update_callback is None + + async def test_scene_none(hass: HomeAssistant, mock_govee_api: MagicMock) -> None: """Test turn on 'none' scene."""