Skip to content

Commit d8dcf86

Browse files
cspurkdflemstr
authored andcommitted
Make structure of packages more consistent with others
This was requested here: <zigpy#2928 (comment)>
1 parent b6fc6dc commit d8dcf86

File tree

5 files changed

+142
-138
lines changed

5 files changed

+142
-138
lines changed

tests/test_schneiderelectric.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from zigpy.zcl import foundation
55
from zigpy.zcl.clusters.closures import WindowCovering
66

7-
import zhaquirks.schneiderelectric.devices.shutters
7+
import zhaquirks.schneiderelectric.shutters
88

99
from tests.common import ClusterListener
1010

@@ -66,15 +66,15 @@ def test_1gang_shutter_1_signature(assert_signature_matches_quirk):
6666
"class": "zigpy.device.Device",
6767
}
6868
assert_signature_matches_quirk(
69-
zhaquirks.schneiderelectric.devices.shutters.OneGangShutter1, signature
69+
zhaquirks.schneiderelectric.shutters.OneGangShutter1, signature
7070
)
7171

7272

7373
async def test_1gang_shutter_1_go_to_lift_percentage_cmd(zigpy_device_from_quirk):
7474
"""Asserts that the go_to_lift_percentage command inverts the percentage value."""
7575

7676
device = zigpy_device_from_quirk(
77-
zhaquirks.schneiderelectric.devices.shutters.OneGangShutter1
77+
zhaquirks.schneiderelectric.shutters.OneGangShutter1
7878
)
7979
window_covering_cluster = device.endpoints[5].window_covering
8080

@@ -95,7 +95,7 @@ async def test_1gang_shutter_1_unpatched_cmd(zigpy_device_from_quirk):
9595
"""Asserts that unpatched ZCL commands keep working."""
9696

9797
device = zigpy_device_from_quirk(
98-
zhaquirks.schneiderelectric.devices.shutters.OneGangShutter1
98+
zhaquirks.schneiderelectric.shutters.OneGangShutter1
9999
)
100100
window_covering_cluster = device.endpoints[5].window_covering
101101

