diff --git a/tests/test_innr.py b/tests/test_innr.py new file mode 100644 index 0000000000..aa79c77609 --- /dev/null +++ b/tests/test_innr.py @@ -0,0 +1,48 @@ +"""Tests for Innr quirks.""" + +import zhaquirks +import zhaquirks.innr.innr_sp242_plug + +zhaquirks.setup() + + +def test_innr242_signature(assert_signature_matches_quirk): + """Test 'innr SP-242' signature matches to its quirk.""" + + signature = { + "node_descriptor": { + "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4454, maximum_buffer_size=74, maximum_incoming_transfer_size=80, server_mask=11264, maximum_outgoing_transfer_size=80, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)" + }, + "endpoints": { + "1": { + "profile_id": 260, + "device_type": "0x010a", + "in_clusters": [ + "0x0000", + "0x0003", + "0x0004", + "0x0005", + "0x0006", + "0x0008", + "0x0702", + "0x0b04", + "0x1000", + "0xe001", + ], + "out_clusters": [ + "0x000a", + "0x0019", + ], + }, + "242": { + "profile_id": 41440, + "device_type": "0x0061", + "in_clusters": [], + "out_clusters": ["0x0021"], + }, + }, + "manufacturer": "innr", + "model": "SP 242", + "class": "zigpy.device.Device", + } + assert_signature_matches_quirk(zhaquirks.innr.innr_sp242_plug.SP242, signature) diff --git a/zhaquirks/innr/innr_sp242_plug.py b/zhaquirks/innr/innr_sp242_plug.py new file mode 100644 index 0000000000..5b6e2a82fa --- /dev/null +++ b/zhaquirks/innr/innr_sp242_plug.py @@ -0,0 +1,105 @@ +"""Innr SP 242 plug.""" + +from zigpy.profiles import zgp, zha +from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.zcl.clusters.general import ( + Basic, + GreenPowerProxy, + Groups, + Identify, + LevelControl, + OnOff, + Ota, + Scenes, + Time, +) +from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement +from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.zcl.clusters.smartenergy import Metering + +from zhaquirks.const import ( + DEVICE_TYPE, + ENDPOINTS, + INPUT_CLUSTERS, + MODELS_INFO, + OUTPUT_CLUSTERS, + PROFILE_ID, +) +from zhaquirks.innr import INNR, MeteringClusterInnr + + +class InnrCluster(CustomCluster): + """Innr manufacturer specific cluster.""" + + cluster_id = 0xE001 + + +class SP242(CustomDevice): + """Innr SP 242 smart plug.""" + + signature = { + MODELS_INFO: [(INNR, "SP 242")], + ENDPOINTS: { + 1: { + PROFILE_ID: zha.PROFILE_ID, + DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT, + INPUT_CLUSTERS: [ + Basic.cluster_id, + Identify.cluster_id, + Groups.cluster_id, + Scenes.cluster_id, + OnOff.cluster_id, + LevelControl.cluster_id, + Metering.cluster_id, + ElectricalMeasurement.cluster_id, + LightLink.cluster_id, + InnrCluster.cluster_id, + ], + OUTPUT_CLUSTERS: [ + Time.cluster_id, + Ota.cluster_id, + ], + }, + 242: { + PROFILE_ID: 41440, + DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, + INPUT_CLUSTERS: [], + OUTPUT_CLUSTERS: [ + GreenPowerProxy.cluster_id, + ], + }, + }, + } + + replacement = { + ENDPOINTS: { + 1: { + PROFILE_ID: zha.PROFILE_ID, + DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT, + INPUT_CLUSTERS: [ + Basic.cluster_id, + Identify.cluster_id, + Groups.cluster_id, + Scenes.cluster_id, + OnOff.cluster_id, + LevelControl.cluster_id, + MeteringClusterInnr, + ElectricalMeasurement.cluster_id, + LightLink.cluster_id, + InnrCluster, + ], + OUTPUT_CLUSTERS: [ + Time.cluster_id, + Ota.cluster_id, + ], + }, + 242: { + PROFILE_ID: 41440, + DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, + INPUT_CLUSTERS: [], + OUTPUT_CLUSTERS: [ + GreenPowerProxy.cluster_id, + ], + }, + }, + }