Fix ZHA startup failure with the Konke button (#92144)

* Ensure devices with bad cluster subclasses do not prevent startup

* Explicitly unit test an affected SML001 device

* Do not use invalid `hue_occupancy` attribute name

* Actually remove `hue_occupancy`

* Bump ZHA dependencies
This commit is contained in:
puddly 2023-04-27 18:35:07 -04:00 committed by GitHub
parent cdbffee781
commit 9d0dd0b784
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 198 additions and 11 deletions

View File

@ -22,6 +22,7 @@ from .core import discovery
from .core.const import (
CLUSTER_HANDLER_ACCELEROMETER,
CLUSTER_HANDLER_BINARY_INPUT,
CLUSTER_HANDLER_HUE_OCCUPANCY,
CLUSTER_HANDLER_OCCUPANCY,
CLUSTER_HANDLER_ON_OFF,
CLUSTER_HANDLER_ZONE,
@ -130,6 +131,11 @@ class Occupancy(BinarySensor):
_attr_device_class: BinarySensorDeviceClass = BinarySensorDeviceClass.OCCUPANCY
@MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_HUE_OCCUPANCY)
class HueOccupancy(Occupancy):
"""ZHA Hue occupancy."""
@STRICT_MATCH(cluster_handler_names=CLUSTER_HANDLER_ON_OFF)
class Opening(BinarySensor):
"""ZHA OnOff BinarySensor."""

View File

@ -347,7 +347,7 @@ class OnOffClientClusterHandler(ClientClusterHandler):
class OnOffClusterHandler(ClusterHandler):
"""Cluster handler for the OnOff Zigbee cluster."""
ON_OFF = 0
ON_OFF = general.OnOff.attributes_by_name["on_off"].id
REPORT_CONFIG = (AttrReportConfig(attr="on_off", config=REPORT_CONFIG_IMMEDIATE),)
ZCL_INIT_ATTRS = {
"start_up_on_off": True,
@ -374,6 +374,15 @@ class OnOffClusterHandler(ClusterHandler):
if self.cluster.endpoint.model == "TS011F":
self.ZCL_INIT_ATTRS["child_lock"] = True
@classmethod
def matches(cls, cluster: zigpy.zcl.Cluster, endpoint: Endpoint) -> bool:
"""Filter the cluster match for specific devices."""
return not (
cluster.endpoint.device.manufacturer == "Konke"
and cluster.endpoint.device.model
in ("3AFE280100510001", "3AFE170100510001")
)
@property
def on_off(self) -> bool | None:
"""Return cached value of on/off attribute."""

View File

@ -78,6 +78,7 @@ CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT = "electrical_measurement"
CLUSTER_HANDLER_EVENT_RELAY = "event_relay"
CLUSTER_HANDLER_FAN = "fan"
CLUSTER_HANDLER_HUMIDITY = "humidity"
CLUSTER_HANDLER_HUE_OCCUPANCY = "philips_occupancy"
CLUSTER_HANDLER_SOIL_MOISTURE = "soil_moisture"
CLUSTER_HANDLER_LEAF_WETNESS = "leaf_wetness"
CLUSTER_HANDLER_IAS_ACE = "ias_ace"

View File

@ -20,10 +20,10 @@
"zigpy_znp"
],
"requirements": [
"bellows==0.35.1",
"bellows==0.35.2",
"pyserial==3.5",
"pyserial-asyncio==0.6",
"zha-quirks==0.0.97",
"zha-quirks==0.0.98",
"zigpy-deconz==0.21.0",
"zigpy==0.55.0",
"zigpy-xbee==0.18.0",

View File

@ -20,9 +20,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .core import discovery
from .core.const import (
CLUSTER_HANDLER_HUE_OCCUPANCY,
CLUSTER_HANDLER_IAS_WD,
CLUSTER_HANDLER_INOVELLI,
CLUSTER_HANDLER_OCCUPANCY,
CLUSTER_HANDLER_ON_OFF,
DATA_ZHA,
SIGNAL_ADD_ENTITIES,
@ -367,7 +367,7 @@ class HueV1MotionSensitivities(types.enum8):
@CONFIG_DIAGNOSTIC_MATCH(
cluster_handler_names=CLUSTER_HANDLER_OCCUPANCY,
cluster_handler_names=CLUSTER_HANDLER_HUE_OCCUPANCY,
manufacturers={"Philips", "Signify Netherlands B.V."},
models={"SML001"},
)
@ -390,7 +390,7 @@ class HueV2MotionSensitivities(types.enum8):
@CONFIG_DIAGNOSTIC_MATCH(
cluster_handler_names=CLUSTER_HANDLER_OCCUPANCY,
cluster_handler_names=CLUSTER_HANDLER_HUE_OCCUPANCY,
manufacturers={"Philips", "Signify Netherlands B.V."},
models={"SML002", "SML003", "SML004"},
)

View File

@ -428,7 +428,7 @@ beautifulsoup4==4.11.1
# beewi_smartclim==0.0.10
# homeassistant.components.zha
bellows==0.35.1
bellows==0.35.2
# homeassistant.components.bmw_connected_drive
bimmer_connected==0.13.0
@ -2709,7 +2709,7 @@ zeroconf==0.58.2
zeversolar==0.3.1
# homeassistant.components.zha
zha-quirks==0.0.97
zha-quirks==0.0.98
# homeassistant.components.zhong_hong
zhong_hong_hvac==1.0.9

View File

@ -361,7 +361,7 @@ base36==0.1.1
beautifulsoup4==4.11.1
# homeassistant.components.zha
bellows==0.35.1
bellows==0.35.2
# homeassistant.components.bmw_connected_drive
bimmer_connected==0.13.0
@ -1964,7 +1964,7 @@ zeroconf==0.58.2
zeversolar==0.3.1
# homeassistant.components.zha
zha-quirks==0.0.97
zha-quirks==0.0.98
# homeassistant.components.zha
zigpy-deconz==0.21.0

View File

@ -240,6 +240,15 @@ def zigpy_device_mock(zigpy_app_controller):
):
common.patch_cluster(cluster)
if attributes is not None:
for ep_id, clusters in attributes.items():
for cluster_name, attrs in clusters.items():
cluster = getattr(device.endpoints[ep_id], cluster_name)
for name, value in attrs.items():
attr_id = cluster.find_attribute(name).id
cluster._attr_cache[attr_id] = value
return device
return _mock_dev

View File

@ -10,16 +10,26 @@ from zigpy.const import (
SIG_MODEL,
SIG_NODE_DESC,
)
from zigpy.profiles import zha
from zigpy.profiles import zha, zll
from zigpy.types import Bool, uint8_t
from zigpy.zcl.clusters.closures import DoorLock
from zigpy.zcl.clusters.general import (
Basic,
Groups,
Identify,
LevelControl,
MultistateInput,
OnOff,
Ota,
PowerConfiguration,
Scenes,
)
from zigpy.zcl.clusters.lighting import Color
from zigpy.zcl.clusters.measurement import (
IlluminanceMeasurement,
OccupancySensing,
TemperatureMeasurement,
)
DEV_SIG_CLUSTER_HANDLERS = "cluster_handlers"
DEV_SIG_DEV_NO = "device_no"
@ -5373,4 +5383,156 @@ DEVICES = [
},
},
},
{
DEV_SIG_DEV_NO: 100,
SIG_MANUFACTURER: "Konke",
SIG_MODEL: "3AFE170100510001",
SIG_NODE_DESC: b"\x02@\x80\x02\x10RR\x00\x00,R\x00\x00",
SIG_ENDPOINTS: {
1: {
PROFILE_ID: 260,
DEVICE_TYPE: zha.DeviceType.ON_OFF_OUTPUT,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
],
OUTPUT_CLUSTERS: [
Identify.cluster_id,
],
}
},
DEV_SIG_EVT_CLUSTER_HANDLERS: [],
DEV_SIG_ENT_MAP: {
("button", "00:11:22:33:44:55:66:77-1-3"): {
DEV_SIG_CLUSTER_HANDLERS: ["identify"],
DEV_SIG_ENT_MAP_CLASS: "ZHAIdentifyButton",
DEV_SIG_ENT_MAP_ID: "button.konke_3afe170100510001_identify",
},
("sensor", "00:11:22:33:44:55:66:77-1-1"): {
DEV_SIG_CLUSTER_HANDLERS: ["power"],
DEV_SIG_ENT_MAP_CLASS: "Battery",
DEV_SIG_ENT_MAP_ID: "sensor.konke_3afe170100510001_battery",
},
("sensor", "00:11:22:33:44:55:66:77-1-0-rssi"): {
DEV_SIG_CLUSTER_HANDLERS: ["basic"],
DEV_SIG_ENT_MAP_CLASS: "RSSISensor",
DEV_SIG_ENT_MAP_ID: "sensor.konke_3afe170100510001_rssi",
},
("sensor", "00:11:22:33:44:55:66:77-1-0-lqi"): {
DEV_SIG_CLUSTER_HANDLERS: ["basic"],
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
DEV_SIG_ENT_MAP_ID: "sensor.konke_3afe170100510001_lqi",
},
},
},
{
DEV_SIG_DEV_NO: 101,
SIG_MANUFACTURER: "Philips",
SIG_MODEL: "SML001",
SIG_NODE_DESC: b"\x02@\x80\x0b\x10Y?\x00\x00\x00?\x00\x00",
SIG_ENDPOINTS: {
1: {
PROFILE_ID: zll.PROFILE_ID,
DEVICE_TYPE: zll.DeviceType.ON_OFF_SENSOR,
INPUT_CLUSTERS: [Basic.cluster_id],
OUTPUT_CLUSTERS: [
Basic.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
LevelControl.cluster_id,
Color.cluster_id,
],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
IlluminanceMeasurement.cluster_id,
TemperatureMeasurement.cluster_id,
OccupancySensing.cluster_id,
],
OUTPUT_CLUSTERS: [
Ota.cluster_id,
],
},
},
DEV_SIG_ATTRIBUTES: {
2: {
"basic": {
"trigger_indicator": Bool(False),
},
"philips_occupancy": {
"sensitivity": uint8_t(1),
},
}
},
DEV_SIG_EVT_CLUSTER_HANDLERS: [
"1:0x0005",
"1:0x0006",
"1:0x0008",
"1:0x0300",
"2:0x0019",
],
DEV_SIG_ENT_MAP: {
("button", "00:11:22:33:44:55:66:77-2-3"): {
DEV_SIG_CLUSTER_HANDLERS: ["identify"],
DEV_SIG_ENT_MAP_CLASS: "ZHAIdentifyButton",
DEV_SIG_ENT_MAP_ID: "button.philips_sml001_identify",
},
("sensor", "00:11:22:33:44:55:66:77-2-1"): {
DEV_SIG_CLUSTER_HANDLERS: ["power"],
DEV_SIG_ENT_MAP_CLASS: "Battery",
DEV_SIG_ENT_MAP_ID: "sensor.philips_sml001_battery",
},
("sensor", "00:11:22:33:44:55:66:77-1-0-rssi"): {
DEV_SIG_CLUSTER_HANDLERS: ["basic"],
DEV_SIG_ENT_MAP_CLASS: "RSSISensor",
DEV_SIG_ENT_MAP_ID: "sensor.philips_sml001_rssi",
},
("sensor", "00:11:22:33:44:55:66:77-1-0-lqi"): {
DEV_SIG_CLUSTER_HANDLERS: ["basic"],
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
DEV_SIG_ENT_MAP_ID: "sensor.philips_sml001_lqi",
},
("binary_sensor", "00:11:22:33:44:55:66:77-1-6"): {
DEV_SIG_CLUSTER_HANDLERS: ["on_off"],
DEV_SIG_ENT_MAP_CLASS: "Motion",
DEV_SIG_ENT_MAP_ID: "binary_sensor.philips_sml001_motion",
},
("sensor", "00:11:22:33:44:55:66:77-2-1024"): {
DEV_SIG_CLUSTER_HANDLERS: ["illuminance"],
DEV_SIG_ENT_MAP_CLASS: "Illuminance",
DEV_SIG_ENT_MAP_ID: "sensor.philips_sml001_illuminance",
},
("binary_sensor", "00:11:22:33:44:55:66:77-2-1030"): {
DEV_SIG_CLUSTER_HANDLERS: ["philips_occupancy"],
DEV_SIG_ENT_MAP_CLASS: "HueOccupancy",
DEV_SIG_ENT_MAP_ID: "binary_sensor.philips_sml001_occupancy",
},
("sensor", "00:11:22:33:44:55:66:77-2-1026"): {
DEV_SIG_CLUSTER_HANDLERS: ["temperature"],
DEV_SIG_ENT_MAP_CLASS: "Temperature",
DEV_SIG_ENT_MAP_ID: "sensor.philips_sml001_temperature",
},
("switch", "00:11:22:33:44:55:66:77-2-0-trigger_indicator"): {
DEV_SIG_CLUSTER_HANDLERS: ["basic"],
DEV_SIG_ENT_MAP_CLASS: "HueMotionTriggerIndicatorSwitch",
DEV_SIG_ENT_MAP_ID: "switch.philips_sml001_led_trigger_indicator",
},
("select", "00:11:22:33:44:55:66:77-2-1030-motion_sensitivity"): {
DEV_SIG_CLUSTER_HANDLERS: ["philips_occupancy"],
DEV_SIG_ENT_MAP_CLASS: "HueV1MotionSensitivity",
DEV_SIG_ENT_MAP_ID: "select.philips_sml001_hue_motion_sensitivity",
},
},
},
]