@@ -116,7 +116,7 @@ async def test_1gang_shutter_1_lift_percentage_updates(zigpy_device_from_quirk):
116116
(e.g., by the device) invert the reported percentage value."""
117117

118118
device = zigpy_device_from_quirk(
119-
zhaquirks.schneiderelectric.devices.shutters.OneGangShutter1
119+
zhaquirks.schneiderelectric.shutters.OneGangShutter1
120120
)
121121
window_covering_cluster = device.endpoints[5].window_covering
122122
cluster_listener = ClusterListener(window_covering_cluster)
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,135 @@
11
"""Quirks implementations for Schneider Electric devices."""
2+
from typing import Any, Coroutine, Dict, Union
3+
4+
from zigpy import types as t
5+
from zigpy.quirks import CustomCluster
6+
from zigpy.zcl import foundation
7+
from zigpy.zcl.clusters.closures import WindowCovering
8+
from zigpy.zcl.clusters.general import Basic
9+
from zigpy.zcl.foundation import ZCLAttributeDef
210

311
SE_MANUF_NAME = "Schneider Electric"
412
SE_MANUF_ID = 0x4190
13+
14+
15+
class SEBasic(CustomCluster, Basic):
16+
"""Schneider Electric manufacturer specific Basic cluster."""
17+
18+
attributes: Dict[int, ZCLAttributeDef] = Basic.attributes.copy()
19+
20+
attributes.update(
21+
{
22+
0xE001: (
23+
"se_sw_build_id",
24+
t.CharacterString,
25+
True,
26+
), # value: "002.004.016 R
27+
0xE002: (
28+
"unknown_attribute_57346",
29+
t.CharacterString,
30+
True,
31+
), # value: "001.000.000"
32+
0xE004: (
33+
"unknown_attribute_57348",
34+
t.CharacterString,
35+
True,
36+
), # value: "213249FEFF5ECFD"
37+
0xE007: (
38+
"unknown_attribute_57351",
39+
t.enum16,
40+
True,
41+
),
42+
0xE008: (
43+
"se_device_type",
44+
t.CharacterString,
45+
True,
46+
), # value: "Wiser Light"
47+
0xE009: (
48+
"se_model",
49+
t.CharacterString,
50+
True,
51+
), # value: "NHPB/SHUTTER/1"
52+
0xE00A: (
53+
"se_realm",
54+
t.CharacterString,
55+
True,
56+
), # value: "Wiser Home"
57+
0xE00B: (
58+
"unknown_attribute_57355",
59+
t.CharacterString,
60+
True,
61+
), # value: "http://www.schneider-electric.com"
62+
}
63+
)
64+
65+
66+
class SEWindowCovering(CustomCluster, WindowCovering):
67+
"""Schneider Electric manufacturer specific Window Covering cluster."""
68+
69+
attributes: Dict[int, ZCLAttributeDef] = WindowCovering.attributes.copy()
70+
71+
attributes.update(
72+
{
73+
0xFFFD: ("unknown_attribute_65533", t.uint16_t, True),
74+
0xE000: ("lift_duration", t.uint16_t, True),
75+
0xE010: ("unknown_attribute_57360", t.bitmap8, True),
76+
0xE012: ("unknown_attribute_57362", t.uint16_t, True),
77+
0xE013: ("unknown_attribute_57363", t.bitmap8, True),
78+
0xE014: ("unknown_attribute_57364", t.uint16_t, True),
79+
0xE015: ("unknown_attribute_57365", t.uint16_t, True),
80+
0xE016: ("unknown_attribute_57366", t.uint16_t, True),
81+
0xE017: ("unknown_attribute_57367", t.uint8_t, True),
82+
}
83+
)
84+
85+
def _update_attribute(self, attrid: Union[int, t.uint16_t], value: Any):
86+
if attrid == WindowCovering.AttributeDefs.current_position_lift_percentage.id:
87+
# Invert the percentage value
88+
value = 100 - value
89+
super()._update_attribute(attrid, value)
90+
91+
async def command(
92+
self,
93+
command_id: Union[foundation.GeneralCommand, int, t.uint8_t],
94+
*args: Any,
95+
**kwargs: Any,
96+
) -> Coroutine:
97+
command = self.server_commands[command_id]
98+
99+
# Override default command to invert percent lift value.
100+
if command.id == WindowCovering.ServerCommandDefs.go_to_lift_percentage.id:
101+
percent = args[0]
102+
percent = 100 - percent
103+
return await super().command(command_id, percent, **kwargs)
104+
105+
return await super().command(command_id, *args, **kwargs)
106+
107+
108+
class SESpecific(CustomCluster):
109+
"""Schneider Electric manufacturer specific cluster."""
110+
111+
name = "Schneider Electric Manufacturer Specific"
112+
ep_attribute = "schneider_electric_manufacturer"
113+
cluster_id = 0xFF17
114+
115+
class LedIndicatorSignals(t.enum8):
116+
"""Available LED indicator signal combinations.
117+
118+
Shutter movement can be indicated with a red LED signal. A green LED
119+
light permanently provides orientation, if desired.
120+
"""
121+
122+
MOVEMENT_ONLY = 0x00
123+
MOVEMENT_AND_ORIENTATION = 0x01
124+
ORIENTATION_ONLY = 0x02
125+
NONE = 0x03
126+
127+
attributes = {
128+
0x0000: ("led_indicator_signals", LedIndicatorSignals, True),
129+
0x0001: ("unknown_attribute_1", t.enum8, True),
130+
0x0010: ("unknown_attribute_16", t.uint8_t, True),
131+
0x0011: ("unknown_attribute_17", t.uint16_t, True),
132+
0x0020: ("unknown_attribute_32", t.uint8_t, True),
133+
0x0021: ("unknown_attribute_33", t.uint16_t, True),
134+
0xFFFD: ("unknown_attribute_65533", t.uint16_t, True),
135+
}

zhaquirks/schneiderelectric/clusters/__init__.py

Lines changed: 0 additions & 131 deletions
This file was deleted.

zhaquirks/schneiderelectric/devices/__init__.py

Whitespace-only changes.

zhaquirks/schneiderelectric/devices/shutters.py renamed to zhaquirks/schneiderelectric/shutters.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@
2121
OUTPUT_CLUSTERS,
2222
PROFILE_ID,
2323
)
24-
from zhaquirks.schneiderelectric import SE_MANUF_NAME
25-
from zhaquirks.schneiderelectric.clusters import SEBasic, SESpecific, SEWindowCovering
24+
from zhaquirks.schneiderelectric import (
25+
SE_MANUF_NAME,
26+
SEBasic,
27+
SESpecific,
28+
SEWindowCovering,
29+
)
2630

2731

2832
class OneGangShutter1(CustomDevice):

0 commit comments

Comments
 (0)