diff --git a/CHANGELOG.md b/CHANGELOG.md index 90190a3a9..e11edc4f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Ongoing - PR [319](https://github.com/plugwise/python-plugwise-usb/pull/319): Replace unclear warning message when a node is not online, also various small improvements suggested by CRAI. +- PR [312](https://github.com/plugwise/python-plugwise-usb/pull/312): properly propagate configuration changes and initialize to available on first node wakeup ## v0.44.11 - 2025-08-14 diff --git a/plugwise_usb/nodes/scan.py b/plugwise_usb/nodes/scan.py index f97ddc26a..fc3e84c46 100644 --- a/plugwise_usb/nodes/scan.py +++ b/plugwise_usb/nodes/scan.py @@ -102,8 +102,8 @@ async def load(self) -> None: await super().load() self._setup_protocol(SCAN_FIRMWARE_SUPPORT, SCAN_FEATURES) - await self.initialize() await self._loaded_callback(NodeEvent.LOADED, self.mac) + await self.initialize() async def initialize(self) -> None: """Initialize Scan node.""" @@ -426,6 +426,10 @@ async def _run_awake_tasks(self) -> None: await super()._run_awake_tasks() if self._motion_config.dirty: await self._configure_scan_task() + await self.publish_feature_update_to_subscribers( + NodeFeature.MOTION_CONFIG, + self._motion_config, + ) async def _configure_scan_task(self) -> bool: """Configure Scan device settings. Returns True if successful.""" diff --git a/plugwise_usb/nodes/sed.py b/plugwise_usb/nodes/sed.py index aab5615ae..acf3b81cc 100644 --- a/plugwise_usb/nodes/sed.py +++ b/plugwise_usb/nodes/sed.py @@ -237,12 +237,15 @@ async def set_awake_duration(self, seconds: int) -> bool: raise ValueError( f"Invalid awake duration ({seconds}). It must be between 1 and 255 seconds." ) + if self._battery_config.awake_duration == seconds: + return False self._battery_config = replace( self._battery_config, awake_duration=seconds, dirty=True, ) + await self._sed_configure_update() return True async def set_clock_interval(self, minutes: int) -> bool: @@ -264,6 +267,7 @@ async def set_clock_interval(self, minutes: int) -> bool: self._battery_config = replace( self._battery_config, clock_interval=minutes, dirty=True ) + await self._sed_configure_update() return True async def set_clock_sync(self, sync: bool) -> bool: @@ -280,6 +284,7 @@ async def set_clock_sync(self, sync: bool) -> bool: self._battery_config = replace( self._battery_config, clock_sync=sync, dirty=True ) + await self._sed_configure_update() return True async def set_maintenance_interval(self, minutes: int) -> bool: @@ -301,6 +306,7 @@ async def set_maintenance_interval(self, minutes: int) -> bool: self._battery_config = replace( self._battery_config, maintenance_interval=minutes, dirty=True ) + await self._sed_configure_update() return True async def set_sleep_duration(self, minutes: int) -> bool: @@ -325,6 +331,7 @@ async def set_sleep_duration(self, minutes: int) -> bool: self._battery_config = replace( self._battery_config, sleep_duration=minutes, dirty=True ) + await self._sed_configure_update() return True # endregion diff --git a/tests/test_usb.py b/tests/test_usb.py index cfef1353e..2c0917bc6 100644 --- a/tests/test_usb.py +++ b/tests/test_usb.py @@ -2000,14 +2000,14 @@ async def load_callback(event: pw_api.NodeEvent, mac: str) -> None: # type: ign awake_response2.timestamp = awake_response1.timestamp + td( seconds=pw_sed.AWAKE_RETRY ) - assert await test_sed.set_awake_duration(15) + assert await test_sed.set_awake_duration(20) assert test_sed.battery_config.dirty mock_stick_controller.send_response = sed_config_accepted await test_sed._awake_response(awake_response2) # pylint: disable=protected-access await asyncio.sleep(0.001) # Ensure time for task to be executed assert not test_sed.battery_config.dirty - assert test_sed.battery_config.awake_duration == 15 - assert test_sed.awake_duration == 15 + assert test_sed.battery_config.awake_duration == 20 + assert test_sed.awake_duration == 20 # test maintenance interval assert test_sed.maintenance_interval == 60