|
1 | 1 | """Module for Schneider Electric devices quirks.""" |
2 | 2 | import logging |
3 | 3 |
|
4 | | -from zigpy.quirks import CustomCluster |
5 | | -import zigpy.types as t |
6 | | -from zigpy.zcl.clusters.closures import WindowCovering |
7 | | -from zigpy.zcl.clusters.general import Basic, OnOff |
8 | | -from zigpy.zcl.clusters.homeautomation import Diagnostic |
9 | | -from zigpy.zcl.foundation import ZCLAttributeDef |
10 | | - |
11 | 4 | _LOGGER = logging.getLogger(__name__) |
12 | 5 |
|
13 | 6 | SE_MANUF_NAME = "Schneider Electric" |
14 | 7 | SE_MANUF_ID = 0x4190 |
15 | | - |
16 | | -# Attribute IDs |
17 | | -ATTR_CURRENT_POSITION_LIFT_PERCENTAGE = 0x0008 |
18 | | - |
19 | | -# Command IDs |
20 | | -CMD_GO_TO_LIFT_PERCENTAGE = 0x0005 |
21 | | - |
22 | | - |
23 | | -class SEManufCluster(CustomCluster): |
24 | | - """Schneider Electric manufacturer specific cluster.""" |
25 | | - |
26 | | - name = "Schneider Electric Manufacturer Specicific" |
27 | | - ep_attribute = "schneider_electric_manufacturer" |
28 | | - |
29 | | - |
30 | | -class SEBasicCluster(SEManufCluster, Basic): |
31 | | - |
32 | | - attributes: dict[int, ZCLAttributeDef] = Basic.attributes.copy() |
33 | | - |
34 | | - attributes.update( |
35 | | - { |
36 | | - 0xE001: ( |
37 | | - "se_sw_build_id", |
38 | | - t.CharacterString, |
39 | | - ), # value: "002.004.016 R |
40 | | - 0xE002: ( |
41 | | - "unknown_attribute_57346", |
42 | | - t.CharacterString, |
43 | | - ), # value: "001.000.000" |
44 | | - 0xE004: ( |
45 | | - "unknown_attribute_57348", |
46 | | - t.CharacterString, |
47 | | - ), # value: "213249FEFF5ECFD" |
48 | | - 0xE007: ("unknown_attribute_57351", t.enum16), |
49 | | - 0xE008: ( |
50 | | - "se_device_type", |
51 | | - t.CharacterString, |
52 | | - ), # value: "Wiser Light" |
53 | | - 0xE009: ( |
54 | | - "se_model", |
55 | | - t.CharacterString, |
56 | | - ), # value: "NHPB/SHUTTER/1" |
57 | | - 0xE00A: ( |
58 | | - "se_realm", |
59 | | - t.CharacterString, |
60 | | - ), # value: "Wiser Home" |
61 | | - 0xE00B: ( |
62 | | - "unknown_attribute_57355", |
63 | | - t.CharacterString, |
64 | | - ), |
65 | | - } |
66 | | - ) |
67 | | - |
68 | | - |
69 | | -class SEOnOff(SEManufCluster, OnOff): |
70 | | - attributes = OnOff.attributes.copy() |
71 | | - attributes.update( |
72 | | - { |
73 | | - 0xE000: ("unknown_attribute_57344", t.uint16_t), |
74 | | - 0xE001: ("unknown_attribute_57345", t.uint32_t), |
75 | | - 0xE002: ("unknown_attribute_57346", t.bitmap8), |
76 | | - 0xE003: ("unknown_attribute_57347", t.uint32_t), |
77 | | - } |
78 | | - ) |
79 | | - |
80 | | - |
81 | | -class SEWindowCovering(SEManufCluster, WindowCovering): |
82 | | - """Manufacturer Specific Cluster of cover device.""" |
83 | | - |
84 | | - attributes: dict[int, ZCLAttributeDef] = WindowCovering.attributes.copy() |
85 | | - |
86 | | - attributes.update( |
87 | | - { |
88 | | - 0xFFFD: ("unknown_attribute_65533", t.uint16_t), |
89 | | - 0xE000: ("lift_duration", t.uint16_t), |
90 | | - 0xE010: ("unknown_attribute_57360", t.bitmap8), |
91 | | - 0xE012: ("unknown_attribute_57362", t.uint16_t), |
92 | | - 0xE013: ("unknown_attribute_57363", t.bitmap8), |
93 | | - 0xE014: ("unknown_attribute_57364", t.uint16_t), |
94 | | - 0xE015: ("unknown_attribute_57365", t.uint16_t), |
95 | | - 0xE016: ("unknown_attribute_57366", t.uint16_t), |
96 | | - 0xE017: ("unknown_attribute_57367", t.uint8_t), |
97 | | - } |
98 | | - ) |
99 | | - |
100 | | - def _update_attribute(self, attrid, value): |
101 | | - if attrid == ATTR_CURRENT_POSITION_LIFT_PERCENTAGE: |
102 | | - # Invert the percentage value |
103 | | - value = 100 - value |
104 | | - super()._update_attribute(attrid, value) |
105 | | - |
106 | | - async def command( |
107 | | - self, command_id, *args, manufacturer=None, expect_reply=True, tsn=None |
108 | | - ): |
109 | | - """Override default command to invert percent lift value.""" |
110 | | - if command_id == CMD_GO_TO_LIFT_PERCENTAGE: |
111 | | - percent = args[0] |
112 | | - percent = 100 - percent |
113 | | - v = (percent,) |
114 | | - return await super().command(command_id, *v) |
115 | | - return await super().command( |
116 | | - command_id, |
117 | | - *args, |
118 | | - manufacturer=manufacturer, |
119 | | - expect_reply=expect_reply, |
120 | | - tsn=tsn |
121 | | - ) |
122 | | - |
123 | | - |
124 | | -class SEDiagnostic(CustomCluster, Diagnostic): |
125 | | - |
126 | | - attributes: dict[int, ZCLAttributeDef] = Diagnostic.attributes.copy() |
127 | | - |
128 | | - # TODO: Check -> this attr don't seems to be manufacturer related (no "manf_id") |
129 | | - attributes.update( |
130 | | - { |
131 | | - 0xFFFD: ("unknown_attribute_65533", t.uint16_t), |
132 | | - } |
133 | | - ) |
134 | | - |
135 | | - |
136 | | -class SESpecificCluster(SEManufCluster): |
137 | | - cluster_id = 0xFF17 |
138 | | - |
139 | | - attributes = { |
140 | | - 0x0000: ("unknown_attribute_0", t.enum8), |
141 | | - 0x0001: ("unknown_attribute_1", t.enum8), |
142 | | - 0x0010: ("unknown_attribute_16", t.uint8_t), |
143 | | - 0x0011: ("unknown_attribute_17", t.uint16_t), |
144 | | - 0x0020: ("unknown_attribute_32", t.uint8_t), |
145 | | - 0x0021: ("unknown_attribute_33", t.uint16_t), |
146 | | - 0xFFFD: ("unknown_attribute_65533", t.uint16_t), |
147 | | - } |
148 | | - |
149 | | - |
150 | | -class SEPiloteMode(int): |
151 | | - ''' |
152 | | - Might be useful for : |
153 | | - - CCTFR6700 (manufacturerCode seems diff: 0x105e) |
154 | | - ''' |
155 | | - Contactor=1 |
156 | | - Pilot=3 |
157 | | - |
158 | | -class WiserDimmerMode(int): |
159 | | - ''' |
160 | | - Might be useful for : |
161 | | - - PUCK/DIMMER/ |
162 | | - - NHROTARY/DIMMER/1 |
163 | | - ''' |
164 | | - Auto = 0 |
165 | | - RC = 1 |
166 | | - RL = 2 |
167 | | - RL_LED = 3 |
168 | | - |
169 | | - |
170 | | -class SEDimmerMode(): |
171 | | - ''' |
172 | | - Might be useful for : |
173 | | - - LK Dimmer (manufacturerCode seems diff: 0x105e) |
174 | | - ''' |
175 | | - RC = 1 |
176 | | - RL = 2 |
177 | | - |
0 commit comments