Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support power/energy for more Aqara (H1) switches, add devices #2784

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions tests/test_quirks.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,6 @@ def _check_range(cluster: zcl.Cluster) -> bool:
# Some quirks do not yet have model info:
zhaquirks.xbee.xbee_io.XBeeSensor,
zhaquirks.xbee.xbee3_io.XBee3Sensor,
zhaquirks.xiaomi.aqara.opple_switch.XiaomiOpple2ButtonSwitchFace2,
zhaquirks.xiaomi.aqara.opple_switch.XiaomiOpple2ButtonSwitchFace1,
zhaquirks.tuya.ts0201.MoesTemperatureHumidtySensorWithScreen,
zhaquirks.smartthings.tag_v4.SmartThingsTagV4,
zhaquirks.smartthings.multi.SmartthingsMultiPurposeSensor,
Expand Down
4 changes: 0 additions & 4 deletions zhaquirks/xiaomi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,10 +542,6 @@ class DeviceTemperatureCluster(LocalDataCluster, DeviceTemperature):
"""Device Temperature Cluster."""


class XiaomiMeteringCluster(LocalDataCluster, Metering):
"""Xiaomi Metering Cluster."""


class TemperatureMeasurementCluster(CustomCluster, TemperatureMeasurement):
"""Temperature cluster that filters out invalid temperature readings."""

Expand Down
12 changes: 7 additions & 5 deletions zhaquirks/xiaomi/aqara/opple_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@
VALUE,
ZHA_SEND_EVENT,
)
from zhaquirks.xiaomi import LUMI, BasicCluster, XiaomiCustomDevice
from zhaquirks.xiaomi import (
LUMI,
BasicCluster,
XiaomiAqaraE1Cluster,
XiaomiCustomDevice,
)

PRESS_TYPES = {0: "hold", 1: "single", 2: "double", 3: "triple", 255: "release"}
STATUS_TYPE_ATTR = 0x0055 # decimal = 85
Expand Down Expand Up @@ -91,7 +96,6 @@
COMMAND_6_HOLD = "6_hold"
COMMAND_6_RELEASE = "6_release"

OPPLE_CLUSTER_ID = 0xFCC0
OPPLE_MFG_CODE = 0x115F


Expand Down Expand Up @@ -129,11 +133,9 @@ def _update_attribute(self, attrid, value):
super()._update_attribute(0, action)


class OppleCluster(CustomCluster):
class OppleCluster(XiaomiAqaraE1Cluster):
"""Opple cluster."""

