Skip to content

Commit

Permalink
Simplify quirks
Browse files Browse the repository at this point in the history
  • Loading branch information
piitaya committed Jan 9, 2025
1 parent 895a2a7 commit f2e0760
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 108 deletions.
66 changes: 1 addition & 65 deletions tests/test_legrand.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
from unittest import mock

import pytest
from zigpy.zcl import foundation

from tests.common import ClusterListener
import zhaquirks
from zhaquirks.legrand import LEGRAND

Expand Down Expand Up @@ -64,7 +62,7 @@ def test_light_switch_with_neutral_signature(assert_signature_matches_quirk):


async def test_legrand_wire_pilot_cluster_write_attrs(zigpy_device_from_v2_quirk):
"""Test Legrand cable outlet heat mode attr writing."""
"""Test Legrand cable outlet pilot_wire_mode attr writing."""

device = zigpy_device_from_v2_quirk(f" {LEGRAND}", " Cable outlet")
legrand_cable_outlet_cluster = device.endpoints[1].legrand_cable_outlet_cluster
Expand All @@ -84,65 +82,3 @@ async def test_legrand_wire_pilot_cluster_write_attrs(zigpy_device_from_v2_quirk
[],
manufacturer=0xFC40,
)


@pytest.mark.parametrize(
"attr, value, expected_attr, expected_value",
[
# Wire pilot mode attribute
(0x4000, 0x00, 0x0000, [1, 0]),
(0x4000, 0x01, 0x0000, [2, 0]),
# Other attributes
(0x0001, False, 0x0001, False),
(0x0002, True, 0x0002, True),
],
)
async def test_legrand_wire_pilot_mode_write_attrs(
zigpy_device_from_v2_quirk, attr, value, expected_attr, expected_value
):
"""Test Legrand cable outlet attr writing."""

device = zigpy_device_from_v2_quirk(f" {LEGRAND}", " Cable outlet")
legrand_cluster = device.endpoints[1].legrand_cluster
legrand_cluster._write_attributes = mock.AsyncMock()

await legrand_cluster.write_attributes({attr: value}, manufacturer=0xFC40)

expected = foundation.Attribute(expected_attr, foundation.TypeValue())
expected_attr_def = legrand_cluster.find_attribute(expected_attr)
expected.value.type = foundation.DataType.from_python_type(
expected_attr_def.type
).type_id
expected.value.value = expected_attr_def.type(expected_value)

legrand_cluster._write_attributes.assert_awaited_with(
[expected],
manufacturer=0xFC40,
)


@pytest.mark.parametrize(
"attr, value, expected_attr, expected_value",
[
# Device mode attribute
(0x0000, [1, 0], 0x4000, False),
(0x0000, [2, 0], 0x4000, True),
],
)
async def test_legrand_wire_pilot_mode_update_attr(
zigpy_device_from_v2_quirk, attr, value, expected_attr, expected_value
):
"""Test Legrand cable outlet attr update."""

device = zigpy_device_from_v2_quirk(f" {LEGRAND}", " Cable outlet")
legrand_cluster = device.endpoints[1].legrand_cluster

legrand_cluster_listener = ClusterListener(legrand_cluster)

legrand_cluster.update_attribute(attr, value)

assert len(legrand_cluster_listener.attribute_updates) == 2
assert legrand_cluster_listener.attribute_updates[0][0] == attr
assert legrand_cluster_listener.attribute_updates[0][1] == value
assert legrand_cluster_listener.attribute_updates[1][0] == expected_attr
assert legrand_cluster_listener.attribute_updates[1][1] == expected_value
58 changes: 15 additions & 43 deletions zhaquirks/legrand/cable_outlet.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,19 @@
from zigpy.zcl.foundation import (
BaseAttributeDefs,
BaseCommandDefs,
DataTypeId,
ZCLAttributeDef,
ZCLCommandDef,
)

from zhaquirks.legrand import LEGRAND, MANUFACTURER_SPECIFIC_CLUSTER_ID

DEVICE_MODE_WIRE_PILOT_ON = [0x02, 0x00]
DEVICE_MODE_WIRE_PILOT_OFF = [0x01, 0x00]


class DeviceMode(t.enum8):
class DeviceMode(t.enum16):
"""Device mode."""

Switch = 0x00
Pilot_wire = 0x01
Switch = 0x0001
Pilot_wire = 0x0002


class LegrandCluster(CustomCluster):
Expand All @@ -35,7 +33,8 @@ class AttributeDefs(BaseAttributeDefs):

device_mode = ZCLAttributeDef(
id=0x0000,
type=t.data16,
type=DeviceMode,
zcl_type=DataTypeId.data16,
is_manufacturer_specific=True,
)
led_dark = ZCLAttributeDef(
Expand All @@ -48,40 +47,6 @@ class AttributeDefs(BaseAttributeDefs):
type=t.Bool,
is_manufacturer_specific=True,
)
device_mode_enum = ZCLAttributeDef(
id=0x4000,
type=t.enum8,
is_manufacturer_specific=True,
)

async def write_attributes(self, attributes, manufacturer=None):
"""Write attributes to the cluster."""

attrs = {}
for attr, value in attributes.items():
attr_def = self.find_attribute(attr)
if attr_def == LegrandCluster.AttributeDefs.device_mode_enum:
mode = (
DEVICE_MODE_WIRE_PILOT_ON
if value == DeviceMode.Pilot_wire
else DEVICE_MODE_WIRE_PILOT_OFF
)
attrs[LegrandCluster.AttributeDefs.device_mode.id] = mode
else:
attrs[attr] = value
return await super().write_attributes(attrs, manufacturer)

def _update_attribute(self, attrid, value) -> None:
super()._update_attribute(attrid, value)
if attrid == LegrandCluster.AttributeDefs.device_mode.id:
mode = (
DeviceMode.Pilot_wire
if value == DEVICE_MODE_WIRE_PILOT_ON
else DeviceMode.Switch
)
super()._update_attribute(
LegrandCluster.AttributeDefs.device_mode_enum.id, mode
)


class PilotWireMode(t.enum8):
Expand Down Expand Up @@ -139,11 +104,18 @@ async def write_attributes(self, attributes, manufacturer=None):
.replaces(LegrandCluster)
.replaces(LegrandCableOutletCluster)
.enum(
attribute_name=LegrandCluster.AttributeDefs.device_mode_enum.name,
attribute_name=LegrandCluster.AttributeDefs.device_mode.name,
cluster_id=LegrandCluster.cluster_id,
enum_class=DeviceMode,
translation_key="device_mode",
translation_key="legrand_cable_outlet_device_mode",
fallback_name="Device mode",
)
.enum(
attribute_name=LegrandCableOutletCluster.AttributeDefs.pilot_wire_mode.name,
cluster_id=LegrandCableOutletCluster.cluster_id,
enum_class=PilotWireMode,
translation_key="legrand_cable_outlet_pilot_wire_mode",
fallback_name="Pilot Wire mode",
)
.add_to_registry()
)

0 comments on commit f2e0760

Please sign in to comment.