Skip to content

Commit bf45816

Browse files
committed
Update Schneider quirks using the leaked spec docs
1 parent 24217a3 commit bf45816

File tree

2 files changed

+197
-63
lines changed

2 files changed

+197
-63
lines changed

zhaquirks/schneiderelectric/__init__.py

Lines changed: 195 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
from zigpy.quirks import CustomCluster
88
from zigpy.zcl import foundation
99
from zigpy.zcl.clusters.closures import WindowCovering
10-
from zigpy.zcl.clusters.general import Basic
10+
from zigpy.zcl.clusters.general import Basic, OnOff
11+
from zigpy.zcl.clusters.lighting import Ballast
1112
from zigpy.zcl.foundation import BaseAttributeDefs, ZCLAttributeDef
1213

1314
SE_MANUF_NAME = "Schneider Electric"
@@ -20,46 +21,157 @@ class SEBasic(CustomCluster, Basic):
2021
class AttributeDefs(Basic.AttributeDefs):
2122
"""Attribute definitions."""
2223

23-
se_sw_build_id: Final = ZCLAttributeDef(
24+
# The Application FW Version attribute specifies the firmware version of the application. The format of this
25+
# attribute is XXX.YYY.ZZZ V.
26+
# XXX = major version
27+
# YYY = minor version
28+
# ZZZ = patch version
29+
# V = Build Type (One of the following: D = Development version, T0, T1 = Verification version, V = Validation
30+
# version, R = Official Release version).
31+
se_application_fw_version: Final = ZCLAttributeDef(
2432
id=0xE001,
2533
type=t.CharacterString,
2634
is_manufacturer_specific=True,
27-
) # value: "002.004.016 R"
28-
unknown_attribute_57346: Final = ZCLAttributeDef(
35+
)
36+
# The Application HWVersion attribute specifies the hardware version of the application design in format
37+
# AAA.BBB.CCC. Meaning:
38+
# AAA - major version
39+
# BBB - minor version
40+
# CCC - patch version
41+
# If version is 000.000.000, HW version is not available.
42+
se_application_hw_version: Final = ZCLAttributeDef(
2943
id=0xE002,
3044
type=t.CharacterString,
3145
is_manufacturer_specific=True,
32-
) # value: "001.000.000"
33-
unknown_attribute_57348: Final = ZCLAttributeDef(
46+
)
47+
# Device serial number. Hexadecimal string of 15 chars length.
48+
se_device_serial_number: Final = ZCLAttributeDef(
3449
id=0xE004,
3550
type=t.CharacterString,
3651
is_manufacturer_specific=True,
37-
) # value: "213249FEFF5ECFD"
38-
unknown_attribute_57351: Final = ZCLAttributeDef(
52+
)
53+
# The ProductIdentifier attribute specifies the unique internal numerical identifier of the product. See device
54+
# description for this value.
55+
se_product_identifier: Final = ZCLAttributeDef(
3956
id=0xE007,
4057
type=t.enum16,
4158
is_manufacturer_specific=True,
4259
)
43-
se_device_type: Final = ZCLAttributeDef(
60+
# The ProductRange attribute specifies the name of the range to which the product belongs.
61+
se_product_range: Final = ZCLAttributeDef(
4462
id=0xE008,
4563
type=t.CharacterString,
4664
is_manufacturer_specific=True,
47-
) # value: "Wiser Light"
48-
se_model: Final = ZCLAttributeDef(
65+
)
66+
# The ProductModel attribute specifies the name of the product model. Same value as model identifier attribute
67+
# 0x0005.
68+
se_product_model: Final = ZCLAttributeDef(
4969
id=0xE009,
5070
type=t.CharacterString,
5171
is_manufacturer_specific=True,
52-
) # value: "NHPB/SHUTTER/1"
53-
se_realm: Final = ZCLAttributeDef(
72+
)
73+
# The ProductFamily attribute specifies the name of the family to which the product belongs.
74+
se_product_family: Final = ZCLAttributeDef(
5475
id=0xE00A,
5576
type=t.CharacterString,
5677
is_manufacturer_specific=True,
57-
) # value: "Wiser Home"
58-
unknown_attribute_57355: Final = ZCLAttributeDef(
78+
)
79+
# VendorURL, value: "http://www.schneider-electric.com"
80+
se_vendor_url: Final = ZCLAttributeDef(
5981
id=0xE00B,
6082
type=t.CharacterString,
6183
is_manufacturer_specific=True,
62-
) # value: "http://www.schneider-electric.com"
84+
)
85+
86+
87+
class SEOnTimeReloadOptions(t.bitmap8):
88+
"""Valid values for the SE OnTimeReloadOptions attr"""
89+
90+
# OnTimeReload timer can be canceled by receiving OFF command -> light is going OFF immediately.
91+
# If this bit is not set, the timer can not be canceled, it is always restarted.
92+
OnTimeReloadCanceledByOffCommand = 0x1
93+
94+
# Impulse mode active. Whenever output should be switched ON, it will be switched ON only for 200msec.
95+
# OnTimeReload attributes is ignored, also bit0 inside this attribute has no sense. If this bit is not set,
96+
# impulse mode is disabled.
97+
ImpulseMode = 0x2
98+
99+
100+
class SEOnOff(CustomCluster, OnOff):
101+
"""Schneider Electric manufacturer specific OnOff cluster."""
102+
103+
class AttributeDefs(OnOff.AttributeDefs):
104+
"""Attribute definitions."""
105+
106+
# Has meaning only if attribute OnTimeReload is not 0. Defines number of seconds before the light is switched
107+
# off automatically when the user is somehow inform the light will be switched off automatically. Value 0 or
108+
# 0xFFFF disables pre-warning. For switch is just short switch OFF and ON, for dimmer device goes to 60
109+
# percent and starts slowly dim down. During this time user can reload the time and postpone automatic switch
110+
# off for time defined in OnTimeReload. If you enter value greater than 6553, after reboot you will read again
111+
# value 6553. If you enter 0xFFFF, functionality will be disabled.
112+
se_pre_warning_time: Final = ZCLAttributeDef(
113+
id=0xE000,
114+
type=t.uint16_t,
115+
is_manufacturer_specific=True,
116+
)
117+
118+
# Defines number of seconds before the light is switched off automatically. Time is in seconds.
119+
# Value 0 disable the functionality. When brightness is changed, or ON command is received, timer is always
120+
# restarted. Check OnTimeReloadOptions for possible impulse mode (if attribute is implemented).
121+
se_on_time_reload: Final = ZCLAttributeDef(
122+
id=0xE001,
123+
type=t.uint32_t,
124+
is_manufacturer_specific=True,
125+
)
126+
127+
se_on_time_reload_options: Final = ZCLAttributeDef(
128+
id=0xE002,
129+
type=SEOnTimeReloadOptions,
130+
is_manufacturer_specific=True,
131+
)
132+
133+
134+
class SEControlMode(t.enum8):
135+
"""Dimming mode for PUCK/DIMMER/* and NHROTARY/DIMMER/1."""
136+
137+
Auto = 0
138+
RC = 1
139+
RL = 2
140+
RL_LED = 3
141+
142+
143+
class SEWiringMode(t.enum8):
144+
"""Dimmer wiring mode. Default value depends on how the dimmer is connected to the mains."""
145+
146+
TwoWiredMode = 0
147+
ThreeWiredMode = 1
148+
149+
150+
class SEDimmingCurve(t.enum8):
151+
"""Dimmer dimming curve"""
152+
153+
Logarithmic = 0
154+
Linear = 1 # Not supported in current FW, but defined in the spec
155+
Exponential = 2 # Not supported in current FW, but defined in the spec
156+
157+
158+
class SEBallast(CustomCluster, Ballast):
159+
"""Schneider Electric Ballast cluster."""
160+
161+
manufacturer_id_override = SE_MANUF_ID
162+
163+
class AttributeDefs(Ballast.AttributeDefs):
164+
"""Attribute definitions."""
165+
166+
se_control_mode: Final = ZCLAttributeDef(
167+
id=0xE000, type=SEControlMode, is_manufacturer_specific=True
168+
)
169+
se_wiring_mode: Final = ZCLAttributeDef(
170+
id=0xE002, type=t.enum8, is_manufacturer_specific=True
171+
)
172+
se_dimming_curve: Final = ZCLAttributeDef(
173+
id=0xE002, type=t.enum8, is_manufacturer_specific=True
174+
)
63175

64176

65177
class SEWindowCovering(CustomCluster, WindowCovering):
@@ -138,17 +250,57 @@ async def command(
138250
return await super().command(command_id, *args, **kwargs)
139251

140252

141-
class SELedIndicatorSignals(t.enum8):
253+
class SESwitchIndication(t.enum8):
142254
"""Available LED indicator signal combinations.
143255
144256
Shutter movement can be indicated with a red LED signal. A green LED
145257
light permanently provides orientation, if desired.
146258
"""
147259

148-
MOVEMENT_ONLY = 0x00
149-
MOVEMENT_AND_ORIENTATION = 0x01
150-
ORIENTATION_ONLY = 0x02
151-
NONE = 0x03
260+
# For lights: LED is on when load is on. For shutter controllers: red LED is on while shutter is moving.
261+
FollowsLoad = 0x00
262+
# For lights: LED is always on. For shutter controllers: red LED is on while shutter is moving, green LED indicates
263+
# direction.
264+
AlwaysOn = 0x01
265+
# For lights: LED is on when load is off. For shutter controllers: red LED is never on, green LED indicates
266+
# direction.
267+
InverseOfLoad = 0x02
268+
# LED(s) are always off.
269+
AlwaysOff = 0x03
270+
271+
272+
class SESwitchAction(t.enum8):
273+
# Behave like a light switch (Up = On, Down = Off)
274+
Light = 0x00
275+
# Behave like an inverted light switch (Up = Off, Down = On)
276+
LightOpposite = 0xFE
277+
# Behave like a dimmer (Up/rotate right = on and/or dim up, Down/rotate left = off and/or dim down)
278+
Dimmer = 0x01
279+
# Behave like an inverted dimmer (Up/rotate right = off and/or dim down, Down/rotate left = on and/or dim up)
280+
DimmerOpposite = 0xFD
281+
# Behave like a standard shutter controller (up/rotate right = move shutter up, down/rotate left = move shutter
282+
# down, short press to stop movement)
283+
StandardShutter = 0x02
284+
# Behave like an inverted standard shutter controller (up/rotate right = move shutter down, down/rotate left = move
285+
# shutter up, short press to stop movement)
286+
StandardShutterOpposite = 0xFC
287+
# Behave like a Schneider shutter controller using SE custom Window Covering cluster (up/rotate right = move
288+
# shutter up, down/rotate left = move shutter down, short press to stop movement)
289+
SchneiderShutter = 0x03
290+
# Behave like an inverted Schneider shutter controller using SE custom Window Covering cluster (up/rotate right =
291+
# move shutter down, down/rotate left = move shutter up, short press to stop movement)
292+
SchneiderShutterOpposite = 0xFB
293+
# Recall scenes according to the Up/DownSceneID attributes, and group using the Up/DownGroupID attributes.
294+
Scene = 0x04
295+
# No observable function?
296+
ToggleLight = 0x05
297+
# No observable function?
298+
ToggleDimmer = 0x06
299+
# No observable function?
300+
AlternateLight = 0x07
301+
# No observable function?
302+
AlternateDimmer = 0x08
303+
NotUsed = 0x7F
152304

153305

154306
class SESpecific(CustomCluster):
@@ -161,37 +313,50 @@ class SESpecific(CustomCluster):
161313
class AttributeDefs(BaseAttributeDefs):
162314
"""Attribute definitions."""
163315

164-
led_indicator_signals: Final = ZCLAttributeDef(
316+
se_switch_indication: Final = ZCLAttributeDef(
165317
id=0x0000,
166-
type=SELedIndicatorSignals,
318+
type=SESwitchIndication,
167319
is_manufacturer_specific=True,
168320
)
169-
unknown_attribute_1: Final = ZCLAttributeDef(
321+
# Default values depends on endpoint and device type. More info you find in device description.
322+
se_switch_actions: Final = ZCLAttributeDef(
170323
id=0x0001,
171-
type=t.enum8,
324+
type=SESwitchAction,
172325
is_manufacturer_specific=True,
173326
)
174-
unknown_attribute_16: Final = ZCLAttributeDef(
327+
# The UpSceneID attribute represents the Scene Id field value of any Scene command cluster transmitted by the
328+
# device when user activates is rocker up side according to the rocker configuration. See SwitchActions
329+
# attribute.
330+
se_up_scene_id: Final = ZCLAttributeDef(
175331
id=0x0010,
176332
type=t.uint8_t,
177333
is_manufacturer_specific=True,
178334
)
179-
unknown_attribute_17: Final = ZCLAttributeDef(
335+
# The UpGroupID attribute represents the Group Id field value of any Scene command cluster transmitted by the
336+
# device when user activates is rocker up side according to the rocker configuration. Value greater than 0xFFF7
337+
# means, no command is sent. See SwitchActions attribute.
338+
se_up_group_id: Final = ZCLAttributeDef(
180339
id=0x0011,
181340
type=t.uint16_t,
182341
is_manufacturer_specific=True,
183342
)
184-
unknown_attribute_32: Final = ZCLAttributeDef(
343+
# The DownSceneID attribute represents the Scene Id field value of any Scene command cluster transmitted by the
344+
# device when user activates is rocker down side according to the rocker configuration. See SwitchActions
345+
# attribute.
346+
se_down_scene_id: Final = ZCLAttributeDef(
185347
id=0x0020,
186348
type=t.uint8_t,
187349
is_manufacturer_specific=True,
188350
)
189-
unknown_attribute_33: Final = ZCLAttributeDef(
351+
# The DownGroupID attribute represents the Group Id field value of any Scene command cluster transmitted by the
352+
# device when user activates is rocker down side according to the rocker configuration. Value greater than
353+
# 0xFFF7 means, no command is sent. See SwitchActions attribute.
354+
se_down_group_id: Final = ZCLAttributeDef(
190355
id=0x0021,
191356
type=t.uint16_t,
192357
is_manufacturer_specific=True,
193358
)
194-
unknown_attribute_65533: Final = ZCLAttributeDef(
359+
se_cluster_revision: Final = ZCLAttributeDef(
195360
id=0xFFFD,
196361
type=t.uint16_t,
197362
is_manufacturer_specific=True,

zhaquirks/schneiderelectric/dimmers.py

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
"""Schneider Electric dimmers and switches quirks."""
22

3-
from typing import Final
43

54
from zigpy.profiles import zgp, zha
6-
from zigpy.quirks import CustomCluster, CustomDevice
7-
import zigpy.types as t
5+
from zigpy.quirks import CustomDevice
86
from zigpy.zcl.clusters.closures import WindowCovering
97
from zigpy.zcl.clusters.general import (
108
Basic,
@@ -18,7 +16,6 @@
1816
)
1917
from zigpy.zcl.clusters.homeautomation import Diagnostic
2018
from zigpy.zcl.clusters.lighting import Ballast
21-
from zigpy.zcl.foundation import ZCLAttributeDef
2219

2320
from zhaquirks.const import (
2421
DEVICE_TYPE,
@@ -28,35 +25,7 @@
2825
OUTPUT_CLUSTERS,
2926
PROFILE_ID,
3027
)
31-
from zhaquirks.schneiderelectric import SE_MANUF_ID, SE_MANUF_NAME, SEBasic, SESpecific
32-
33-
34-
class ControlMode(t.enum8):
35-
"""Dimming mode for PUCK/DIMMER/* and NHROTARY/DIMMER/1."""
36-
37-
Auto = 0
38-
RC = 1
39-
RL = 2
40-
RL_LED = 3
41-
42-
43-
class SEBallast(CustomCluster, Ballast):
44-
"""Schneider Electric Ballast cluster."""
45-
46-
manufacturer_id_override = SE_MANUF_ID
47-
48-
class AttributeDefs(Ballast.AttributeDefs):
49-
"""Attribute definitions."""
50-
51-
control_mode: Final = ZCLAttributeDef(
52-
id=0xE000, type=ControlMode, is_manufacturer_specific=True
53-
)
54-
unknown_attribute_e001: Final = ZCLAttributeDef(
55-
id=0xE002, type=t.enum8, is_manufacturer_specific=True
56-
)
57-
unknown_attribute_e002: Final = ZCLAttributeDef(
58-
id=0xE002, type=t.enum8, is_manufacturer_specific=True
59-
)
28+
from zhaquirks.schneiderelectric import SE_MANUF_NAME, SEBallast, SEBasic, SESpecific
6029

6130

6231
class NHRotaryDimmer1(CustomDevice):

0 commit comments

Comments
 (0)