ep_attribute = "opple_cluster"
cluster_id = OPPLE_CLUSTER_ID
attributes = {
0x0009: ("mode", types.uint8_t, True),
}
Expand Down
142 changes: 49 additions & 93 deletions zhaquirks/xiaomi/aqara/opple_switch.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Xiaomi aqara single key wall switch devices."""
"""Xiaomi Aqara wall switch devices. Also see switch_h1 files similar H1 rocker switches."""
import copy
from enum import Enum

Expand Down Expand Up @@ -33,18 +33,22 @@
ENDPOINT_ID,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PRESS_TYPE,
PROFILE_ID,
VALUE,
ZHA_SEND_EVENT,
)
from zhaquirks.xiaomi import (
LUMI,
AnalogInputCluster,
BasicCluster,
DeviceTemperatureCluster,
ElectricalMeasurementCluster,
MeteringCluster,
OnOffCluster,
XiaomiCustomDevice,
XiaomiMeteringCluster,
)

from .opple_remote import MultistateInputCluster, OppleCluster
Expand Down Expand Up @@ -85,7 +89,6 @@ class OppleSwitchCluster(OppleCluster):
"""Xiaomi mfg cluster implementation."""

attributes = copy.deepcopy(OppleCluster.attributes)

attributes.update(
{
0x0002: ("power_outage_count", t.uint8_t, True),
Expand Down Expand Up @@ -124,28 +127,29 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
INPUT_CLUSTERS: [
BasicCluster,
DeviceTemperatureCluster, # 2
Identify.cluster_id, # 3
Groups.cluster_id, # 4
Scenes.cluster_id, # 5
OnOffCluster, # 6
Alarms.cluster_id, # 9
MultistateInputCluster, # 18
XiaomiMeteringCluster, # 0x0702
OppleSwitchCluster, # 0xFCC0 / 64704
DeviceTemperatureCluster,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOffCluster,
Alarms.cluster_id,
MultistateInputCluster,
MeteringCluster,
ElectricalMeasurementCluster,
OppleSwitchCluster,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
2: {
DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
INPUT_CLUSTERS: [
BasicCluster,
Identify.cluster_id, # 3
Groups.cluster_id, # 4
Scenes.cluster_id, # 5
OnOffCluster, # 6
MultistateInputCluster, # 18
OppleSwitchCluster, # 0xFCC0 / 64704
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOffCluster,
MultistateInputCluster,
OppleSwitchCluster,
],
OUTPUT_CLUSTERS: [],
},
Expand All @@ -154,7 +158,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
AnalogInput.cluster_id, # 12
AnalogInputCluster,
],
OUTPUT_CLUSTERS: [],
},
Expand All @@ -163,7 +167,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
AnalogInput.cluster_id, # 12
AnalogInput.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
Expand All @@ -172,7 +176,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
MultistateInputCluster, # 18
MultistateInputCluster,
],
OUTPUT_CLUSTERS: [],
},
Expand All @@ -181,7 +185,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
MultistateInputCluster, # 18
MultistateInputCluster,
],
OUTPUT_CLUSTERS: [],
},
Expand All @@ -190,7 +194,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
MultistateInputCluster, # 18
MultistateInputCluster,
],
OUTPUT_CLUSTERS: [],
},
Expand All @@ -199,7 +203,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
MultistateInputCluster, # 18
MultistateInputCluster,
],
OUTPUT_CLUSTERS: [],
},
Expand Down Expand Up @@ -273,23 +277,22 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
"""Xiaomi Opple 2 Button Switch. Face 1."""

device_automation_triggers = XiaomiOpple2ButtonSwitchBase.device_automation_triggers

signature = {
MODELS_INFO: [(LUMI, "lumi.switch.b2naus01")],
ENDPOINTS: {
# input_clusters=[0, 2, 3, 4, 5, 6, 18, 64704], output_clusters=[10, 25]
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id, # 0
DeviceTemperatureCluster.cluster_id, # 2
Identify.cluster_id, # 3
Groups.cluster_id, # 4
Scenes.cluster_id, # 5
OnOff.cluster_id, # 6
MultistateInputCluster.cluster_id, # 18
OppleSwitchCluster.cluster_id, # 0xFCC0 / 64704
Basic.cluster_id,
DeviceTemperatureCluster.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
MultistateInputCluster.cluster_id,
OppleSwitchCluster.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
Expand All @@ -298,13 +301,13 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id, # 0
Identify.cluster_id, # 3
Groups.cluster_id, # 4
Scenes.cluster_id, # 5
OnOff.cluster_id, # 6
MultistateInputCluster.cluster_id, # 18
OppleSwitchCluster.cluster_id, # 0xFCC0 / 64704
Basic.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
MultistateInputCluster.cluster_id,
OppleSwitchCluster.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
Expand All @@ -313,7 +316,7 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
AnalogInput.cluster_id, # 12
AnalogInput.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
Expand All @@ -322,7 +325,7 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
AnalogInput.cluster_id, # 12
AnalogInput.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
Expand All @@ -331,7 +334,7 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
MultistateInputCluster.cluster_id, # 18
MultistateInputCluster.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
Expand All @@ -340,7 +343,7 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
MultistateInputCluster.cluster_id, # 18
MultistateInputCluster.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
Expand All @@ -349,54 +352,7 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
MultistateInputCluster.cluster_id, # 18
],
OUTPUT_CLUSTERS: [],
},
242: {
PROFILE_ID: zgp.PROFILE_ID,
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}


class XiaomiOpple2ButtonSwitchFace2(XiaomiOpple2ButtonSwitchBase):
"""Xiaomi Opple 2 Button Switch. Face 2."""

device_automation_triggers = XiaomiOpple2ButtonSwitchBase.device_automation_triggers

signature = {
ENDPOINTS: {
# input_clusters=[0, 2, 3, 4, 5, 6, 18, 64704], output_clusters=[10, 25]
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id, # 0
DeviceTemperatureCluster.cluster_id, # 2
Identify.cluster_id, # 3
Groups.cluster_id, # 4
Scenes.cluster_id, # 5
OnOff.cluster_id, # 6
Alarms.cluster_id, # 9
XiaomiMeteringCluster.cluster_id, # 0x0702
0x0B04,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
# input_clusters=[0, 3, 4, 5, 6, 18, 64704], output_clusters=[]
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id, # 0
Identify.cluster_id, # 3
Groups.cluster_id, # 4
Scenes.cluster_id, # 5
OnOff.cluster_id, # 6
MultistateInputCluster.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
Expand Down
Loading
Loading