* do not report on 0x1000 LightLink cluster
* don't flood Zigbee network during configuration or initialization
* add lifeline of 60 minutes to lights
* use ootb polling
This commit is contained in:
David F. Mulcahey 2019-03-02 14:09:01 -05:00 committed by Alexei Chetroi
parent 5eab86986e
commit 45316f6ed6
6 changed files with 44 additions and 10 deletions

View File

@ -64,6 +64,13 @@ class OnOffChannel(ZigbeeChannel):
await self.get_attribute_value(self.ON_OFF, from_cache=from_cache))
await super().async_initialize(from_cache)
async def async_update(self):
"""Initialize channel."""
_LOGGER.debug("Attempting to update onoff state")
self._state = bool(
await self.get_attribute_value(self.ON_OFF, from_cache=False))
await super().async_update()
class LevelControlChannel(ZigbeeChannel):
"""Channel for the LevelControl Zigbee cluster."""

View File

@ -43,4 +43,5 @@ def populate_channel_registry():
zcl.clusters.general.Basic.cluster_id: BasicChannel,
zcl.clusters.security.IasZone.cluster_id: IASZoneChannel,
zcl.clusters.hvac.Fan.cluster_id: FanChannel,
zcl.clusters.lightlink.LightLink.cluster_id: ZigbeeChannel,
})

View File

@ -205,20 +205,22 @@ class ZHADevice:
async def _execute_channel_tasks(self, task_name, *args):
"""Gather and execute a set of CHANNEL tasks."""
channel_tasks = []
semaphore = asyncio.Semaphore(3)
for channel in self.all_channels:
channel_tasks.append(
self._async_create_task(channel, task_name, *args))
self._async_create_task(semaphore, channel, task_name, *args))
await asyncio.gather(*channel_tasks)
async def _async_create_task(self, channel, func_name, *args):
async def _async_create_task(self, semaphore, channel, func_name, *args):
"""Configure a single channel on this device."""
try:
await getattr(channel, func_name)(*args)
_LOGGER.debug('%s: channel: %s %s stage succeeded',
self.name,
"{}-{}".format(
channel.name, channel.unique_id),
func_name)
async with semaphore:
await getattr(channel, func_name)(*args)
_LOGGER.debug('%s: channel: %s %s stage succeeded',
self.name,
"{}-{}".format(
channel.name, channel.unique_id),
func_name)
except Exception as ex: # pylint: disable=broad-except
_LOGGER.warning(
'%s channel: %s %s stage failed ex: %s',

View File

@ -452,8 +452,11 @@ def establish_device_mappings():
NO_SENSOR_CLUSTERS.append(zcl.clusters.general.Basic.cluster_id)
NO_SENSOR_CLUSTERS.append(
zcl.clusters.general.PowerConfiguration.cluster_id)
NO_SENSOR_CLUSTERS.append(zcl.clusters.lightlink.LightLink.cluster_id)
BINDABLE_CLUSTERS.append(zcl.clusters.general.LevelControl.cluster_id)
BINDABLE_CLUSTERS.append(zcl.clusters.general.OnOff.cluster_id)
BINDABLE_CLUSTERS.append(zcl.clusters.lighting.Color.cluster_id)
DEVICE_CLASS[zha.PROFILE_ID].update({
zha.DeviceType.ON_OFF_SWITCH: 'binary_sensor',
@ -537,6 +540,7 @@ def establish_device_mappings():
zcl.clusters.general.PollControl.cluster_id: [],
zcl.clusters.general.GreenPowerProxy.cluster_id: [],
zcl.clusters.general.OnOffConfiguration.cluster_id: [],
zcl.clusters.lightlink.LightLink.cluster_id: [],
zcl.clusters.general.OnOff.cluster_id: [{
'attr': 'on_off',
'config': REPORT_CONFIG_IMMEDIATE

View File

@ -4,6 +4,7 @@ Lights on Zigbee Home Automation networks.
For more details on this platform, please refer to the documentation
at https://home-assistant.io/components/light.zha/
"""
from datetime import timedelta
import logging
from homeassistant.components import light
@ -26,6 +27,7 @@ CAPABILITIES_COLOR_XY = 0x08
CAPABILITIES_COLOR_TEMP = 0x10
UNSUPPORTED_ATTRIBUTE = 0x86
SCAN_INTERVAL = timedelta(minutes=60)
async def async_setup_platform(hass, config, async_add_entities,
@ -92,6 +94,11 @@ class Light(ZhaEntity, light.Light):
self._supported_features |= light.SUPPORT_COLOR
self._hs_color = (0, 0)
@property
def should_poll(self) -> bool:
"""Poll state from device."""
return True
@property
def is_on(self) -> bool:
"""Return true if entity is on."""
@ -217,3 +224,8 @@ class Light(ZhaEntity, light.Light):
return
self._state = False
self.async_schedule_update_ha_state()
async def async_update(self):
"""Attempt to retrieve on off state from the light."""
if self._on_off_channel:
await self._on_off_channel.async_update()

View File

@ -71,11 +71,19 @@ class Switch(ZhaEntity, SwitchDevice):
async def async_turn_on(self, **kwargs):
"""Turn the entity on."""
await self._on_off_channel.on()
success = await self._on_off_channel.on()
if not success:
return
self._state = True
self.async_schedule_update_ha_state()
async def async_turn_off(self, **kwargs):
"""Turn the entity off."""
await self._on_off_channel.off()
success = await self._on_off_channel.off()
if not success:
return
self._state = False
self.async_schedule_update_ha_state()
def async_set_state(self, state):
"""Handle state update from channel."""