* 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
330 lines
12 KiB
Python
330 lines
12 KiB
Python
"""
|
|
Mapping registries for Zigbee Home Automation.
|
|
|
|
For more details about this component, please refer to the documentation at
|
|
https://home-assistant.io/components/zha/
|
|
"""
|
|
|
|
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR
|
|
from homeassistant.components.fan import DOMAIN as FAN
|
|
from homeassistant.components.light import DOMAIN as LIGHT
|
|
from homeassistant.components.lock import DOMAIN as LOCK
|
|
from homeassistant.components.sensor import DOMAIN as SENSOR
|
|
from homeassistant.components.switch import DOMAIN as SWITCH
|
|
|
|
from .const import (
|
|
HUMIDITY,
|
|
TEMPERATURE, ILLUMINANCE, PRESSURE, METERING, ELECTRICAL_MEASUREMENT,
|
|
OCCUPANCY, REPORT_CONFIG_IMMEDIATE, OPENING, ZONE, RADIO_DESCRIPTION,
|
|
REPORT_CONFIG_ASAP, REPORT_CONFIG_DEFAULT, REPORT_CONFIG_MIN_INT,
|
|
REPORT_CONFIG_MAX_INT, REPORT_CONFIG_OP, ACCELERATION, RadioType, RADIO,
|
|
CONTROLLER
|
|
)
|
|
|
|
SMARTTHINGS_HUMIDITY_CLUSTER = 64581
|
|
SMARTTHINGS_ACCELERATION_CLUSTER = 64514
|
|
|
|
DEVICE_CLASS = {}
|
|
SINGLE_INPUT_CLUSTER_DEVICE_CLASS = {}
|
|
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS = {}
|
|
SENSOR_TYPES = {}
|
|
RADIO_TYPES = {}
|
|
BINARY_SENSOR_TYPES = {}
|
|
REMOTE_DEVICE_TYPES = {}
|
|
CLUSTER_REPORT_CONFIGS = {}
|
|
CUSTOM_CLUSTER_MAPPINGS = {}
|
|
EVENT_RELAY_CLUSTERS = []
|
|
CHANNEL_ONLY_CLUSTERS = []
|
|
OUTPUT_CHANNEL_ONLY_CLUSTERS = []
|
|
BINDABLE_CLUSTERS = []
|
|
INPUT_BIND_ONLY_CLUSTERS = []
|
|
BINARY_SENSOR_CLUSTERS = set()
|
|
LIGHT_CLUSTERS = set()
|
|
SWITCH_CLUSTERS = set()
|
|
COMPONENT_CLUSTERS = {
|
|
BINARY_SENSOR: BINARY_SENSOR_CLUSTERS,
|
|
LIGHT: LIGHT_CLUSTERS,
|
|
SWITCH: SWITCH_CLUSTERS
|
|
}
|
|
|
|
|
|
def establish_device_mappings():
|
|
"""Establish mappings between ZCL objects and HA ZHA objects.
|
|
|
|
These cannot be module level, as importing bellows must be done in a
|
|
in a function.
|
|
"""
|
|
from zigpy import zcl
|
|
from zigpy.profiles import zha, zll
|
|
|
|
if zha.PROFILE_ID not in DEVICE_CLASS:
|
|
DEVICE_CLASS[zha.PROFILE_ID] = {}
|
|
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
|
|
return {
|
|
RADIO: bellows.ezsp.EZSP(),
|
|
CONTROLLER: ControllerApplication
|
|
}
|
|
|
|
RADIO_TYPES[RadioType.ezsp.name] = {
|
|
RADIO: get_ezsp_radio,
|
|
RADIO_DESCRIPTION: 'EZSP'
|
|
}
|
|
|
|
def get_xbee_radio():
|
|
import zigpy_xbee.api
|
|
from zigpy_xbee.zigbee.application import ControllerApplication
|
|
return {
|
|
RADIO: zigpy_xbee.api.XBee(),
|
|
CONTROLLER: ControllerApplication
|
|
}
|
|
|
|
RADIO_TYPES[RadioType.xbee.name] = {
|
|
RADIO: get_xbee_radio,
|
|
RADIO_DESCRIPTION: 'XBee'
|
|
}
|
|
|
|
def get_deconz_radio():
|
|
import zigpy_deconz.api
|
|
from zigpy_deconz.zigbee.application import ControllerApplication
|
|
return {
|
|
RADIO: zigpy_deconz.api.Deconz(),
|
|
CONTROLLER: ControllerApplication
|
|
}
|
|
|
|
RADIO_TYPES[RadioType.deconz.name] = {
|
|
RADIO: get_deconz_radio,
|
|
RADIO_DESCRIPTION: 'Deconz'
|
|
}
|
|
|
|
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.LevelControl.cluster_id)
|
|
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.OnOff.cluster_id)
|
|
|
|
CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.general.Basic.cluster_id)
|
|
CHANNEL_ONLY_CLUSTERS.append(
|
|
zcl.clusters.general.PowerConfiguration.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,
|
|
zha.DeviceType.ON_OFF_LIGHT: LIGHT,
|
|
zha.DeviceType.DIMMABLE_LIGHT: LIGHT,
|
|
zha.DeviceType.COLOR_DIMMABLE_LIGHT: LIGHT,
|
|
zha.DeviceType.ON_OFF_LIGHT_SWITCH: SWITCH,
|
|
zha.DeviceType.DIMMER_SWITCH: LIGHT,
|
|
zha.DeviceType.COLOR_DIMMER_SWITCH: LIGHT,
|
|
zha.DeviceType.ON_OFF_BALLAST: SWITCH,
|
|
zha.DeviceType.DIMMABLE_BALLAST: LIGHT,
|
|
zha.DeviceType.ON_OFF_PLUG_IN_UNIT: SWITCH,
|
|
zha.DeviceType.DIMMABLE_PLUG_IN_UNIT: LIGHT,
|
|
zha.DeviceType.COLOR_TEMPERATURE_LIGHT: LIGHT,
|
|
zha.DeviceType.EXTENDED_COLOR_LIGHT: LIGHT
|
|
})
|
|
|
|
DEVICE_CLASS[zll.PROFILE_ID].update({
|
|
zll.DeviceType.ON_OFF_LIGHT: LIGHT,
|
|
zll.DeviceType.ON_OFF_PLUGIN_UNIT: SWITCH,
|
|
zll.DeviceType.DIMMABLE_LIGHT: LIGHT,
|
|
zll.DeviceType.DIMMABLE_PLUGIN_UNIT: LIGHT,
|
|
zll.DeviceType.COLOR_LIGHT: LIGHT,
|
|
zll.DeviceType.EXTENDED_COLOR_LIGHT: LIGHT,
|
|
zll.DeviceType.COLOR_TEMPERATURE_LIGHT: LIGHT
|
|
})
|
|
|
|
SINGLE_INPUT_CLUSTER_DEVICE_CLASS.update({
|
|
zcl.clusters.general.OnOff: SWITCH,
|
|
zcl.clusters.measurement.RelativeHumidity: SENSOR,
|
|
# this works for now but if we hit conflicts we can break it out to
|
|
# a different dict that is keyed by manufacturer
|
|
SMARTTHINGS_HUMIDITY_CLUSTER: SENSOR,
|
|
zcl.clusters.measurement.TemperatureMeasurement: SENSOR,
|
|
zcl.clusters.measurement.PressureMeasurement: SENSOR,
|
|
zcl.clusters.measurement.IlluminanceMeasurement: SENSOR,
|
|
zcl.clusters.smartenergy.Metering: SENSOR,
|
|
zcl.clusters.homeautomation.ElectricalMeasurement: SENSOR,
|
|
zcl.clusters.security.IasZone: BINARY_SENSOR,
|
|
zcl.clusters.measurement.OccupancySensing: BINARY_SENSOR,
|
|
zcl.clusters.hvac.Fan: FAN,
|
|
SMARTTHINGS_ACCELERATION_CLUSTER: BINARY_SENSOR,
|
|
zcl.clusters.general.MultistateInput.cluster_id: SENSOR,
|
|
zcl.clusters.general.AnalogInput.cluster_id: SENSOR,
|
|
zcl.clusters.closures.DoorLock: LOCK
|
|
})
|
|
|
|
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS.update({
|
|
zcl.clusters.general.OnOff: BINARY_SENSOR,
|
|
})
|
|
|
|
SENSOR_TYPES.update({
|
|
zcl.clusters.measurement.RelativeHumidity.cluster_id: HUMIDITY,
|
|
SMARTTHINGS_HUMIDITY_CLUSTER: HUMIDITY,
|
|
zcl.clusters.measurement.TemperatureMeasurement.cluster_id:
|
|
TEMPERATURE,
|
|
zcl.clusters.measurement.PressureMeasurement.cluster_id: PRESSURE,
|
|
zcl.clusters.measurement.IlluminanceMeasurement.cluster_id:
|
|
ILLUMINANCE,
|
|
zcl.clusters.smartenergy.Metering.cluster_id: METERING,
|
|
zcl.clusters.homeautomation.ElectricalMeasurement.cluster_id:
|
|
ELECTRICAL_MEASUREMENT,
|
|
})
|
|
|
|
BINARY_SENSOR_TYPES.update({
|
|
zcl.clusters.measurement.OccupancySensing.cluster_id: OCCUPANCY,
|
|
zcl.clusters.security.IasZone.cluster_id: ZONE,
|
|
zcl.clusters.general.OnOff.cluster_id: OPENING,
|
|
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: [],
|
|
zcl.clusters.general.Commissioning.cluster_id: [],
|
|
zcl.clusters.general.Identify.cluster_id: [],
|
|
zcl.clusters.general.Groups.cluster_id: [],
|
|
zcl.clusters.general.Scenes.cluster_id: [],
|
|
zcl.clusters.general.Partition.cluster_id: [],
|
|
zcl.clusters.general.Ota.cluster_id: [],
|
|
zcl.clusters.general.PowerProfile.cluster_id: [],
|
|
zcl.clusters.general.ApplianceControl.cluster_id: [],
|
|
zcl.clusters.general.PollControl.cluster_id: [],
|
|
zcl.clusters.general.GreenPowerProxy.cluster_id: [],
|
|
zcl.clusters.general.OnOffConfiguration.cluster_id: [],
|
|
zcl.clusters.lightlink.LightLink.cluster_id: [],
|
|
zcl.clusters.general.OnOff.cluster_id: [{
|
|
'attr': 'on_off',
|
|
'config': REPORT_CONFIG_IMMEDIATE
|
|
}],
|
|
zcl.clusters.general.LevelControl.cluster_id: [{
|
|
'attr': 'current_level',
|
|
'config': REPORT_CONFIG_ASAP
|
|
}],
|
|
zcl.clusters.lighting.Color.cluster_id: [{
|
|
'attr': 'current_x',
|
|
'config': REPORT_CONFIG_DEFAULT
|
|
}, {
|
|
'attr': 'current_y',
|
|
'config': REPORT_CONFIG_DEFAULT
|
|
}, {
|
|
'attr': 'color_temperature',
|
|
'config': REPORT_CONFIG_DEFAULT
|
|
}],
|
|
zcl.clusters.measurement.RelativeHumidity.cluster_id: [{
|
|
'attr': 'measured_value',
|
|
'config': (
|
|
REPORT_CONFIG_MIN_INT,
|
|
REPORT_CONFIG_MAX_INT,
|
|
50
|
|
)
|
|
}],
|
|
zcl.clusters.measurement.TemperatureMeasurement.cluster_id: [{
|
|
'attr': 'measured_value',
|
|
'config': (
|
|
REPORT_CONFIG_MIN_INT,
|
|
REPORT_CONFIG_MAX_INT,
|
|
50
|
|
)
|
|
}],
|
|
SMARTTHINGS_ACCELERATION_CLUSTER: [{
|
|
'attr': 'acceleration',
|
|
'config': REPORT_CONFIG_ASAP
|
|
}, {
|
|
'attr': 'x_axis',
|
|
'config': REPORT_CONFIG_ASAP
|
|
}, {
|
|
'attr': 'y_axis',
|
|
'config': REPORT_CONFIG_ASAP
|
|
}, {
|
|
'attr': 'z_axis',
|
|
'config': REPORT_CONFIG_ASAP
|
|
}],
|
|
SMARTTHINGS_HUMIDITY_CLUSTER: [{
|
|
'attr': 'measured_value',
|
|
'config': (
|
|
REPORT_CONFIG_MIN_INT,
|
|
REPORT_CONFIG_MAX_INT,
|
|
50
|
|
)
|
|
}],
|
|
zcl.clusters.measurement.PressureMeasurement.cluster_id: [{
|
|
'attr': 'measured_value',
|
|
'config': REPORT_CONFIG_DEFAULT
|
|
}],
|
|
zcl.clusters.measurement.IlluminanceMeasurement.cluster_id: [{
|
|
'attr': 'measured_value',
|
|
'config': REPORT_CONFIG_DEFAULT
|
|
}],
|
|
zcl.clusters.smartenergy.Metering.cluster_id: [{
|
|
'attr': 'instantaneous_demand',
|
|
'config': REPORT_CONFIG_DEFAULT
|
|
}],
|
|
zcl.clusters.homeautomation.ElectricalMeasurement.cluster_id: [{
|
|
'attr': 'active_power',
|
|
'config': REPORT_CONFIG_DEFAULT
|
|
}],
|
|
zcl.clusters.general.PowerConfiguration.cluster_id: [{
|
|
'attr': 'battery_voltage',
|
|
'config': REPORT_CONFIG_DEFAULT
|
|
}, {
|
|
'attr': 'battery_percentage_remaining',
|
|
'config': REPORT_CONFIG_DEFAULT
|
|
}],
|
|
zcl.clusters.measurement.OccupancySensing.cluster_id: [{
|
|
'attr': 'occupancy',
|
|
'config': REPORT_CONFIG_IMMEDIATE
|
|
}],
|
|
zcl.clusters.hvac.Fan.cluster_id: [{
|
|
'attr': 'fan_mode',
|
|
'config': REPORT_CONFIG_OP
|
|
}],
|
|
zcl.clusters.closures.DoorLock.cluster_id: [{
|
|
'attr': 'lock_state',
|
|
'config': REPORT_CONFIG_IMMEDIATE
|
|
}],
|
|
})
|
|
|
|
BINARY_SENSOR_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
|
|
BINARY_SENSOR_CLUSTERS.add(zcl.clusters.security.IasZone.cluster_id)
|
|
BINARY_SENSOR_CLUSTERS.add(
|
|
zcl.clusters.measurement.OccupancySensing.cluster_id)
|
|
BINARY_SENSOR_CLUSTERS.add(SMARTTHINGS_ACCELERATION_CLUSTER)
|
|
|
|
LIGHT_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
|
|
LIGHT_CLUSTERS.add(zcl.clusters.general.LevelControl.cluster_id)
|
|
LIGHT_CLUSTERS.add(zcl.clusters.lighting.Color.cluster_id)
|
|
|
|
SWITCH_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
|