mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
ZHA fixes (#21592)
* 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:
parent
5eab86986e
commit
45316f6ed6
@ -64,6 +64,13 @@ class OnOffChannel(ZigbeeChannel):
|
|||||||
await self.get_attribute_value(self.ON_OFF, from_cache=from_cache))
|
await self.get_attribute_value(self.ON_OFF, from_cache=from_cache))
|
||||||
await super().async_initialize(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):
|
class LevelControlChannel(ZigbeeChannel):
|
||||||
"""Channel for the LevelControl Zigbee cluster."""
|
"""Channel for the LevelControl Zigbee cluster."""
|
||||||
|
@ -43,4 +43,5 @@ def populate_channel_registry():
|
|||||||
zcl.clusters.general.Basic.cluster_id: BasicChannel,
|
zcl.clusters.general.Basic.cluster_id: BasicChannel,
|
||||||
zcl.clusters.security.IasZone.cluster_id: IASZoneChannel,
|
zcl.clusters.security.IasZone.cluster_id: IASZoneChannel,
|
||||||
zcl.clusters.hvac.Fan.cluster_id: FanChannel,
|
zcl.clusters.hvac.Fan.cluster_id: FanChannel,
|
||||||
|
zcl.clusters.lightlink.LightLink.cluster_id: ZigbeeChannel,
|
||||||
})
|
})
|
||||||
|
@ -205,20 +205,22 @@ class ZHADevice:
|
|||||||
async def _execute_channel_tasks(self, task_name, *args):
|
async def _execute_channel_tasks(self, task_name, *args):
|
||||||
"""Gather and execute a set of CHANNEL tasks."""
|
"""Gather and execute a set of CHANNEL tasks."""
|
||||||
channel_tasks = []
|
channel_tasks = []
|
||||||
|
semaphore = asyncio.Semaphore(3)
|
||||||
for channel in self.all_channels:
|
for channel in self.all_channels:
|
||||||
channel_tasks.append(
|
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)
|
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."""
|
"""Configure a single channel on this device."""
|
||||||
try:
|
try:
|
||||||
await getattr(channel, func_name)(*args)
|
async with semaphore:
|
||||||
_LOGGER.debug('%s: channel: %s %s stage succeeded',
|
await getattr(channel, func_name)(*args)
|
||||||
self.name,
|
_LOGGER.debug('%s: channel: %s %s stage succeeded',
|
||||||
"{}-{}".format(
|
self.name,
|
||||||
channel.name, channel.unique_id),
|
"{}-{}".format(
|
||||||
func_name)
|
channel.name, channel.unique_id),
|
||||||
|
func_name)
|
||||||
except Exception as ex: # pylint: disable=broad-except
|
except Exception as ex: # pylint: disable=broad-except
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
'%s channel: %s %s stage failed ex: %s',
|
'%s channel: %s %s stage failed ex: %s',
|
||||||
|
@ -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.Basic.cluster_id)
|
||||||
NO_SENSOR_CLUSTERS.append(
|
NO_SENSOR_CLUSTERS.append(
|
||||||
zcl.clusters.general.PowerConfiguration.cluster_id)
|
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.LevelControl.cluster_id)
|
||||||
BINDABLE_CLUSTERS.append(zcl.clusters.general.OnOff.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({
|
DEVICE_CLASS[zha.PROFILE_ID].update({
|
||||||
zha.DeviceType.ON_OFF_SWITCH: 'binary_sensor',
|
zha.DeviceType.ON_OFF_SWITCH: 'binary_sensor',
|
||||||
@ -537,6 +540,7 @@ def establish_device_mappings():
|
|||||||
zcl.clusters.general.PollControl.cluster_id: [],
|
zcl.clusters.general.PollControl.cluster_id: [],
|
||||||
zcl.clusters.general.GreenPowerProxy.cluster_id: [],
|
zcl.clusters.general.GreenPowerProxy.cluster_id: [],
|
||||||
zcl.clusters.general.OnOffConfiguration.cluster_id: [],
|
zcl.clusters.general.OnOffConfiguration.cluster_id: [],
|
||||||
|
zcl.clusters.lightlink.LightLink.cluster_id: [],
|
||||||
zcl.clusters.general.OnOff.cluster_id: [{
|
zcl.clusters.general.OnOff.cluster_id: [{
|
||||||
'attr': 'on_off',
|
'attr': 'on_off',
|
||||||
'config': REPORT_CONFIG_IMMEDIATE
|
'config': REPORT_CONFIG_IMMEDIATE
|
||||||
|
@ -4,6 +4,7 @@ Lights on Zigbee Home Automation networks.
|
|||||||
For more details on this platform, please refer to the documentation
|
For more details on this platform, please refer to the documentation
|
||||||
at https://home-assistant.io/components/light.zha/
|
at https://home-assistant.io/components/light.zha/
|
||||||
"""
|
"""
|
||||||
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from homeassistant.components import light
|
from homeassistant.components import light
|
||||||
@ -26,6 +27,7 @@ CAPABILITIES_COLOR_XY = 0x08
|
|||||||
CAPABILITIES_COLOR_TEMP = 0x10
|
CAPABILITIES_COLOR_TEMP = 0x10
|
||||||
|
|
||||||
UNSUPPORTED_ATTRIBUTE = 0x86
|
UNSUPPORTED_ATTRIBUTE = 0x86
|
||||||
|
SCAN_INTERVAL = timedelta(minutes=60)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, async_add_entities,
|
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._supported_features |= light.SUPPORT_COLOR
|
||||||
self._hs_color = (0, 0)
|
self._hs_color = (0, 0)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self) -> bool:
|
||||||
|
"""Poll state from device."""
|
||||||
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
"""Return true if entity is on."""
|
"""Return true if entity is on."""
|
||||||
@ -217,3 +224,8 @@ class Light(ZhaEntity, light.Light):
|
|||||||
return
|
return
|
||||||
self._state = False
|
self._state = False
|
||||||
self.async_schedule_update_ha_state()
|
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()
|
||||||
|
@ -71,11 +71,19 @@ class Switch(ZhaEntity, SwitchDevice):
|
|||||||
|
|
||||||
async def async_turn_on(self, **kwargs):
|
async def async_turn_on(self, **kwargs):
|
||||||
"""Turn the entity on."""
|
"""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):
|
async def async_turn_off(self, **kwargs):
|
||||||
"""Turn the entity off."""
|
"""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):
|
def async_set_state(self, state):
|
||||||
"""Handle state update from channel."""
|
"""Handle state update from channel."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user