Skip to content

Commit 0013971

Browse files
kosmiqTheJulianJES
authored andcommitted
Fix instantaneous demand on Schneider Wiser outlets (zigpy#2836)
Co-authored-by: TheJulianJES <[email protected]>
1 parent a473265 commit 0013971

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed

tests/test_schneider.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""Tests for Schneider."""
2+
3+
import pytest
4+
from zigpy.zcl.clusters.smartenergy import Metering
5+
6+
import zhaquirks.schneider.outlet
7+
8+
from tests.common import ClusterListener
9+
10+
zhaquirks.setup()
11+
12+
13+
@pytest.mark.parametrize("quirk", (zhaquirks.schneider.outlet.SocketOutlet,))
14+
async def test_schneider_device_temp(zigpy_device_from_quirk, quirk):
15+
"""Test that instant demand is divided by 1000."""
16+
device = zigpy_device_from_quirk(quirk)
17+
18+
metering_cluster = device.endpoints[6].smartenergy_metering
19+
metering_listener = ClusterListener(metering_cluster)
20+
instantaneous_demand_attr_id = Metering.AttributeDefs.instantaneous_demand.id
21+
summation_delivered_attr_id = Metering.AttributeDefs.current_summ_delivered.id
22+
23+
# verify instant demand is divided by 1000
24+
metering_cluster.update_attribute(instantaneous_demand_attr_id, 25000)
25+
assert len(metering_listener.attribute_updates) == 1
26+
assert metering_listener.attribute_updates[0][0] == instantaneous_demand_attr_id
27+
assert metering_listener.attribute_updates[0][1] == 25 # divided by 1000
28+
29+
# verify other attributes are not modified
30+
metering_cluster.update_attribute(summation_delivered_attr_id, 25)
31+
assert len(metering_listener.attribute_updates) == 2
32+
assert metering_listener.attribute_updates[1][0] == summation_delivered_attr_id
33+
assert metering_listener.attribute_updates[1][1] == 25 # not modified

zhaquirks/schneider/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""Quirks for Schneider devices."""
2+
3+
SCHNEIDER = "Schneider Electric"

zhaquirks/schneider/outlet.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
"""Schneider Electric (Wiser) Outlet Quirks."""
2+
from zigpy.profiles import zgp, zha
3+
from zigpy.quirks import CustomCluster, CustomDevice
4+
from zigpy.zcl.clusters.general import (
5+
Basic,
6+
GreenPowerProxy,
7+
Groups,
8+
Identify,
9+
OnOff,
10+
Ota,
11+
Scenes,
12+
)
13+
from zigpy.zcl.clusters.homeautomation import Diagnostic, ElectricalMeasurement
14+
from zigpy.zcl.clusters.smartenergy import DeviceManagement, Metering
15+
16+
from zhaquirks.const import (
17+
DEVICE_TYPE,
18+
ENDPOINTS,
19+
INPUT_CLUSTERS,
20+
MODELS_INFO,
21+
OUTPUT_CLUSTERS,
22+
PROFILE_ID,
23+
)
24+
from zhaquirks.schneider import SCHNEIDER
25+
26+
27+
class MeteringCluster(CustomCluster, Metering):
28+
"""Custom Metering cluster to fix instantaneous demand value multiplied by 1000."""
29+
30+
def _update_attribute(self, attrid, value):
31+
if attrid == self.AttributeDefs.instantaneous_demand.id:
32+
value = value / 1000
33+
super()._update_attribute(attrid, value)
34+
35+
36+
class SocketOutlet(CustomDevice):
37+
"""Schneider Electric Socket outlet WDE002182, WDE002172."""
38+
39+
signature = {
40+
MODELS_INFO: [
41+
(SCHNEIDER, "SOCKET/OUTLET/1"),
42+
(SCHNEIDER, "SOCKET/OUTLET/2"),
43+
],
44+
ENDPOINTS: {
45+
# <SimpleDescriptor endpoint=1 profile=260 device_type=9
46+
# device_version=0
47+
# input_clusters=[0, 3, 4, 5, 6, 1794, 1800, 2820, 2821, 64516] output_clusters=[25]>
48+
6: {
49+
PROFILE_ID: zha.PROFILE_ID,
50+
DEVICE_TYPE: zha.DeviceType.MAIN_POWER_OUTLET,
51+
INPUT_CLUSTERS: [
52+
Basic.cluster_id,
53+
Identify.cluster_id,
54+
Groups.cluster_id,
55+
Scenes.cluster_id,
56+
OnOff.cluster_id,
57+
Metering.cluster_id,
58+
DeviceManagement.cluster_id,
59+
ElectricalMeasurement.cluster_id,
60+
Diagnostic.cluster_id,
61+
0xFC04,
62+
],
63+
OUTPUT_CLUSTERS: [
64+
Ota.cluster_id,
65+
],
66+
},
67+
242: {
68+
PROFILE_ID: zgp.PROFILE_ID,
69+
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
70+
INPUT_CLUSTERS: [],
71+
OUTPUT_CLUSTERS: [
72+
GreenPowerProxy.cluster_id,
73+
],
74+
},
75+
},
76+
}
77+
78+
replacement = {
79+
ENDPOINTS: {
80+
6: {
81+
PROFILE_ID: zha.PROFILE_ID,
82+
DEVICE_TYPE: zha.DeviceType.MAIN_POWER_OUTLET,
83+
INPUT_CLUSTERS: [
84+
Basic.cluster_id,
85+
Identify.cluster_id,
86+
Groups.cluster_id,
87+
Scenes.cluster_id,
88+
OnOff.cluster_id,
89+
MeteringCluster,
90+
DeviceManagement.cluster_id,
91+
ElectricalMeasurement.cluster_id,
92+
Diagnostic.cluster_id,
93+
0xFC04,
94+
],
95+
OUTPUT_CLUSTERS: [
96+
Ota.cluster_id,
97+
],
98+
},
99+
242: {
100+
PROFILE_ID: zgp.PROFILE_ID,
101+
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
102+
INPUT_CLUSTERS: [],
103+
OUTPUT_CLUSTERS: [
104+
GreenPowerProxy.cluster_id,
105+
],
106+
},
107+
},
108+
}

0 commit comments

Comments
 (0)