Skip to content

Commit

Permalink
ZHA fixes (#21592)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
dmulcahey authored and Adminiuga committed Mar 2, 2019
1 parent 5eab869 commit 45316f6
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 10 deletions.
7 changes: 7 additions & 0 deletions homeassistant/components/zha/core/channels/general.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ async def async_initialize(self, from_cache):
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."""
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/zha/core/channels/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
18 changes: 10 additions & 8 deletions homeassistant/components/zha/core/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,20 +205,22 @@ async def async_initialize(self, from_cache=False):
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',
Expand Down
4 changes: 4 additions & 0 deletions homeassistant/components/zha/core/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions homeassistant/components/zha/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
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
Expand All @@ -26,6 +27,7 @@
CAPABILITIES_COLOR_TEMP = 0x10

UNSUPPORTED_ATTRIBUTE = 0x86
SCAN_INTERVAL = timedelta(minutes=60)


async def async_setup_platform(hass, config, async_add_entities,
Expand Down Expand Up @@ -92,6 +94,11 @@ def __init__(self, unique_id, zha_device, channels, **kwargs):
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."""
Expand Down Expand Up @@ -217,3 +224,8 @@ async def async_turn_off(self, **kwargs):
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()
12 changes: 10 additions & 2 deletions homeassistant/components/zha/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,19 @@ def is_on(self) -> bool:

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."""
Expand Down

0 comments on commit 45316f6

Please sign in to comment.