Add Philips Hue motion sensor config entities to ZHA (#79923)

* Add Hue trigger LED config switch

* Add Hue sensitivity config select

* Use existing consts for channel names

* Add friendly names to config entities

* Follow HA capitalization conventions

* Move Hue motion sensor check to a helper method

* Move helper method to a new helpers file in channels folder
pull/80767/head
TheJulianJES 2022-10-22 02:59:51 +02:00 committed by GitHub
parent 5eb69f38aa
commit 00b0fa6cdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 1 deletions

View File

@ -28,6 +28,7 @@ from ..const import (
SIGNAL_UPDATE_DEVICE,
)
from .base import AttrReportConfig, ClientChannel, ZigbeeChannel, parse_and_log_command
from .helpers import is_hue_motion_sensor
if TYPE_CHECKING:
from . import ChannelPool
@ -152,6 +153,15 @@ class BasicChannel(ZigbeeChannel):
6: "Emergency mains and transfer switch",
}
def __init__(self, cluster: zigpy.zcl.Cluster, ch_pool: ChannelPool) -> None:
"""Initialize Basic channel."""
super().__init__(cluster, ch_pool)
if is_hue_motion_sensor(self):
self.ZCL_INIT_ATTRS = ( # pylint: disable=invalid-name
self.ZCL_INIT_ATTRS.copy()
)
self.ZCL_INIT_ATTRS["trigger_indicator"] = True
@registries.ZIGBEE_CHANNEL_REGISTRY.register(general.BinaryInput.cluster_id)
class BinaryInput(ZigbeeChannel):

View File

@ -0,0 +1,15 @@
"""Helpers for use with ZHA Zigbee channels."""
from .base import ZigbeeChannel
def is_hue_motion_sensor(channel: ZigbeeChannel) -> bool:
"""Return true if the manufacturer and model match known Hue motion sensor models."""
return channel.cluster.endpoint.manufacturer in (
"Philips",
"Signify Netherlands B.V.",
) and channel.cluster.endpoint.model in (
"SML001",
"SML002",
"SML003",
"SML004",
)

View File

@ -1,4 +1,9 @@
"""Measurement channels module for Zigbee Home Automation."""
from __future__ import annotations
from typing import TYPE_CHECKING
import zigpy.zcl
from zigpy.zcl.clusters import measurement
from .. import registries
@ -9,6 +14,10 @@ from ..const import (
REPORT_CONFIG_MIN_INT,
)
from .base import AttrReportConfig, ZigbeeChannel
from .helpers import is_hue_motion_sensor
if TYPE_CHECKING:
from . import ChannelPool
@registries.ZIGBEE_CHANNEL_REGISTRY.register(measurement.FlowMeasurement.cluster_id)
@ -50,6 +59,15 @@ class OccupancySensing(ZigbeeChannel):
AttrReportConfig(attr="occupancy", config=REPORT_CONFIG_IMMEDIATE),
)
def __init__(self, cluster: zigpy.zcl.Cluster, ch_pool: ChannelPool) -> None:
"""Initialize Occupancy channel."""
super().__init__(cluster, ch_pool)
if is_hue_motion_sensor(self):
self.ZCL_INIT_ATTRS = ( # pylint: disable=invalid-name
self.ZCL_INIT_ATTRS.copy()
)
self.ZCL_INIT_ATTRS["sensitivity"] = True
@registries.ZIGBEE_CHANNEL_REGISTRY.register(measurement.PressureMeasurement.cluster_id)
class PressureMeasurement(ZigbeeChannel):

View File

@ -22,6 +22,7 @@ from .core import discovery
from .core.const import (
CHANNEL_IAS_WD,
CHANNEL_INOVELLI,
CHANNEL_OCCUPANCY,
CHANNEL_ON_OFF,
DATA_ZHA,
SIGNAL_ADD_ENTITIES,
@ -259,13 +260,57 @@ class AqaraMotionSensitivities(types.enum8):
channel_names="opple_cluster", models={"lumi.motion.ac01", "lumi.motion.ac02"}
)
class AqaraMotionSensitivity(ZCLEnumSelectEntity, id_suffix="motion_sensitivity"):
"""Representation of a ZHA on off transition time configuration entity."""
"""Representation of a ZHA motion sensitivity configuration entity."""
_select_attr = "motion_sensitivity"
_enum = AqaraMotionSensitivities
_attr_name = "Motion sensitivity"
class HueV1MotionSensitivities(types.enum8):
"""Hue v1 motion sensitivities."""
Low = 0x00
Medium = 0x01
High = 0x02
@CONFIG_DIAGNOSTIC_MATCH(
channel_names=CHANNEL_OCCUPANCY,
manufacturers={"Philips", "Signify Netherlands B.V."},
models={"SML001"},
)
class HueV1MotionSensitivity(ZCLEnumSelectEntity, id_suffix="motion_sensitivity"):
"""Representation of a ZHA motion sensitivity configuration entity."""
_select_attr = "sensitivity"
_attr_name = "Hue motion sensitivity"
_enum = HueV1MotionSensitivities
class HueV2MotionSensitivities(types.enum8):
"""Hue v2 motion sensitivities."""
Lowest = 0x00
Low = 0x01
Medium = 0x02
High = 0x03
Highest = 0x04
@CONFIG_DIAGNOSTIC_MATCH(
channel_names=CHANNEL_OCCUPANCY,
manufacturers={"Philips", "Signify Netherlands B.V."},
models={"SML002", "SML003", "SML004"},
)
class HueV2MotionSensitivity(ZCLEnumSelectEntity, id_suffix="motion_sensitivity"):
"""Representation of a ZHA motion sensitivity configuration entity."""
_select_attr = "sensitivity"
_attr_name = "Hue motion sensitivity"
_enum = HueV2MotionSensitivities
class AqaraMonitoringModess(types.enum8):
"""Aqara monitoring modes."""

View File

@ -19,6 +19,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .core import discovery
from .core.const import (
CHANNEL_BASIC,
CHANNEL_INOVELLI,
CHANNEL_ON_OFF,
DATA_ZHA,
@ -305,6 +306,20 @@ class XiaomiPlugPowerOutageMemorySwitch(
_attr_name = "Power outage memory"
@CONFIG_DIAGNOSTIC_MATCH(
channel_names=CHANNEL_BASIC,
manufacturers={"Philips", "Signify Netherlands B.V."},
models={"SML001", "SML002", "SML003", "SML004"},
)
class HueMotionTriggerIndicatorSwitch(
ZHASwitchConfigurationEntity, id_suffix="trigger_indicator"
):
"""Representation of a ZHA motion triggering configuration entity."""
_zcl_attribute: str = "trigger_indicator"
_attr_name = "LED trigger indicator"
@CONFIG_DIAGNOSTIC_MATCH(
channel_names="ikea_airpurifier",
models={"STARKVIND Air purifier", "STARKVIND Air purifier table"},