Misc. ZHA enhancements (#24559)
* add nwk to device info * input bind only cluster support * cleanup channel only clusters * dirty hack to correct xiaomi vibration sensor * exclude remaining remote binary sensors * review comments * fix comment
This commit is contained in:
parent
b782ed6bbb
commit
c173a3be44
4 changed files with 78 additions and 20 deletions
|
@ -18,7 +18,7 @@ from .const import (
|
|||
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
|
||||
BATTERY_OR_UNKNOWN, NWK
|
||||
)
|
||||
from .channels import EventRelayChannel
|
||||
|
||||
|
@ -189,6 +189,7 @@ class ZHADevice:
|
|||
ieee = str(self.ieee)
|
||||
return {
|
||||
IEEE: ieee,
|
||||
NWK: self.nwk,
|
||||
ATTR_MANUFACTURER: self.manufacturer,
|
||||
MODEL: self.model,
|
||||
NAME: self.name or ieee,
|
||||
|
@ -390,7 +391,7 @@ class ZHADevice:
|
|||
manufacturer=manufacturer
|
||||
)
|
||||
_LOGGER.debug(
|
||||
'set: %s for attr: %s to cluster: %s for entity: %s - res: %s',
|
||||
'set: %s for attr: %s to cluster: %s for ept: %s - res: %s',
|
||||
value,
|
||||
attribute,
|
||||
cluster_id,
|
||||
|
|
|
@ -21,9 +21,10 @@ from .const import (
|
|||
SENSOR_TYPE, UNKNOWN, GENERIC, POWER_CONFIGURATION_CHANNEL
|
||||
)
|
||||
from .registries import (
|
||||
BINARY_SENSOR_TYPES, NO_SENSOR_CLUSTERS, EVENT_RELAY_CLUSTERS,
|
||||
BINARY_SENSOR_TYPES, CHANNEL_ONLY_CLUSTERS, EVENT_RELAY_CLUSTERS,
|
||||
SENSOR_TYPES, DEVICE_CLASS, COMPONENT_CLUSTERS,
|
||||
SINGLE_INPUT_CLUSTER_DEVICE_CLASS, SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS
|
||||
SINGLE_INPUT_CLUSTER_DEVICE_CLASS, SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS,
|
||||
OUTPUT_CHANNEL_ONLY_CLUSTERS, REMOTE_DEVICE_TYPES
|
||||
)
|
||||
from ..device_entity import ZhaDeviceEntity
|
||||
|
||||
|
@ -87,6 +88,12 @@ def async_process_endpoint(
|
|||
def _async_create_cluster_channel(cluster, zha_device, is_new_join,
|
||||
channels=None, channel_class=None):
|
||||
"""Create a cluster channel and attach it to a device."""
|
||||
# really ugly hack to deal with xiaomi using the door lock cluster
|
||||
# incorrectly.
|
||||
if hasattr(cluster, 'ep_attribute') and \
|
||||
cluster.ep_attribute == 'multistate_input':
|
||||
channel_class = AttributeListeningChannel
|
||||
# end of ugly hack
|
||||
if channel_class is None:
|
||||
channel_class = ZIGBEE_CHANNEL_REGISTRY.get(cluster.cluster_id,
|
||||
AttributeListeningChannel)
|
||||
|
@ -161,17 +168,18 @@ def _async_handle_single_cluster_matches(hass, endpoint, zha_device,
|
|||
profile_clusters, device_key,
|
||||
is_new_join):
|
||||
"""Dispatch single cluster matches to HA components."""
|
||||
from zigpy.zcl.clusters.general import OnOff
|
||||
cluster_matches = []
|
||||
cluster_match_results = []
|
||||
for cluster in endpoint.in_clusters.values():
|
||||
# don't let profiles prevent these channels from being created
|
||||
if cluster.cluster_id in NO_SENSOR_CLUSTERS:
|
||||
if cluster.cluster_id in CHANNEL_ONLY_CLUSTERS:
|
||||
cluster_match_results.append(
|
||||
_async_handle_channel_only_cluster_match(
|
||||
zha_device,
|
||||
cluster,
|
||||
is_new_join,
|
||||
))
|
||||
continue
|
||||
|
||||
if cluster.cluster_id not in profile_clusters:
|
||||
cluster_match_results.append(_async_handle_single_cluster_match(
|
||||
|
@ -184,15 +192,33 @@ def _async_handle_single_cluster_matches(hass, endpoint, zha_device,
|
|||
))
|
||||
|
||||
for cluster in endpoint.out_clusters.values():
|
||||
if cluster.cluster_id in OUTPUT_CHANNEL_ONLY_CLUSTERS:
|
||||
cluster_match_results.append(
|
||||
_async_handle_channel_only_cluster_match(
|
||||
zha_device,
|
||||
cluster,
|
||||
is_new_join,
|
||||
))
|
||||
continue
|
||||
|
||||
device_type = cluster.endpoint.device_type
|
||||
profile_id = cluster.endpoint.profile_id
|
||||
|
||||
if cluster.cluster_id not in profile_clusters:
|
||||
cluster_match_results.append(_async_handle_single_cluster_match(
|
||||
hass,
|
||||
zha_device,
|
||||
cluster,
|
||||
device_key,
|
||||
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS,
|
||||
is_new_join,
|
||||
))
|
||||
# prevent remotes and controllers from getting entities
|
||||
if not (cluster.cluster_id == OnOff.cluster_id and profile_id in
|
||||
REMOTE_DEVICE_TYPES and device_type in
|
||||
REMOTE_DEVICE_TYPES[profile_id]):
|
||||
cluster_match_results.append(
|
||||
_async_handle_single_cluster_match(
|
||||
hass,
|
||||
zha_device,
|
||||
cluster,
|
||||
device_key,
|
||||
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS,
|
||||
is_new_join,
|
||||
)
|
||||
)
|
||||
|
||||
if cluster.cluster_id in EVENT_RELAY_CLUSTERS:
|
||||
_async_create_cluster_channel(
|
||||
|
|
|
@ -32,7 +32,7 @@ from .discovery import (
|
|||
async_create_device_entity, async_dispatch_discovery_info,
|
||||
async_process_endpoint)
|
||||
from .patches import apply_application_controller_patch
|
||||
from .registries import RADIO_TYPES
|
||||
from .registries import RADIO_TYPES, INPUT_BIND_ONLY_CLUSTERS
|
||||
from .store import async_get_registry
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -274,8 +274,10 @@ class ZHAGateway:
|
|||
)
|
||||
if endpoint_id != 0:
|
||||
for cluster in endpoint.in_clusters.values():
|
||||
cluster.bind_only = False
|
||||
cluster.bind_only = \
|
||||
cluster.cluster_id in INPUT_BIND_ONLY_CLUSTERS
|
||||
for cluster in endpoint.out_clusters.values():
|
||||
# output clusters are always bind only
|
||||
cluster.bind_only = True
|
||||
else:
|
||||
is_rejoin = is_new_join is True
|
||||
|
|
|
@ -30,11 +30,14 @@ SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS = {}
|
|||
SENSOR_TYPES = {}
|
||||
RADIO_TYPES = {}
|
||||
BINARY_SENSOR_TYPES = {}
|
||||
REMOTE_DEVICE_TYPES = {}
|
||||
CLUSTER_REPORT_CONFIGS = {}
|
||||
CUSTOM_CLUSTER_MAPPINGS = {}
|
||||
EVENT_RELAY_CLUSTERS = []
|
||||
NO_SENSOR_CLUSTERS = []
|
||||
CHANNEL_ONLY_CLUSTERS = []
|
||||
OUTPUT_CHANNEL_ONLY_CLUSTERS = []
|
||||
BINDABLE_CLUSTERS = []
|
||||
INPUT_BIND_ONLY_CLUSTERS = []
|
||||
BINARY_SENSOR_CLUSTERS = set()
|
||||
LIGHT_CLUSTERS = set()
|
||||
SWITCH_CLUSTERS = set()
|
||||
|
@ -59,6 +62,11 @@ def establish_device_mappings():
|
|||
if zll.PROFILE_ID not in DEVICE_CLASS:
|
||||
DEVICE_CLASS[zll.PROFILE_ID] = {}
|
||||
|
||||
if zha.PROFILE_ID not in REMOTE_DEVICE_TYPES:
|
||||
REMOTE_DEVICE_TYPES[zha.PROFILE_ID] = []
|
||||
if zll.PROFILE_ID not in REMOTE_DEVICE_TYPES:
|
||||
REMOTE_DEVICE_TYPES[zll.PROFILE_ID] = []
|
||||
|
||||
def get_ezsp_radio():
|
||||
import bellows.ezsp
|
||||
from bellows.zigbee.application import ControllerApplication
|
||||
|
@ -101,15 +109,21 @@ def establish_device_mappings():
|
|||
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.LevelControl.cluster_id)
|
||||
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.OnOff.cluster_id)
|
||||
|
||||
NO_SENSOR_CLUSTERS.append(zcl.clusters.general.Basic.cluster_id)
|
||||
NO_SENSOR_CLUSTERS.append(
|
||||
CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.general.Basic.cluster_id)
|
||||
CHANNEL_ONLY_CLUSTERS.append(
|
||||
zcl.clusters.general.PowerConfiguration.cluster_id)
|
||||
NO_SENSOR_CLUSTERS.append(zcl.clusters.lightlink.LightLink.cluster_id)
|
||||
CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.lightlink.LightLink.cluster_id)
|
||||
|
||||
OUTPUT_CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.general.Scenes.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.lighting.Color.cluster_id)
|
||||
|
||||
INPUT_BIND_ONLY_CLUSTERS.append(
|
||||
zcl.clusters.lightlink.LightLink.cluster_id
|
||||
)
|
||||
|
||||
DEVICE_CLASS[zha.PROFILE_ID].update({
|
||||
zha.DeviceType.SMART_PLUG: SWITCH,
|
||||
zha.DeviceType.LEVEL_CONTROLLABLE_OUTPUT: LIGHT,
|
||||
|
@ -181,6 +195,21 @@ def establish_device_mappings():
|
|||
SMARTTHINGS_ACCELERATION_CLUSTER: ACCELERATION,
|
||||
})
|
||||
|
||||
zhap = zha.PROFILE_ID
|
||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.NON_COLOR_SCENE_CONTROLLER)
|
||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.NON_COLOR_CONTROLLER)
|
||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_SCENE_CONTROLLER)
|
||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_CONTROLLER)
|
||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.REMOTE_CONTROL)
|
||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.SCENE_SELECTOR)
|
||||
|
||||
zllp = zll.PROFILE_ID
|
||||
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.COLOR_CONTROLLER)
|
||||
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.COLOR_SCENE_CONTROLLER)
|
||||
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.CONTROLLER)
|
||||
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.SCENE_CONTROLLER)
|
||||
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.CONTROL_BRIDGE)
|
||||
|
||||
CLUSTER_REPORT_CONFIGS.update({
|
||||
zcl.clusters.general.Alarms.cluster_id: [],
|
||||
zcl.clusters.general.Basic.cluster_id: [],
|
||||
|
|
Loading…
Add table
Reference in a new issue