Enhancement/zha model manuf (#24771)
* Cleanup ZHA entities model and manufacturer usage. Zigpy includes manufacturer and model as attributes of a zigpy Device class, which simplifies handling of manufacturer and/or model derived properties for the ZHA platform. * Sort ZHA imports. * Lint.
This commit is contained in:
parent
29311e6391
commit
6ae1228e61
5 changed files with 45 additions and 76 deletions
|
@ -77,6 +77,8 @@ METERING = 'metering'
|
||||||
ELECTRICAL_MEASUREMENT = 'electrical_measurement'
|
ELECTRICAL_MEASUREMENT = 'electrical_measurement'
|
||||||
GENERIC = 'generic'
|
GENERIC = 'generic'
|
||||||
UNKNOWN = 'unknown'
|
UNKNOWN = 'unknown'
|
||||||
|
UNKNOWN_MANUFACTURER = 'unk_manufacturer'
|
||||||
|
UNKNOWN_MODEL = 'unk_model'
|
||||||
OPENING = 'opening'
|
OPENING = 'opening'
|
||||||
OCCUPANCY = 'occupancy'
|
OCCUPANCY = 'occupancy'
|
||||||
ACCELERATION = 'acceleration'
|
ACCELERATION = 'acceleration'
|
||||||
|
|
|
@ -10,17 +10,16 @@ import logging
|
||||||
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import (
|
from homeassistant.helpers.dispatcher import (
|
||||||
async_dispatcher_connect, async_dispatcher_send
|
async_dispatcher_connect, async_dispatcher_send)
|
||||||
)
|
|
||||||
from .const import (
|
|
||||||
ATTR_MANUFACTURER, POWER_CONFIGURATION_CHANNEL, SIGNAL_AVAILABLE, IN, OUT,
|
|
||||||
ATTR_CLUSTER_ID, ATTR_ATTRIBUTE, ATTR_VALUE, ATTR_COMMAND, SERVER,
|
|
||||||
ATTR_COMMAND_TYPE, ATTR_ARGS, CLIENT_COMMANDS, SERVER_COMMANDS,
|
|
||||||
ATTR_ENDPOINT_ID, IEEE, MODEL, NAME, UNKNOWN, QUIRK_APPLIED,
|
|
||||||
QUIRK_CLASS, ZDO_CHANNEL, MANUFACTURER_CODE, POWER_SOURCE, MAINS_POWERED,
|
|
||||||
BATTERY_OR_UNKNOWN, NWK
|
|
||||||
)
|
|
||||||
from .channels import EventRelayChannel
|
from .channels import EventRelayChannel
|
||||||
|
from .const import (
|
||||||
|
ATTR_ARGS, ATTR_ATTRIBUTE, ATTR_CLUSTER_ID, ATTR_COMMAND,
|
||||||
|
ATTR_COMMAND_TYPE, ATTR_ENDPOINT_ID, ATTR_MANUFACTURER, ATTR_VALUE,
|
||||||
|
BATTERY_OR_UNKNOWN, CLIENT_COMMANDS, IEEE, IN, MAINS_POWERED,
|
||||||
|
MANUFACTURER_CODE, MODEL, NAME, NWK, OUT, POWER_CONFIGURATION_CHANNEL,
|
||||||
|
POWER_SOURCE, QUIRK_APPLIED, QUIRK_CLASS, SERVER, SERVER_COMMANDS,
|
||||||
|
SIGNAL_AVAILABLE, UNKNOWN_MANUFACTURER, UNKNOWN_MODEL, ZDO_CHANNEL)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -39,22 +38,10 @@ class ZHADevice:
|
||||||
"""Initialize the gateway."""
|
"""Initialize the gateway."""
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
self._zigpy_device = zigpy_device
|
self._zigpy_device = zigpy_device
|
||||||
# Get first non ZDO endpoint id to use to get manufacturer and model
|
|
||||||
endpoint_ids = zigpy_device.endpoints.keys()
|
|
||||||
self._manufacturer = UNKNOWN
|
|
||||||
self._model = UNKNOWN
|
|
||||||
ept_id = next((ept_id for ept_id in endpoint_ids if ept_id != 0), None)
|
|
||||||
if ept_id is not None:
|
|
||||||
self._manufacturer = zigpy_device.endpoints[ept_id].manufacturer
|
|
||||||
self._model = zigpy_device.endpoints[ept_id].model
|
|
||||||
self._zha_gateway = zha_gateway
|
self._zha_gateway = zha_gateway
|
||||||
self.cluster_channels = {}
|
self.cluster_channels = {}
|
||||||
self._relay_channels = {}
|
self._relay_channels = {}
|
||||||
self._all_channels = []
|
self._all_channels = []
|
||||||
self._name = "{} {}".format(
|
|
||||||
self.manufacturer,
|
|
||||||
self.model
|
|
||||||
)
|
|
||||||
self._available = False
|
self._available = False
|
||||||
self._available_signal = "{}_{}_{}".format(
|
self._available_signal = "{}_{}_{}".format(
|
||||||
self.name, self.ieee, SIGNAL_AVAILABLE)
|
self.name, self.ieee, SIGNAL_AVAILABLE)
|
||||||
|
@ -74,7 +61,7 @@ class ZHADevice:
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""Return device name."""
|
"""Return device name."""
|
||||||
return self._name
|
return "{} {}".format(self.manufacturer, self.model)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ieee(self):
|
def ieee(self):
|
||||||
|
@ -84,12 +71,16 @@ class ZHADevice:
|
||||||
@property
|
@property
|
||||||
def manufacturer(self):
|
def manufacturer(self):
|
||||||
"""Return manufacturer for device."""
|
"""Return manufacturer for device."""
|
||||||
return self._manufacturer
|
if self._zigpy_device.manufacturer is None:
|
||||||
|
return UNKNOWN_MANUFACTURER
|
||||||
|
return self._zigpy_device.manufacturer
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def model(self):
|
def model(self):
|
||||||
"""Return model for device."""
|
"""Return model for device."""
|
||||||
return self._model
|
if self._zigpy_device.model is None:
|
||||||
|
return UNKNOWN_MODEL
|
||||||
|
return self._zigpy_device.model
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def manufacturer_code(self):
|
def manufacturer_code(self):
|
||||||
|
|
|
@ -14,8 +14,8 @@ import traceback
|
||||||
|
|
||||||
from homeassistant.components.system_log import LogEntry, _figure_out_source
|
from homeassistant.components.system_log import LogEntry, _figure_out_source
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.device_registry import\
|
from homeassistant.helpers.device_registry import (
|
||||||
async_get_registry as get_dev_reg
|
async_get_registry as get_dev_reg)
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
from homeassistant.helpers.entity_component import EntityComponent
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
|
|
||||||
|
@ -27,14 +27,14 @@ from .const import (
|
||||||
DEBUG_LEVELS, DEFAULT_BAUDRATE, DEFAULT_DATABASE_NAME, DEVICE_FULL_INIT,
|
DEBUG_LEVELS, DEFAULT_BAUDRATE, DEFAULT_DATABASE_NAME, DEVICE_FULL_INIT,
|
||||||
DEVICE_INFO, DEVICE_JOINED, DEVICE_REMOVED, DOMAIN, IEEE, LOG_ENTRY,
|
DEVICE_INFO, DEVICE_JOINED, DEVICE_REMOVED, DOMAIN, IEEE, LOG_ENTRY,
|
||||||
LOG_OUTPUT, MODEL, NWK, ORIGINAL, RADIO, RADIO_DESCRIPTION, RAW_INIT,
|
LOG_OUTPUT, MODEL, NWK, ORIGINAL, RADIO, RADIO_DESCRIPTION, RAW_INIT,
|
||||||
SIGNAL_REMOVE, SIGNATURE, TYPE, ZHA, ZHA_GW_MSG, ZIGPY, ZIGPY_DECONZ,
|
SIGNAL_REMOVE, SIGNATURE, TYPE, UNKNOWN_MANUFACTURER, UNKNOWN_MODEL, ZHA,
|
||||||
ZIGPY_XBEE)
|
ZHA_GW_MSG, ZIGPY, ZIGPY_DECONZ, ZIGPY_XBEE)
|
||||||
from .device import DeviceStatus, ZHADevice
|
from .device import DeviceStatus, ZHADevice
|
||||||
from .discovery import (
|
from .discovery import (
|
||||||
async_create_device_entity, async_dispatch_discovery_info,
|
async_create_device_entity, async_dispatch_discovery_info,
|
||||||
async_process_endpoint)
|
async_process_endpoint)
|
||||||
from .patches import apply_application_controller_patch
|
from .patches import apply_application_controller_patch
|
||||||
from .registries import RADIO_TYPES, INPUT_BIND_ONLY_CLUSTERS
|
from .registries import INPUT_BIND_ONLY_CLUSTERS, RADIO_TYPES
|
||||||
from .store import async_get_registry
|
from .store import async_get_registry
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -119,13 +119,8 @@ class ZHAGateway:
|
||||||
"""Handle a device initialization without quirks loaded."""
|
"""Handle a device initialization without quirks loaded."""
|
||||||
if device.nwk == 0x0000:
|
if device.nwk == 0x0000:
|
||||||
return
|
return
|
||||||
endpoint_ids = device.endpoints.keys()
|
|
||||||
ept_id = next((ept_id for ept_id in endpoint_ids if ept_id != 0), None)
|
manuf = device.manufacturer
|
||||||
manufacturer = 'Unknown'
|
|
||||||
model = 'Unknown'
|
|
||||||
if ept_id is not None:
|
|
||||||
manufacturer = device.endpoints[ept_id].manufacturer
|
|
||||||
model = device.endpoints[ept_id].model
|
|
||||||
async_dispatcher_send(
|
async_dispatcher_send(
|
||||||
self._hass,
|
self._hass,
|
||||||
ZHA_GW_MSG,
|
ZHA_GW_MSG,
|
||||||
|
@ -133,8 +128,8 @@ class ZHAGateway:
|
||||||
TYPE: RAW_INIT,
|
TYPE: RAW_INIT,
|
||||||
NWK: device.nwk,
|
NWK: device.nwk,
|
||||||
IEEE: str(device.ieee),
|
IEEE: str(device.ieee),
|
||||||
MODEL: model,
|
MODEL: device.model if device.model else UNKNOWN_MODEL,
|
||||||
ATTR_MANUFACTURER: manufacturer,
|
ATTR_MANUFACTURER: manuf if manuf else UNKNOWN_MANUFACTURER,
|
||||||
SIGNATURE: device.get_signature()
|
SIGNATURE: device.get_signature()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,8 +6,9 @@ import time
|
||||||
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.util import slugify
|
from homeassistant.util import slugify
|
||||||
from .entity import ZhaEntity
|
|
||||||
from .core.const import POWER_CONFIGURATION_CHANNEL, SIGNAL_STATE_ATTR
|
from .core.const import POWER_CONFIGURATION_CHANNEL, SIGNAL_STATE_ATTR
|
||||||
|
from .entity import ZhaEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -39,16 +40,11 @@ class ZhaDeviceEntity(ZhaEntity):
|
||||||
"""Init ZHA endpoint entity."""
|
"""Init ZHA endpoint entity."""
|
||||||
ieee = zha_device.ieee
|
ieee = zha_device.ieee
|
||||||
ieeetail = ''.join(['%02x' % (o, ) for o in ieee[-4:]])
|
ieeetail = ''.join(['%02x' % (o, ) for o in ieee[-4:]])
|
||||||
unique_id = None
|
unique_id = "{}_{}_{}".format(
|
||||||
if zha_device.manufacturer is not None and \
|
slugify(zha_device.manufacturer),
|
||||||
zha_device.model is not None:
|
slugify(zha_device.model),
|
||||||
unique_id = "{}_{}_{}".format(
|
ieeetail,
|
||||||
slugify(zha_device.manufacturer),
|
)
|
||||||
slugify(zha_device.model),
|
|
||||||
ieeetail,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
unique_id = str(ieeetail)
|
|
||||||
|
|
||||||
kwargs['component'] = 'zha'
|
kwargs['component'] = 'zha'
|
||||||
super().__init__(unique_id, zha_device, channels, skip_entity_id=True,
|
super().__init__(unique_id, zha_device, channels, skip_entity_id=True,
|
||||||
|
|
|
@ -11,9 +11,8 @@ from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
from homeassistant.util import slugify
|
from homeassistant.util import slugify
|
||||||
|
|
||||||
from .core.const import (
|
from .core.const import (
|
||||||
DOMAIN, ATTR_MANUFACTURER, DATA_ZHA, DATA_ZHA_BRIDGE_ID, MODEL, NAME,
|
ATTR_MANUFACTURER, DATA_ZHA, DATA_ZHA_BRIDGE_ID, DOMAIN, MODEL, NAME,
|
||||||
SIGNAL_REMOVE
|
SIGNAL_REMOVE)
|
||||||
)
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -32,31 +31,17 @@ class ZhaEntity(RestoreEntity, entity.Entity):
|
||||||
self._force_update = False
|
self._force_update = False
|
||||||
self._should_poll = False
|
self._should_poll = False
|
||||||
self._unique_id = unique_id
|
self._unique_id = unique_id
|
||||||
self._name = None
|
|
||||||
if zha_device.manufacturer and zha_device.model is not None:
|
|
||||||
self._name = "{} {}".format(
|
|
||||||
zha_device.manufacturer,
|
|
||||||
zha_device.model
|
|
||||||
)
|
|
||||||
if not skip_entity_id:
|
if not skip_entity_id:
|
||||||
ieee = zha_device.ieee
|
ieee = zha_device.ieee
|
||||||
ieeetail = ''.join(['%02x' % (o, ) for o in ieee[-4:]])
|
ieeetail = ''.join(['%02x' % (o, ) for o in ieee[-4:]])
|
||||||
if zha_device.manufacturer and zha_device.model is not None:
|
self.entity_id = "{}.{}_{}_{}_{}{}".format(
|
||||||
self.entity_id = "{}.{}_{}_{}_{}{}".format(
|
self._domain,
|
||||||
self._domain,
|
slugify(zha_device.manufacturer),
|
||||||
slugify(zha_device.manufacturer),
|
slugify(zha_device.model),
|
||||||
slugify(zha_device.model),
|
ieeetail,
|
||||||
ieeetail,
|
channels[0].cluster.endpoint.endpoint_id,
|
||||||
channels[0].cluster.endpoint.endpoint_id,
|
kwargs.get(ENTITY_SUFFIX, ''),
|
||||||
kwargs.get(ENTITY_SUFFIX, ''),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.entity_id = "{}.zha_{}_{}{}".format(
|
|
||||||
self._domain,
|
|
||||||
ieeetail,
|
|
||||||
channels[0].cluster.endpoint.endpoint_id,
|
|
||||||
kwargs.get(ENTITY_SUFFIX, ''),
|
|
||||||
)
|
|
||||||
self._state = None
|
self._state = None
|
||||||
self._device_state_attributes = {}
|
self._device_state_attributes = {}
|
||||||
self._zha_device = zha_device
|
self._zha_device = zha_device
|
||||||
|
@ -70,7 +55,7 @@ class ZhaEntity(RestoreEntity, entity.Entity):
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""Return Entity's default name."""
|
"""Return Entity's default name."""
|
||||||
return self._name
|
return self.zha_device.name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self) -> str:
|
def unique_id(self) -> str:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue