diff --git a/homeassistant/components/binary_sensor/zha.py b/homeassistant/components/binary_sensor/zha.py index cabbbd704a0014..0842ab7db6ea8f 100644 --- a/homeassistant/components/binary_sensor/zha.py +++ b/homeassistant/components/binary_sensor/zha.py @@ -65,28 +65,25 @@ async def _async_setup_iaszone(hass, config, async_add_entities, async def _async_setup_remote(hass, config, async_add_entities, discovery_info): - async def safe(coro): - """Run coro, catching ZigBee delivery errors, and ignoring them.""" - import zigpy.exceptions - try: - await coro - except zigpy.exceptions.DeliveryError as exc: - _LOGGER.warning("Ignoring error during setup: %s", exc) + remote = Remote(**discovery_info) if discovery_info['new_join']: from zigpy.zcl.clusters.general import OnOff, LevelControl out_clusters = discovery_info['out_clusters'] if OnOff.cluster_id in out_clusters: cluster = out_clusters[OnOff.cluster_id] - await safe(cluster.bind()) - await safe(cluster.configure_reporting(0, 0, 600, 1)) + await zha.configure_reporting( + remote.entity_id, cluster, 0, min_report=0, max_report=600, + reportable_change=1 + ) if LevelControl.cluster_id in out_clusters: cluster = out_clusters[LevelControl.cluster_id] - await safe(cluster.bind()) - await safe(cluster.configure_reporting(0, 1, 600, 1)) + await zha.configure_reporting( + remote.entity_id, cluster, 0, min_report=1, max_report=600, + reportable_change=1 + ) - sensor = Switch(**discovery_info) - async_add_entities([sensor], update_before_add=True) + async_add_entities([remote], update_before_add=True) class BinarySensor(zha.Entity, BinarySensorDevice): @@ -131,7 +128,7 @@ def cluster_command(self, tsn, command_id, args): async def async_update(self): """Retrieve latest state.""" - from bellows.types.basic import uint16_t + from zigpy.types.basic import uint16_t result = await zha.safe_read(self._endpoint.ias_zone, ['zone_status'], @@ -141,7 +138,7 @@ async def async_update(self): self._state = result.get('zone_status', self._state) & 3 -class Switch(zha.Entity, BinarySensorDevice): +class Remote(zha.Entity, BinarySensorDevice): """ZHA switch/remote controller/button.""" _domain = DOMAIN diff --git a/homeassistant/components/sensor/zha.py b/homeassistant/components/sensor/zha.py index 6202f8cb7efd29..0a6710f8f6cec9 100644 --- a/homeassistant/components/sensor/zha.py +++ b/homeassistant/components/sensor/zha.py @@ -57,9 +57,9 @@ def make_sensor(discovery_info): if discovery_info['new_join']: cluster = list(in_clusters.values())[0] - yield from cluster.bind() - yield from cluster.configure_reporting( - sensor.value_attribute, 300, 600, sensor.min_reportable_change, + yield from zha.configure_reporting( + sensor.entity_id, cluster, sensor.value_attribute, + reportable_change=sensor.min_reportable_change ) return sensor diff --git a/homeassistant/components/switch/zha.py b/homeassistant/components/switch/zha.py index 9f780b631b655f..7ac93180cd7703 100644 --- a/homeassistant/components/switch/zha.py +++ b/homeassistant/components/switch/zha.py @@ -17,17 +17,23 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up the Zigbee Home Automation switches.""" + from zigpy.zcl.clusters.general import OnOff + discovery_info = zha.get_discovery_info(hass, discovery_info) if discovery_info is None: return - from zigpy.zcl.clusters.general import OnOff - in_clusters = discovery_info['in_clusters'] - cluster = in_clusters[OnOff.cluster_id] - await cluster.bind() - await cluster.configure_reporting(0, 0, 600, 1,) + switch = Switch(**discovery_info) + + if discovery_info['new_join']: + in_clusters = discovery_info['in_clusters'] + cluster = in_clusters[OnOff.cluster_id] + await zha.configure_reporting( + switch.entity_id, cluster, switch.value_attribute, + min_report=0, max_report=600, reportable_change=1 + ) - async_add_entities([Switch(**discovery_info)], update_before_add=True) + async_add_entities([switch], update_before_add=True) class Switch(zha.Entity, SwitchDevice): diff --git a/homeassistant/components/zha/__init__.py b/homeassistant/components/zha/__init__.py index 48c2ad20be05c8..4c1109f685da80 100644 --- a/homeassistant/components/zha/__init__.py +++ b/homeassistant/components/zha/__init__.py @@ -399,3 +399,42 @@ async def safe_read(cluster, attributes, allow_cache=True): return result except Exception: # pylint: disable=broad-except return {} + + +async def configure_reporting(entity_id, cluster, attr, skip_bind=False, + min_report=300, max_report=900, + reportable_change=1): + """Configure attribute reporting for a cluster. + + while swallowing the DeliverError exceptions in case of unreachable + devices. + """ + from zigpy.exceptions import DeliveryError + + attr_name = cluster.attributes.get(attr, [attr])[0] + cluster_name = cluster.ep_attribute + if not skip_bind: + try: + res = await cluster.bind() + _LOGGER.debug( + "%s: bound '%s' cluster: %s", entity_id, cluster_name, res[0] + ) + except DeliveryError as ex: + _LOGGER.debug( + "%s: Failed to bind '%s' cluster: %s", + entity_id, cluster_name, str(ex) + ) + + try: + res = await cluster.configure_reporting(attr, min_report, + max_report, reportable_change) + _LOGGER.debug( + "%s: reporting '%s' attr on '%s' cluster: %d/%d/%d: Status: %s", + entity_id, attr_name, cluster_name, min_report, max_report, + reportable_change, res[0][0].status + ) + except DeliveryError as ex: + _LOGGER.debug( + "%s: failed to set reporting for '%s' attr on '%s' cluster: %s", + entity_id, attr_name, cluster_name, str(ex) + )