-
Notifications
You must be signed in to change notification settings - Fork 687
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ThirdReality multifunction night light (#2540)
* Add ThirdReality multifunction night light * Improve comment for `ThirdRealitySpecificCluster` * Use `AttributeDefs` to get `zone_type` ID * Only forward when `attrid=0x0002` * Rename constant * Add basic test checking if motion attr is forwarded --------- Co-authored-by: TheJulianJES <[email protected]>
- Loading branch information
1 parent
cd908ce
commit efa4828
Showing
2 changed files
with
146 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
"""Tests for Third Reality quirks.""" | ||
|
||
|
||
import pytest | ||
from zigpy.zcl.clusters.security import IasZone | ||
|
||
import zhaquirks | ||
import zhaquirks.thirdreality.night_light | ||
|
||
from tests.common import ClusterListener | ||
|
||
zhaquirks.setup() | ||
|
||
|
||
@pytest.mark.parametrize("quirk", (zhaquirks.thirdreality.night_light.Nightlight,)) | ||
async def test_third_reality_nightlight(zigpy_device_from_quirk, quirk): | ||
"""Test Third Reality night light forwarding motion attribute to IasZone cluster.""" | ||
|
||
device = zigpy_device_from_quirk(quirk) | ||
|
||
ias_zone_cluster = device.endpoints[1].ias_zone | ||
ias_zone_listener = ClusterListener(ias_zone_cluster) | ||
|
||
ias_zone_status_id = IasZone.AttributeDefs.zone_status.id | ||
|
||
third_reality_cluster = device.endpoints[1].in_clusters[0xFC00] | ||
|
||
# 0x0002 is also used on manufacturer specific cluster for motion events | ||
third_reality_cluster.update_attribute(0x0002, IasZone.ZoneStatus.Alarm_1) | ||
|
||
assert len(ias_zone_listener.attribute_updates) == 1 | ||
assert ias_zone_listener.attribute_updates[0][0] == ias_zone_status_id | ||
assert ias_zone_listener.attribute_updates[0][1] == IasZone.ZoneStatus.Alarm_1 | ||
|
||
# turn off motion alarm | ||
third_reality_cluster.update_attribute(0x0002, 0) | ||
|
||
assert len(ias_zone_listener.attribute_updates) == 2 | ||
assert ias_zone_listener.attribute_updates[1][0] == ias_zone_status_id | ||
assert ias_zone_listener.attribute_updates[1][1] == 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
"""Third Reality night light zigbee devices.""" | ||
from zigpy.profiles import zha | ||
from zigpy.quirks import CustomCluster, CustomDevice | ||
from zigpy.zcl.clusters.general import ( | ||
Basic, | ||
Groups, | ||
Identify, | ||
LevelControl, | ||
MultistateInput, | ||
OnOff, | ||
Ota, | ||
Scenes, | ||
) | ||
from zigpy.zcl.clusters.lighting import Color | ||
from zigpy.zcl.clusters.lightlink import LightLink | ||
from zigpy.zcl.clusters.measurement import IlluminanceMeasurement | ||
from zigpy.zcl.clusters.security import IasZone | ||
|
||
from zhaquirks import LocalDataCluster | ||
from zhaquirks.const import ( | ||
DEVICE_TYPE, | ||
ENDPOINTS, | ||
INPUT_CLUSTERS, | ||
MODELS_INFO, | ||
OUTPUT_CLUSTERS, | ||
PROFILE_ID, | ||
) | ||
from zhaquirks.thirdreality import THIRD_REALITY | ||
|
||
THIRD_REALITY_CLUSTER_ID = 0xFC00 | ||
THIRD_REALITY_MOTION_EVENT_ATTR_ID = 0x0002 | ||
|
||
|
||
class ThirdRealitySpecificCluster(CustomCluster): | ||
"""Manufacturer specific cluster to relay motion event to IAS Zone cluster.""" | ||
|
||
cluster_id = THIRD_REALITY_CLUSTER_ID | ||
|
||
def _update_attribute(self, attrid, value): | ||
super()._update_attribute(attrid, value) | ||
if attrid == THIRD_REALITY_MOTION_EVENT_ATTR_ID: | ||
self.endpoint.ias_zone.update_attribute( | ||
IasZone.AttributeDefs.zone_status.id, value | ||
) | ||
|
||
|
||
class LocalIasZone(LocalDataCluster, IasZone): | ||
"""Local IAS Zone cluster.""" | ||
|
||
_CONSTANT_ATTRIBUTES = { | ||
IasZone.AttributeDefs.zone_type.id: IasZone.ZoneType.Motion_Sensor | ||
} | ||
|
||
|
||
class Nightlight(CustomDevice): | ||
"""Custom device for 3RSNL02043Z.""" | ||
|
||
signature = { | ||
MODELS_INFO: [(THIRD_REALITY, "3RSNL02043Z")], | ||
ENDPOINTS: { | ||
1: { | ||
PROFILE_ID: zha.PROFILE_ID, | ||
DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, | ||
INPUT_CLUSTERS: [ | ||
Basic.cluster_id, | ||
Identify.cluster_id, | ||
Groups.cluster_id, | ||
Scenes.cluster_id, | ||
OnOff.cluster_id, | ||
LevelControl.cluster_id, | ||
MultistateInput.cluster_id, | ||
Color.cluster_id, | ||
IlluminanceMeasurement.cluster_id, | ||
LightLink.cluster_id, | ||
ThirdRealitySpecificCluster.cluster_id, | ||
], | ||
OUTPUT_CLUSTERS: [ | ||
Ota.cluster_id, | ||
], | ||
} | ||
}, | ||
} | ||
replacement = { | ||
ENDPOINTS: { | ||
1: { | ||
DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, | ||
INPUT_CLUSTERS: [ | ||
Basic.cluster_id, | ||
Identify.cluster_id, | ||
Groups.cluster_id, | ||
Scenes.cluster_id, | ||
OnOff.cluster_id, | ||
LevelControl.cluster_id, | ||
MultistateInput.cluster_id, | ||
Color.cluster_id, | ||
IlluminanceMeasurement.cluster_id, | ||
LightLink.cluster_id, | ||
LocalIasZone, | ||
ThirdRealitySpecificCluster, | ||
], | ||
OUTPUT_CLUSTERS: [ | ||
Ota.cluster_id, | ||
], | ||
} | ||
} | ||
} |