Skip to content

Commit 074ca5e

Browse files
authored
Fix Frient EMI Norwegian HAN divisor (#4396)
1 parent b84dcc4 commit 074ca5e

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

tests/test_develco.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
from unittest import mock
44

5+
import zigpy.types as t
56
from zigpy.zcl import ClusterType, foundation
67
from zigpy.zcl.clusters.smartenergy import Metering
78

9+
from tests.common import ClusterListener
810
import zhaquirks
911

1012
zhaquirks.setup()
@@ -137,3 +139,51 @@ async def test_frient_emi(zigpy_device_from_v2_quirk):
137139
assert attr_data == b"\x00\x00%d\x00\x00\x00\x00\x00"
138140

139141
assert result == (foundation.Status.SUCCESS, "done")
142+
143+
144+
async def test_mfg_cluster_events(zigpy_device_from_v2_quirk):
145+
"""Test Frient EMI Norwegian HAN ignoring incorrect divisor attribute reports."""
146+
device = zigpy_device_from_v2_quirk("frient A/S", "EMIZB-132", endpoint_ids=[1, 2])
147+
148+
metering_cluster = device.endpoints[2].smartenergy_metering
149+
metering_listener = ClusterListener(metering_cluster)
150+
151+
# divisor already fixed at 1000
152+
assert metering_cluster.get(Metering.AttributeDefs.divisor.id) == 1000
153+
154+
# send incorrect divisor attribute report
155+
device.packet_received(
156+
t.ZigbeePacket(
157+
profile_id=260,
158+
cluster_id=Metering.cluster_id,
159+
src_ep=2,
160+
dst_ep=2,
161+
# XXX: get data from real device
162+
data=t.SerializableBytes(b'\x1c\x00\x00\x01\n\x02\x03"\x00\x02\x00'),
163+
)
164+
)
165+
166+
# attribute_updated event should not be emitted
167+
assert len(metering_listener.attribute_updates) == 0
168+
169+
# divisor should still be fixed at 1000
170+
assert metering_cluster.get(Metering.AttributeDefs.divisor.id) == 1000
171+
172+
# send current_summ_delivered attribute report
173+
device.packet_received(
174+
t.ZigbeePacket(
175+
profile_id=260,
176+
cluster_id=Metering.cluster_id,
177+
src_ep=2,
178+
dst_ep=2,
179+
data=t.SerializableBytes(
180+
b"\x1c\x00\x00\x01\n\x00\x00%\xd2\x04\x00\x00\x00\x00"
181+
),
182+
)
183+
)
184+
185+
# attribute_updated event should be emitted
186+
assert len(metering_listener.attribute_updates) == 1
187+
assert (
188+
metering_cluster.get(Metering.AttributeDefs.current_summ_delivered.id) == 1234
189+
)

zhaquirks/develco/emi_han.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""Frient Electricity Meter Interface Norwegian HAN."""
2+
3+
from __future__ import annotations
4+
5+
from typing import Any
6+
7+
from zigpy.quirks import CustomCluster
8+
from zigpy.quirks.v2 import QuirkBuilder
9+
import zigpy.types as t
10+
from zigpy.zcl.clusters.smartenergy import Metering
11+
12+
13+
class FrientMetering(CustomCluster, Metering):
14+
"""Frient EMI Norwegian HAN Metering cluster definition."""
15+
16+
# fix device issue
17+
_CONSTANT_ATTRIBUTES = {Metering.AttributeDefs.divisor.id: 1000}
18+
19+
def _update_attribute(self, attrid: int | t.uint16_t, value: Any) -> None:
20+
"""Update attribute with value."""
21+
# prevent attribute_updated events for divisor
22+
if attrid == Metering.AttributeDefs.divisor.id:
23+
return
24+
super()._update_attribute(attrid, value)
25+
26+
27+
(
28+
QuirkBuilder("frient A/S", "EMIZB-132")
29+
.replaces(FrientMetering, endpoint_id=2)
30+
.add_to_registry()
31+
)

0 commit comments

Comments
 (0)