-
-
Notifications
You must be signed in to change notification settings - Fork 37.8k
ZHA - add events for remote like devices #18493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
8c69c15
c4af1e2
9076fe5
3b1e44a
d050473
e13745b
857c2a2
e3a4ff7
867ad95
d0194d4
3189973
0a0938b
b3a0020
f0a2d97
93f38e1
9d6f00c
96445b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,7 @@ | |
|
|
||
| import homeassistant.helpers.config_validation as cv | ||
| from homeassistant import const as ha_const | ||
| from homeassistant.core import EventOrigin, callback | ||
| from homeassistant.helpers import discovery, entity | ||
| from homeassistant.util import slugify | ||
| from homeassistant.helpers.entity_component import EntityComponent | ||
|
|
@@ -132,6 +133,9 @@ async def remove(service): | |
| hass.services.async_register(DOMAIN, SERVICE_REMOVE, remove, | ||
| schema=SERVICE_SCHEMAS[SERVICE_REMOVE]) | ||
|
|
||
| import homeassistant.components.zha.const as zha_const | ||
| hass.data[zha_const.DATA_ZHA_EVENT] = [] | ||
|
|
||
| return True | ||
|
|
||
|
|
||
|
|
@@ -177,6 +181,7 @@ def device_removed(self, device): | |
| async def async_device_initialized(self, device, join): | ||
| """Handle device joined and basic information discovered (async).""" | ||
| import zigpy.profiles | ||
| import homeassistant.components.zha.event as event | ||
| import homeassistant.components.zha.const as zha_const | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please move this too.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a design issue w/ the modules that causes circular imports. I have it corrected in another branch and can fix this in a subsequent PR if that is ok. |
||
| zha_const.populate_data() | ||
|
|
||
|
|
@@ -197,6 +202,40 @@ async def async_device_initialized(self, device, join): | |
| node_config = self._config[DOMAIN][CONF_DEVICE_CONFIG].get( | ||
| device_key, {}) | ||
|
|
||
| _LOGGER.debug( | ||
| "Manufacturer: %s model: %s", | ||
| endpoint.manufacturer, | ||
| endpoint.model | ||
| ) | ||
| supported_remote_models = zha_const.REMOTE_DEVICE_TYPES.get( | ||
| endpoint.profile_id, {}).get(endpoint.manufacturer, []) | ||
| _LOGGER.debug( | ||
| "Supported remote models: %s", | ||
| supported_remote_models | ||
| ) | ||
| if endpoint.profile_id in zigpy.profiles.PROFILES and \ | ||
| endpoint.model in supported_remote_models: | ||
| profile = zigpy.profiles.PROFILES[endpoint.profile_id] | ||
| profile_clusters = profile.CLUSTERS[endpoint.device_type] | ||
| in_clusters = [endpoint.in_clusters[c] | ||
| for c in profile_clusters[0] | ||
| if c in endpoint.in_clusters] | ||
| out_clusters = [endpoint.out_clusters[c] | ||
| for c in profile_clusters[1] | ||
| if c in endpoint.out_clusters] | ||
| discovery_info = { | ||
| 'application_listener': self, | ||
| 'endpoint': endpoint, | ||
| 'in_clusters': in_clusters, | ||
| 'out_clusters': out_clusters, | ||
| 'manufacturer': endpoint.manufacturer, | ||
| 'model': endpoint.model, | ||
| 'new_join': join, | ||
| 'unique_id': device_key, | ||
| } | ||
| self._hass.data[DISCOVERY_KEY][device_key] = discovery_info | ||
| await event._async_setup_event(self._hass, discovery_info) | ||
|
|
||
| if endpoint.profile_id in zigpy.profiles.PROFILES: | ||
| profile = zigpy.profiles.PROFILES[endpoint.profile_id] | ||
| if zha_const.DEVICE_CLASS.get(endpoint.profile_id, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| import logging | ||
| from homeassistant.util import slugify | ||
| from homeassistant.core import EventOrigin, callback | ||
|
|
||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
| async def _async_setup_event(hass, discovery_info): | ||
|
dmulcahey marked this conversation as resolved.
Outdated
|
||
| from homeassistant.components.zha import const as zha_const | ||
|
dmulcahey marked this conversation as resolved.
Outdated
|
||
| from homeassistant.components.zha import configure_reporting | ||
| out_clusters = discovery_info['out_clusters'] | ||
| in_clusters = discovery_info['in_clusters'] | ||
| for in_cluster in in_clusters: | ||
| event = ZHAEvent(hass, in_cluster, discovery_info) | ||
| if discovery_info['new_join']: | ||
| await configure_reporting(event.event_id, in_cluster, 0, | ||
| False, 0, 600, 1) | ||
| hass.data[zha_const.DATA_ZHA_EVENT].append( | ||
|
dmulcahey marked this conversation as resolved.
Outdated
|
||
| event | ||
| ) | ||
| for out_cluster in out_clusters: | ||
| event = ZHAEvent(hass, out_cluster, discovery_info) | ||
| if discovery_info['new_join']: | ||
| await configure_reporting(event.event_id, out_cluster, 0, | ||
| False, 0, 600, 1) | ||
| hass.data[zha_const.DATA_ZHA_EVENT].append( | ||
| event | ||
| ) | ||
|
|
||
|
|
||
| class ZHAEvent(object): | ||
| """When you want signals instead of entities. | ||
| Stateless sensors such as remotes are expected to generate an event | ||
| instead of a sensor entity in hass. | ||
| """ | ||
|
|
||
| def __init__(self, hass, cluster, discovery_info): | ||
| """Register callback that will be used for signals.""" | ||
| self._hass = hass | ||
| self._cluster = cluster | ||
| self._cluster.add_listener(self) | ||
| ieee = discovery_info['endpoint'].device.ieee | ||
| ieeetail = ''.join(['%02x' % (o, ) for o in ieee[-4:]]) | ||
| if discovery_info['manufacturer'] and discovery_info['model'] is not \ | ||
| None: | ||
| self.event_id = "{}.{}_{}_{}{}".format( | ||
| slugify(discovery_info['manufacturer']), | ||
| slugify(discovery_info['model']), | ||
| ieeetail, | ||
| discovery_info['endpoint'].endpoint_id, | ||
| discovery_info.get('entity_suffix', '') | ||
| ) | ||
| else: | ||
| self.event_id = "{}.event_{}{}".format( | ||
| ieeetail, | ||
| discovery_info['endpoint'].endpoint_id, | ||
| discovery_info.get('entity_suffix', '') | ||
| ) | ||
|
|
||
| @callback | ||
| def cluster_command(self, tsn, command_id, args): | ||
| """Handle commands received to this cluster.""" | ||
| self._hass.bus.async_fire( | ||
| 'zha_' + self._cluster.server_commands.get(command_id)[0], | ||
| {'device': self.event_id, 'args': args}, | ||
| EventOrigin.remote | ||
| ) | ||
| _LOGGER.debug( | ||
|
dmulcahey marked this conversation as resolved.
Outdated
|
||
| "%s: fired %s event with arguments: %s", self.event_id, | ||
| self._cluster.server_commands.get(command_id)[0], | ||
| args | ||
| ) | ||
|
|
||
| @callback | ||
| def attribute_updated(self, attrid, value): | ||
| self._hass.bus.async_fire( | ||
| 'zha_attribute_updated', | ||
| {'device': self.event_id, | ||
| 'attribute': self._cluster.attributes.get(attrid, ['Unknown'])[0], | ||
| 'attribute_id': attrid, | ||
| 'value': value}, | ||
| EventOrigin.remote | ||
| ) | ||
| _LOGGER.debug( | ||
|
dmulcahey marked this conversation as resolved.
Outdated
|
||
| "%s: updated attribute %s with value: %s and id: %s", | ||
| self.event_id, | ||
| self._cluster.attributes.get(attrid, ['Unknown'])[0], | ||
| value, | ||
| attrid | ||
| ) | ||
|
|
||
| @callback | ||
| def zdo_command(self, *args, **kwargs): | ||
|
MartinHjelmare marked this conversation as resolved.
|
||
| _LOGGER.debug( | ||
| "%s: issued zdo command %s with args: %s", self.event_id, | ||
| args, | ||
| kwargs | ||
| ) | ||
Uh oh!
There was an error while loading. Please reload this page.