diff --git a/homeassistant/components/zha/core/const.py b/homeassistant/components/zha/core/const.py index 22f8f0f261d..12d928e172a 100644 --- a/homeassistant/components/zha/core/const.py +++ b/homeassistant/components/zha/core/const.py @@ -155,6 +155,9 @@ DEBUG_RELAY_LOGGERS = [DEBUG_COMP_ZHA, DEBUG_COMP_ZIGPY] DEFAULT_RADIO_TYPE = "ezsp" DEFAULT_BAUDRATE = 57600 DEFAULT_DATABASE_NAME = "zigbee.db" + +DEVICE_PAIRING_STATUS = "pairing_status" + DISCOVERY_KEY = "zha_discovery_info" DOMAIN = "zha" diff --git a/homeassistant/components/zha/core/gateway.py b/homeassistant/components/zha/core/gateway.py index 13a87c13226..bec429cdf22 100644 --- a/homeassistant/components/zha/core/gateway.py +++ b/homeassistant/components/zha/core/gateway.py @@ -3,6 +3,7 @@ import asyncio import collections from datetime import timedelta +from enum import Enum import itertools import logging import os @@ -54,6 +55,7 @@ from .const import ( DEBUG_LEVELS, DEBUG_RELAY_LOGGERS, DEFAULT_DATABASE_NAME, + DEVICE_PAIRING_STATUS, DOMAIN, SIGNAL_ADD_ENTITIES, SIGNAL_GROUP_MEMBERSHIP_CHANGE, @@ -94,6 +96,15 @@ EntityReference = collections.namedtuple( ) +class DevicePairingStatus(Enum): + """Status of a device.""" + + PAIRED = 1 + INTERVIEW_COMPLETE = 2 + CONFIGURED = 3 + INITIALIZED = 4 + + class ZHAGateway: """Gateway that handles events that happen on the ZHA Zigbee network.""" @@ -240,8 +251,11 @@ class ZHAGateway: ZHA_GW_MSG, { ATTR_TYPE: ZHA_GW_MSG_DEVICE_JOINED, - ATTR_NWK: device.nwk, - ATTR_IEEE: str(device.ieee), + ZHA_GW_MSG_DEVICE_INFO: { + ATTR_NWK: device.nwk, + ATTR_IEEE: str(device.ieee), + DEVICE_PAIRING_STATUS: DevicePairingStatus.PAIRED.name, + }, }, ) @@ -253,11 +267,14 @@ class ZHAGateway: ZHA_GW_MSG, { ATTR_TYPE: ZHA_GW_MSG_RAW_INIT, - ATTR_NWK: device.nwk, - ATTR_IEEE: str(device.ieee), - ATTR_MODEL: device.model if device.model else UNKNOWN_MODEL, - ATTR_MANUFACTURER: manuf if manuf else UNKNOWN_MANUFACTURER, - ATTR_SIGNATURE: device.get_signature(), + ZHA_GW_MSG_DEVICE_INFO: { + ATTR_NWK: device.nwk, + ATTR_IEEE: str(device.ieee), + DEVICE_PAIRING_STATUS: DevicePairingStatus.INTERVIEW_COMPLETE.name, + ATTR_MODEL: device.model if device.model else UNKNOWN_MODEL, + ATTR_MANUFACTURER: manuf if manuf else UNKNOWN_MANUFACTURER, + ATTR_SIGNATURE: device.get_signature(), + }, }, ) @@ -552,8 +569,8 @@ class ZHAGateway: ) await self._async_device_joined(zha_device) - device_info = zha_device.zha_device_info - + device_info = zha_device.device_info + device_info[DEVICE_PAIRING_STATUS] = DevicePairingStatus.INITIALIZED.name async_dispatcher_send( self._hass, ZHA_GW_MSG, @@ -565,7 +582,17 @@ class ZHAGateway: async def _async_device_joined(self, zha_device: zha_typing.ZhaDeviceType) -> None: zha_device.available = True + device_info = zha_device.device_info await zha_device.async_configure() + device_info[DEVICE_PAIRING_STATUS] = DevicePairingStatus.CONFIGURED.name + async_dispatcher_send( + self._hass, + ZHA_GW_MSG, + { + ATTR_TYPE: ZHA_GW_MSG_DEVICE_FULL_INIT, + ZHA_GW_MSG_DEVICE_INFO: device_info, + }, + ) await zha_device.async_initialize(from_cache=False) async_dispatcher_send(self._hass, SIGNAL_ADD_ENTITIES) @@ -577,6 +604,16 @@ class ZHAGateway: ) # we don't have to do this on a nwk swap but we don't have a way to tell currently await zha_device.async_configure() + device_info = zha_device.device_info + device_info[DEVICE_PAIRING_STATUS] = DevicePairingStatus.CONFIGURED.name + async_dispatcher_send( + self._hass, + ZHA_GW_MSG, + { + ATTR_TYPE: ZHA_GW_MSG_DEVICE_FULL_INIT, + ZHA_GW_MSG_DEVICE_INFO: device_info, + }, + ) # force async_initialize() to fire so don't explicitly call it zha_device.available = False zha_device.update_available(True)