-
Notifications
You must be signed in to change notification settings - Fork 726
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
180 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,45 @@ | ||
"""Tests for NodOn.""" | ||
|
||
from unittest import mock | ||
from zigpy.zcl import foundation | ||
|
||
import zhaquirks | ||
from zhaquirks.nodon.pilot_wire import NodOnSIN4FP21 | ||
|
||
zhaquirks.setup() | ||
|
||
|
||
def test_nodon_pilot_wire_signature_match(assert_signature_matches_quirk): | ||
"""Test signature for NodOn SIN-4-FP-21 (Pilot Wire).""" | ||
|
||
signature = { | ||
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4747, maximum_buffer_size=82, maximum_incoming_transfer_size=500, server_mask=11264, maximum_outgoing_transfer_size=500, descriptor_capability_field=<DescriptorCapability.NONE: 0>)", | ||
"endpoints": { | ||
"1": { | ||
"profile_id": 260, | ||
"device_type": "0x0051", | ||
"in_clusters": [ | ||
"0x0000", | ||
"0x0003", | ||
"0x0004", | ||
"0x0005", | ||
"0x0006", | ||
"0x0702", | ||
"0x1000", | ||
"0xfc00", | ||
], | ||
"out_clusters": ["0x0019"], | ||
}, | ||
"242": { | ||
"profile_id": 41440, | ||
"device_type": "0x0066", | ||
"in_clusters": ["0x0021"], | ||
"out_clusters": ["0x0021"], | ||
}, | ||
}, | ||
"manufacturer": "NodOn", | ||
"model": "SIN-4-FP-21", | ||
"class": "zhaquirks.nodon.pilot_wire.NodOnSIN4FP21", | ||
} | ||
|
||
assert_signature_matches_quirk(zhaquirks.nodon.pilot_wire.NodOnSIN4FP21, signature) |
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,135 @@ | ||
"""NodOn pilot wire heating module.""" | ||
|
||
from zigpy.profiles import zgp, zha | ||
from zigpy.quirks import CustomDevice, CustomCluster | ||
from zigpy.zcl import foundation | ||
from zigpy.zcl.clusters.general import ( | ||
Basic, | ||
GreenPowerProxy, | ||
Groups, | ||
Identify, | ||
OnOff, | ||
Ota, | ||
Scenes, | ||
) | ||
|
||
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, | ||
) | ||
|
||
import zigpy.types as t | ||
|
||
|
||
class NodOnPilotWireManufacturerSpecificCluster(CustomCluster): | ||
"""NodOn manufacturer specific cluster to set Pilot Wire mode.""" | ||
|
||
# Codes taken from | ||
# https://github.com/Koenkk/zigbee-herdsman-converters/blob/0f4833340a20db3dae625a61c41d9be0a6f952be/src/converters/fromZigbee.ts#L5285. | ||
class PilotWireMode(t.enum8): | ||
"""Pilot Wide Modes available in the device.""" | ||
Off = 0x00 | ||
Comfort = 0x01 | ||
Eco = 0x02 | ||
FrostProtection = 0x03 | ||
ComfortMinus1 = 0x04 | ||
ComfortMinus2 = 0x05 | ||
|
||
name: str = "NodOnPilotWireManufacturerSpecificCluster" | ||
cluster_id: t.uint16_t = 0xFC00 | ||
ep_attribute: str = "nodon_pilot_wire_manufacturer_specific" | ||
|
||
attributes = { | ||
0x0000: ("mode", PilotWireMode, True), | ||
} | ||
|
||
server_commands = { | ||
0x0000: foundation.ZCLCommandDef( | ||
"setMode", | ||
{"mode": PilotWireMode}, | ||
False, | ||
is_manufacturer_specific=True, | ||
), | ||
} | ||
|
||
|
||
class NodOnSIN4FP21(CustomDevice): | ||
"""NodOn pilot wire heating module.""" | ||
|
||
signature = { | ||
MODELS_INFO: [("NodOn", "SIN-4-FP-21")], | ||
ENDPOINTS: { | ||
# SimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1, | ||
# input_clusters=[0, 3, 4, 5, 6, 1794, 4096, 64512], | ||
# output_clusters=[25] | ||
1: { | ||
PROFILE_ID: zha.PROFILE_ID, | ||
# PilotWire is not really a smart plug, but this is what NodOn reports | ||
DEVICE_TYPE: zha.DeviceType.SMART_PLUG, | ||
INPUT_CLUSTERS: [ | ||
Basic.cluster_id, | ||
Identify.cluster_id, | ||
Groups.cluster_id, | ||
Scenes.cluster_id, | ||
OnOff.cluster_id, | ||
Metering.cluster_id, | ||
LightLink.cluster_id, | ||
NodOnPilotWireManufacturerSpecificCluster.cluster_id, | ||
], | ||
OUTPUT_CLUSTERS: [ | ||
Ota.cluster_id, | ||
], | ||
}, | ||
# <SimpleDescriptor endpoint=242 profile=41440 device_type=102 | ||
# input_clusters=[33] | ||
# output_clusters=[33] | ||
242: { | ||
PROFILE_ID: zgp.PROFILE_ID, | ||
DEVICE_TYPE: zgp.DeviceType.COMBO_BASIC, | ||
INPUT_CLUSTERS: [GreenPowerProxy.cluster_id], | ||
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], | ||
}, | ||
}, | ||
} | ||
|
||
replacement = { | ||
ENDPOINTS: { | ||
# SimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1, | ||
# input_clusters=[0, 3, 4, 5, 6, 1794, 4096, 64512], | ||
# output_clusters=[25] | ||
1: { | ||
PROFILE_ID: zha.PROFILE_ID, | ||
# PilotWire is not really a smart plug, but this is what NodOn reports | ||
DEVICE_TYPE: zha.DeviceType.SMART_PLUG, | ||
INPUT_CLUSTERS: [ | ||
Basic.cluster_id, | ||
Identify.cluster_id, | ||
Groups.cluster_id, | ||
Scenes.cluster_id, | ||
OnOff.cluster_id, | ||
Metering.cluster_id, | ||
LightLink.cluster_id, | ||
NodOnPilotWireManufacturerSpecificCluster, | ||
], | ||
OUTPUT_CLUSTERS: [ | ||
Ota.cluster_id, | ||
], | ||
}, | ||
# <SimpleDescriptor endpoint=242 profile=41440 device_type=102 | ||
# input_clusters=[33] | ||
# output_clusters=[33] | ||
242: { | ||
PROFILE_ID: zgp.PROFILE_ID, | ||
DEVICE_TYPE: zgp.DeviceType.COMBO_BASIC, | ||
INPUT_CLUSTERS: [GreenPowerProxy.cluster_id], | ||
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], | ||
}, | ||
}, | ||
} |