Consolidate update parameters

This commit is contained in:
sdb9696 2024-06-29 08:28:18 +01:00
parent ec1082a228
commit 00bf59be6c
6 changed files with 31 additions and 21 deletions

View File

@ -233,8 +233,18 @@ class Device(ABC):
return await connect(host=host, config=config) # type: ignore[arg-type] return await connect(host=host, config=config) # type: ignore[arg-type]
@abstractmethod @abstractmethod
async def update(self, update_children: bool = True, update_parent: bool = True): async def update(self, update_children_or_parent: bool = True):
"""Update the device.""" """Update the device.
Must be called after updating any attributes for the state changes
to be reflected on the device.
:param update_children_or_parent: On a parent device when true will
call update on all the child devices. On a child device when true
will also update the parent device. Setting to false requires
knowledge of the inner workings of the library and should be used
with caution.
"""
async def disconnect(self): async def disconnect(self):
"""Disconnect and close any underlying connection resources.""" """Disconnect and close any underlying connection resources."""

View File

@ -283,7 +283,7 @@ class IotDevice(Device):
"""Retrieve system information.""" """Retrieve system information."""
return await self._query_helper("system", "get_sysinfo") return await self._query_helper("system", "get_sysinfo")
async def update(self, update_children: bool = True): async def update(self, update_children_or_parent: bool = True):
"""Query the device to update the data. """Query the device to update the data.
Needed for properties that are decorated with `requires_update`. Needed for properties that are decorated with `requires_update`.

View File

@ -121,12 +121,12 @@ class IotStrip(IotDevice):
"""Return if any of the outlets are on.""" """Return if any of the outlets are on."""
return any(plug.is_on for plug in self.children) return any(plug.is_on for plug in self.children)
async def update(self, update_children: bool = True, update_parent: bool = True): async def update(self, update_children_or_parent: bool = True):
"""Update some of the attributes. """Update some of the attributes.
Needed for methods that are decorated with `requires_update`. Needed for methods that are decorated with `requires_update`.
""" """
await self._update(update_children) await self._update(update_children_or_parent)
async def _update( async def _update(
self, self,
@ -368,13 +368,13 @@ class IotStripPlug(IotPlug):
for module_feat in module._module_features.values(): for module_feat in module._module_features.values():
self._add_feature(module_feat) self._add_feature(module_feat)
async def update(self, update_children: bool = True, update_parent: bool = True): async def update(self, update_children_or_parent: bool = True):
"""Query the device to update the data. """Query the device to update the data.
Needed for properties that are decorated with `requires_update`. Needed for properties that are decorated with `requires_update`.
""" """
if update_parent: if update_children_or_parent:
await self.parent._update(update_children=False, called_from_child=self) await self.parent._update(called_from_child=self)
else: else:
await self._update() await self._update()

View File

@ -36,14 +36,14 @@ class SmartChildDevice(SmartDevice):
self._id = info["device_id"] self._id = info["device_id"]
self.protocol = _ChildProtocolWrapper(self._id, parent.protocol) self.protocol = _ChildProtocolWrapper(self._id, parent.protocol)
async def update(self, update_children: bool = True, update_parent: bool = True): async def update(self, update_children_or_parent: bool = True):
"""Update the device. """Update the device.
Calling update directly on a child device will update the parent Calling update directly on a child device will update the parent
and only this child. and only this child.
""" """
if update_parent: if update_children_or_parent:
await self._parent._update(update_children=False, called_from_child=self) await self._parent._update(called_from_child=self)
else: else:
await self._update() await self._update()

View File

@ -147,9 +147,9 @@ class SmartDevice(Device):
if "child_device" in self._components and not self.children: if "child_device" in self._components and not self.children:
await self._initialize_children() await self._initialize_children()
async def update(self, update_children: bool = True, update_parent: bool = True): async def update(self, update_children_or_parent: bool = True):
"""Update the device.""" """Update the device."""
await self._update(update_children) await self._update(update_children_or_parent)
async def _update( async def _update(
self, update_children: bool = True, called_from_child: SmartDevice | None = None self, update_children: bool = True, called_from_child: SmartDevice | None = None

View File

@ -120,29 +120,29 @@ async def test_device_updates(dev: Device, mocker: MockerFixture):
parent_spy = mocker.spy(dev, "_update") parent_spy = mocker.spy(dev, "_update")
child_spies = {child: mocker.spy(child, "_update") for child in dev.children} child_spies = {child: mocker.spy(child, "_update") for child in dev.children}
# update children # update children, all devices call update
await dev.update(update_children=True) await dev.update(update_children_or_parent=True)
parent_spy.assert_called_once() parent_spy.assert_called_once()
for child_spy in child_spies.values(): for child_spy in child_spies.values():
child_spy.assert_called_once() child_spy.assert_called_once()
# do not update children # do not update children, only parent calls update
parent_spy.reset_mock() parent_spy.reset_mock()
for child_spy in child_spies.values(): for child_spy in child_spies.values():
child_spy.reset_mock() child_spy.reset_mock()
await dev.update(update_children=False) await dev.update(update_children_or_parent=False)
parent_spy.assert_called_once() parent_spy.assert_called_once()
for child_spy in child_spies.values(): for child_spy in child_spies.values():
child_spy.assert_not_called() child_spy.assert_not_called()
# update parent # update parent, only the parent and one child call update
parent_spy.reset_mock() parent_spy.reset_mock()
for child_spy in child_spies.values(): for child_spy in child_spies.values():
child_spy.reset_mock() child_spy.reset_mock()
child_to_update = dev.children[0] child_to_update = dev.children[0]
await child_to_update.update(update_parent=True) await child_to_update.update(update_children_or_parent=True)
parent_spy.assert_called_once() parent_spy.assert_called_once()
assert child_to_update assert child_to_update
for child, child_spy in child_spies.items(): for child, child_spy in child_spies.items():
@ -151,12 +151,12 @@ async def test_device_updates(dev: Device, mocker: MockerFixture):
else: else:
child_spy.assert_not_called() child_spy.assert_not_called()
# do not update parent # do not update parent, only the one child calls update
parent_spy.reset_mock() parent_spy.reset_mock()
for child_spy in child_spies.values(): for child_spy in child_spies.values():
child_spy.reset_mock() child_spy.reset_mock()
await child_to_update.update(update_parent=False) await child_to_update.update(update_children_or_parent=False)
parent_spy.assert_not_called() parent_spy.assert_not_called()
assert child_to_update assert child_to_update
for child, child_spy in child_spies.items(): for child, child_spy in child_spies.items():