Skip to content

Commit 13784c6

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

File tree

2 files changed

+201
-63
lines changed

2 files changed

+201
-63
lines changed

zhaquirks/schneiderelectric/__init__.py

Lines changed: 199 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,161 @@ 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+
# OnTimeReload timer can be canceled by receiving OFF command -> light is going OFF immediately.
89+
# If this bit is not set, the timer can not be canceled, it is always restarted.
90+
OnTimeReloadCanceledByOffCommand = 0x1
91+
92+
# Impulse mode active. Whenever output should be switched ON, it will be switched ON only for 200msec.
93+
# OnTimeReload attributes is ignored, also bit0 inside this attribute has no sense. If this bit is not set,
94+
# impulse mode is disabled.
95+
ImpulseMode = 0x2
96+
97+
98+
class SEOnOff(CustomCluster, OnOff):
99+
"""Schneider Electric manufacturer specific OnOff cluster."""
100+
101+
class AttributeDefs(OnOff.AttributeDefs):
102+
"""Attribute definitions."""
103+
104+
# Has meaning only if attribute OnTimeReload is not 0. Defines number of seconds before the light is switched
105+
# off automaticaly when the user is somehow inform the light will be switched off automaticaly. Value 0 or
106+
# 0xFFFF disables prewarning. For switch is just short switch OFF and ON, for dimmer device goes to 60
107+
# percent and starts slowly dim down. During this time user can reload the time and postpone automatic switch
108+
# off for time defined in OnTimeReload. If you enter value greater than 6553, after reboot you will read again
109+
# value 6553. If you enter 0xFFFF, functionality will be disabled.
110+
se_pre_warming_time: Final = ZCLAttributeDef(
111+
id=0xE000,
112+
type=t.uint16_t,
113+
is_manufacturer_specific=True,
114+
)
115+
116+
# Defines number of seconds before the light is switched off automatically. Time is in seconds.
117+
# Value 0 disable the functionality. When brightness is changed, or ON command is received, timer is always
118+
# restarted. Check OnTimeReloadOptions for possible impulse mode (if attribute is implemented).
119+
se_on_time_reload: Final = ZCLAttributeDef(
120+
id=0xE001,
121+
type=t.uint32_t,
122+
is_manufacturer_specific=True,
123+
)
124+
125+
# Has meaning only if attribute OnTimeReload is not 0. Defines number of seconds before the light is switched
126+
# off automaticaly when the user is somehow inform the light will be switched off automaticaly. Value 0 or
127+
# 0xFFFF disables prewarning. For switch is just short switch OFF and ON, for dimmer device goes to 60
128+
# percent and starts slowly dim down. During this time user can reload the time and postpone automatic switch
129+
# off for time defined in OnTimeReload. If you enter value greater than 6553, after reboot you will read again
130+
# value 6553. If you enter 0xFFFF, functionality will be disabled.
131+
se_on_time_reload_options: Final = ZCLAttributeDef(
132+
id=0xE002,
133+
type=SEOnTimeReloadOptions,
134+
is_manufacturer_specific=True,
135+
)
136+
137+
138+
class SEControlMode(t.enum8):
139+
"""Dimming mode for PUCK/DIMMER/* and NHROTARY/DIMMER/1."""
140+
141+
Auto = 0
142+
RC = 1
143+
RL = 2
144+
RL_LED = 3
145+
146+
147+
class SEWiringMode(t.enum8):
148+
"""Dimmer wiring mode. Default value depends on how the dimmer is connected to the mains."""
149+
150+
TwoWiredMode = 0
151+
ThreeWiredMode = 1
152+
153+
154+
class SEDimmingCurve(t.enum8):
155+
"""Dimmer dimming curve"""
156+
157+
Logarithmic = 0
158+
Linear = 1 # Not supported in current FW, but defined in the spec
159+
Exponential = 2 # Not supported in current FW, but defined in the spec
160+
161+
162+
class SEBallast(CustomCluster, Ballast):
163+
"""Schneider Electric Ballast cluster."""
164+
165+
manufacturer_id_override = SE_MANUF_ID
166+
167+
class AttributeDefs(Ballast.AttributeDefs):
168+
"""Attribute definitions."""
169+
170+
se_control_mode: Final = ZCLAttributeDef(
171+
id=0xE000, type=SEControlMode, is_manufacturer_specific=True
172+
)
173+
se_wiring_mode: Final = ZCLAttributeDef(
174+
id=0xE002, type=t.enum8, is_manufacturer_specific=True
175+
)
176+
se_dimming_curve: Final = ZCLAttributeDef(
177+
id=0xE002, type=t.enum8, is_manufacturer_specific=True
178+
)
63179

