From 1bdbe90d2a410f4fee9c747870fc6b21cc74c2fb Mon Sep 17 00:00:00 2001 From: Alexei Chetroi Date: Mon, 8 Jun 2020 08:54:52 -0400 Subject: [PATCH] Prevent double ZHA channel initialization (#36554) * Preven double channel initialization. * Use a setter for setting ZHA device availability. --- homeassistant/components/zha/core/device.py | 11 ++++++----- homeassistant/components/zha/core/gateway.py | 8 ++++++-- homeassistant/components/zha/core/patches.py | 3 +-- homeassistant/components/zha/entity.py | 2 +- tests/components/zha/test_api.py | 6 +++--- tests/components/zha/test_fan.py | 6 +++--- tests/components/zha/test_gateway.py | 6 +++--- tests/components/zha/test_light.py | 8 ++++---- tests/components/zha/test_switch.py | 6 +++--- 9 files changed, 30 insertions(+), 26 deletions(-) diff --git a/homeassistant/components/zha/core/device.py b/homeassistant/components/zha/core/device.py index fcbf518a9db..918247f4f79 100644 --- a/homeassistant/components/zha/core/device.py +++ b/homeassistant/components/zha/core/device.py @@ -263,9 +263,14 @@ class ZHADevice(LogMixin): @property def available(self): - """Return True if sensor is available.""" + """Return True if device is available.""" return self._available + @available.setter + def available(self, new_availability: bool) -> None: + """Set device availability.""" + self._available = new_availability + @property def zigbee_signature(self) -> Dict[str, Any]: """Get zigbee signature for this device.""" @@ -274,10 +279,6 @@ class ZHADevice(LogMixin): ATTR_ENDPOINTS: self._channels.zigbee_signature, } - def set_available(self, available): - """Set availability from restore and prevent signals.""" - self._available = available - @classmethod def new( cls, diff --git a/homeassistant/components/zha/core/gateway.py b/homeassistant/components/zha/core/gateway.py index 08f412dfcd8..ff62aeeb68a 100644 --- a/homeassistant/components/zha/core/gateway.py +++ b/homeassistant/components/zha/core/gateway.py @@ -485,16 +485,20 @@ class ZHAGateway: self, sender, profile, cluster, src_ep, dst_ep, message ): """Handle tasks when a device becomes available.""" - self.async_update_device(sender) + self.async_update_device(sender, available=True) @callback - def async_update_device(self, sender: zigpy_dev.Device, available: bool = True): + def async_update_device( + self, sender: zigpy_dev.Device, available: bool = True + ) -> None: """Update device that has just become available.""" if sender.ieee in self.devices: device = self.devices[sender.ieee] # avoid a race condition during new joins if device.status is DeviceStatus.INITIALIZED: device.update_available(available) + else: + device.available = available async def async_update_device_storage(self): """Update the devices in the store.""" diff --git a/homeassistant/components/zha/core/patches.py b/homeassistant/components/zha/core/patches.py index 3d8c84e9bf3..633152e253c 100644 --- a/homeassistant/components/zha/core/patches.py +++ b/homeassistant/components/zha/core/patches.py @@ -7,8 +7,7 @@ def apply_application_controller_patch(zha_gateway): def handle_message(sender, profile, cluster, src_ep, dst_ep, message): """Handle message from a device.""" if ( - not sender.initializing - and sender.ieee in zha_gateway.devices + sender.ieee in zha_gateway.devices and not zha_gateway.devices[sender.ieee].available ): zha_gateway.async_device_became_available( diff --git a/homeassistant/components/zha/entity.py b/homeassistant/components/zha/entity.py index 8629fc50075..c9faca921a7 100644 --- a/homeassistant/components/zha/entity.py +++ b/homeassistant/components/zha/entity.py @@ -211,7 +211,7 @@ class ZhaEntity(BaseZhaEntity, RestoreEntity): if not self.zha_device.is_mains_powered: # mains powered devices will get real time state self.async_restore_last_state(last_state) - self._zha_device.set_available(True) + self._zha_device.available = True async def async_update(self) -> None: """Retrieve latest state.""" diff --git a/tests/components/zha/test_api.py b/tests/components/zha/test_api.py index 88fd1e8437f..0587bd14c8c 100644 --- a/tests/components/zha/test_api.py +++ b/tests/components/zha/test_api.py @@ -42,7 +42,7 @@ async def device_switch(hass, zigpy_device_mock, zha_device_joined): ieee=IEEE_SWITCH_DEVICE, ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device @@ -65,7 +65,7 @@ async def device_groupable(hass, zigpy_device_mock, zha_device_joined): ieee=IEEE_GROUPABLE_DEVICE, ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device @@ -266,7 +266,7 @@ async def test_list_groupable_devices(zha_client, device_groupable): # Make sure there are no groupable devices when the device is unavailable # Make device unavailable - device_groupable.set_available(False) + device_groupable.available = False await zha_client.send_json({ID: 11, TYPE: "zha/devices/groupable"}) diff --git a/tests/components/zha/test_fan.py b/tests/components/zha/test_fan.py index 91819e6f457..6aca57091fd 100644 --- a/tests/components/zha/test_fan.py +++ b/tests/components/zha/test_fan.py @@ -65,7 +65,7 @@ async def coordinator(hass, zigpy_device_mock, zha_device_joined): node_descriptor=b"\xf8\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device @@ -83,7 +83,7 @@ async def device_fan_1(hass, zigpy_device_mock, zha_device_joined): ieee=IEEE_GROUPABLE_DEVICE, ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device @@ -105,7 +105,7 @@ async def device_fan_2(hass, zigpy_device_mock, zha_device_joined): ieee=IEEE_GROUPABLE_DEVICE2, ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device diff --git a/tests/components/zha/test_gateway.py b/tests/components/zha/test_gateway.py index 379e4d56492..37f4424d7b8 100644 --- a/tests/components/zha/test_gateway.py +++ b/tests/components/zha/test_gateway.py @@ -58,7 +58,7 @@ async def coordinator(hass, zigpy_device_mock, zha_device_joined): node_descriptor=b"\xf8\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device @@ -82,7 +82,7 @@ async def device_light_1(hass, zigpy_device_mock, zha_device_joined): ieee=IEEE_GROUPABLE_DEVICE, ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device @@ -106,7 +106,7 @@ async def device_light_2(hass, zigpy_device_mock, zha_device_joined): ieee=IEEE_GROUPABLE_DEVICE2, ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device diff --git a/tests/components/zha/test_light.py b/tests/components/zha/test_light.py index 09c6d97808c..89f920bf40d 100644 --- a/tests/components/zha/test_light.py +++ b/tests/components/zha/test_light.py @@ -88,7 +88,7 @@ async def coordinator(hass, zigpy_device_mock, zha_device_joined): node_descriptor=b"\xf8\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device @@ -114,7 +114,7 @@ async def device_light_1(hass, zigpy_device_mock, zha_device_joined): nwk=0xB79D, ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device @@ -140,7 +140,7 @@ async def device_light_2(hass, zigpy_device_mock, zha_device_joined): nwk=0xC79E, ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device @@ -166,7 +166,7 @@ async def device_light_3(hass, zigpy_device_mock, zha_device_joined): nwk=0xB89F, ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device diff --git a/tests/components/zha/test_switch.py b/tests/components/zha/test_switch.py index 7bdf2ccc4d2..7f95829af12 100644 --- a/tests/components/zha/test_switch.py +++ b/tests/components/zha/test_switch.py @@ -56,7 +56,7 @@ async def coordinator(hass, zigpy_device_mock, zha_device_joined): node_descriptor=b"\xf8\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device @@ -75,7 +75,7 @@ async def device_switch_1(hass, zigpy_device_mock, zha_device_joined): ieee=IEEE_GROUPABLE_DEVICE, ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device @@ -94,7 +94,7 @@ async def device_switch_2(hass, zigpy_device_mock, zha_device_joined): ieee=IEEE_GROUPABLE_DEVICE2, ) zha_device = await zha_device_joined(zigpy_device) - zha_device.set_available(True) + zha_device.available = True return zha_device