Fix bug in ZHA and tweak non sensor channel logic (#21234)

* fix race condition and prevent profiles from stealing channels

* fix battery voltage
This commit is contained in:
David F. Mulcahey 2019-02-20 10:33:29 -05:00 committed by Pascal Vizeli
parent 5b24b271cc
commit cece6454e4
3 changed files with 23 additions and 10 deletions

View File

@ -199,4 +199,4 @@ class PowerConfigurationChannel(ZigbeeChannel):
await self.get_attribute_value(
'battery_percentage_remaining', from_cache=from_cache)
await self.get_attribute_value(
'active_power', from_cache=from_cache)
'battery_voltage', from_cache=from_cache)

View File

@ -5,6 +5,7 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/zha/
"""
import asyncio
from enum import Enum
import logging
from homeassistant.helpers.dispatcher import (
@ -23,6 +24,13 @@ from .channels.general import BasicChannel
_LOGGER = logging.getLogger(__name__)
class DeviceStatus(Enum):
"""Status of a device."""
CREATED = 1
INITIALIZED = 2
class ZHADevice:
"""ZHA Zigbee device object."""
@ -61,6 +69,7 @@ class ZHADevice:
self._zigpy_device.__class__.__name__
)
self.power_source = None
self.status = DeviceStatus.CREATED
@property
def name(self):
@ -186,6 +195,7 @@ class ZHADevice:
self.name,
BasicChannel.POWER_SOURCES.get(self.power_source)
)
self.status = DeviceStatus.INITIALIZED
_LOGGER.debug('%s: completed initialization', self.name)
async def _execute_channel_tasks(self, task_name, *args):

View File

@ -23,7 +23,7 @@ from .const import (
REPORT_CONFIG_ASAP, REPORT_CONFIG_DEFAULT, REPORT_CONFIG_MIN_INT,
REPORT_CONFIG_MAX_INT, REPORT_CONFIG_OP, SIGNAL_REMOVE, NO_SENSOR_CLUSTERS,
POWER_CONFIGURATION_CHANNEL)
from .device import ZHADevice
from .device import ZHADevice, DeviceStatus
from ..device_entity import ZhaDeviceEntity
from .channels import (
AttributeListeningChannel, EventRelayChannel, ZDOChannel
@ -139,7 +139,9 @@ class ZHAGateway:
"""Update device that has just become available."""
if sender.ieee in self.devices:
device = self.devices[sender.ieee]
device.update_available(True)
# avoid a race condition during new joins
if device.status is DeviceStatus.INITIALIZED:
device.update_available(True)
async def async_device_initialized(self, device, is_new_join):
"""Handle device joined and basic information discovered (async)."""
@ -323,6 +325,14 @@ async def _handle_single_cluster_matches(hass, endpoint, zha_device,
cluster_match_tasks = []
event_channel_tasks = []
for cluster in endpoint.in_clusters.values():
# don't let profiles prevent these channels from being created
if cluster.cluster_id in NO_SENSOR_CLUSTERS:
cluster_match_tasks.append(_handle_channel_only_cluster_match(
zha_device,
cluster,
is_new_join,
))
if cluster.cluster_id not in profile_clusters[0]:
cluster_match_tasks.append(_handle_single_cluster_match(
hass,
@ -333,13 +343,6 @@ async def _handle_single_cluster_matches(hass, endpoint, zha_device,
is_new_join,
))
if cluster.cluster_id in NO_SENSOR_CLUSTERS:
cluster_match_tasks.append(_handle_channel_only_cluster_match(
zha_device,
cluster,
is_new_join,
))
for cluster in endpoint.out_clusters.values():
if cluster.cluster_id not in profile_clusters[1]:
cluster_match_tasks.append(_handle_single_cluster_match(