64180

65181
class SEWindowCovering(CustomCluster, WindowCovering):
@@ -138,17 +254,57 @@ async def command(
138254
return await super().command(command_id, *args, **kwargs)
139255

140256

141-
class SELedIndicatorSignals(t.enum8):
257+
class SESwitchIndication(t.enum8):
142258
"""Available LED indicator signal combinations.
143259
144260
Shutter movement can be indicated with a red LED signal. A green LED
145261
light permanently provides orientation, if desired.
146262
"""
147263

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

153309

154310
class SESpecific(CustomCluster):
@@ -161,37 +317,50 @@ class SESpecific(CustomCluster):
161317
class AttributeDefs(BaseAttributeDefs):
162318
"""Attribute definitions."""
163319

164-
led_indicator_signals: Final = ZCLAttributeDef(
320+
se_switch_indication: Final = ZCLAttributeDef(
165321
id=0x0000,
166-
type=SELedIndicatorSignals,
322+
type=SESwitchIndication,
167323
is_manufacturer_specific=True,
168324
)
169-
unknown_attribute_1: Final = ZCLAttributeDef(
325+
# Default values depends on endpoint and device type. More info you find in device description.
326+
se_switch_actions: Final = ZCLAttributeDef(
170327
id=0x0001,
171-
type=t.enum8,
328+
type=SESwitchAction,
172329
is_manufacturer_specific=True,
173330
)
174-
unknown_attribute_16: Final = ZCLAttributeDef(
331+
# The UpSceneID attribute represents the Scene Id field value of any Scene command cluster transmitted by the
332+
# device when user activates is rocker up side according to the rocker configuration. See SwitchActions
333+
# attribute.
334+
se_up_scene_id: Final = ZCLAttributeDef(
175335
id=0x0010,
176336
type=t.uint8_t,
177337
is_manufacturer_specific=True,
178338
)
179-
unknown_attribute_17: Final = ZCLAttributeDef(
339+
# The UpGroupID attribute represents the Group Id field value of any Scene command cluster transmitted by the
340+
# device when user activates is rocker up side according to the rocker configuration. Value greater than 0xFFF7
341+
# means, no command is sent. See SwitchActions attribute.
342+
se_up_group_id: Final = ZCLAttributeDef(
180343
id=0x0011,
181344
type=t.uint16_t,
182345
is_manufacturer_specific=True,
183346
)
184-
unknown_attribute_32: Final = ZCLAttributeDef(
347+
# The DownSceneID attribute represents the Scene Id field value of any Scene command cluster transmitted by the
348+
# device when user activates is rocker down side according to the rocker configuration. See SwitchActions
349+
# attribute.
350+
se_down_scene_id: Final = ZCLAttributeDef(
185351
id=0x0020,
186352
type=t.uint8_t,
187353
is_manufacturer_specific=True,
188354
)
189-
unknown_attribute_33: Final = ZCLAttributeDef(
355+
# The DownGroupID attribute represents the Group Id field value of any Scene command cluster transmitted by the
356+
# device when user activates is rocker down side according to the rocker configuration. Value greater than
357+
# 0xFFF7 means, no command is sent. See SwitchActions attribute.
358+
se_down_group_id: Final = ZCLAttributeDef(
190359
id=0x0021,
191360
type=t.uint16_t,
192361
is_manufacturer_specific=True,
193362
)
194-
unknown_attribute_65533: Final = ZCLAttributeDef(
363+
se_cluster_revision: Final = ZCLAttributeDef(
195364
id=0xFFFD,
196365
type=t.uint16_t,
197366
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)