Skip to content

Commit 9ec15e2

Browse files
Vietrzr
authored andcommitted
UIC-3272: Custom Switch Color cluster
Origin: #146 Signed-off-by: Philippe Coval <philippe.coval@silabs.com>
1 parent c145d8d commit 9ec15e2

File tree

6 files changed

+857
-2
lines changed

6 files changed

+857
-2
lines changed

applications/zpc/components/zcl_cluster_servers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ add_library(
1717
src/zcl_OTA_cluster_server.cpp
1818
src/zcl_rf_telemetry_cluster_server.c
1919
src/zcl_scenes_cluster_server.cpp
20+
src/switch_color_cluster_server.cpp
2021
)
2122

2223
target_include_directories(
Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
2+
/******************************************************************************
3+
* # License
4+
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
5+
******************************************************************************
6+
* The licensor of this software is Silicon Laboratories Inc. Your use of this
7+
* software is governed by the terms of Silicon Labs Master Software License
8+
* Agreement (MSLA) available at
9+
* www.silabs.com/about-us/legal/master-software-license-agreement. This
10+
* software is distributed to you in Source Code format and is governed by the
11+
* sections of the MSLA applicable to Source Code.
12+
*
13+
*****************************************************************************/
14+
// Includes from this component
15+
#include "switch_color_cluster_server.h"
16+
17+
// Includes from Unify
18+
#include "sl_log.h"
19+
#include "sl_status.h"
20+
#include "attribute_store_helper.h"
21+
#include "attribute_store.h"
22+
#include "zpc_attribute_store_network_helper.h"
23+
#include "zwave_command_class_color_switch_types.h"
24+
25+
#include "attribute_store_defined_attribute_types.h"
26+
#include "unify_dotdot_defined_attribute_types.h"
27+
#include "unify_dotdot_attribute_store.h"
28+
#include "unify_dotdot_attribute_store_node_state.h"
29+
#include "unify_dotdot_attribute_store_helpers.h"
30+
31+
// Includes from auto-generated files
32+
#include "dotdot_mqtt.h"
33+
34+
// Cpp include
35+
#include "attribute.hpp"
36+
37+
// Setup Log ID
38+
#define LOG_TAG "switch_color_cluster_server"
39+
40+
// Attribute macro, shortening those long defines for attribute types:
41+
#define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_SWITCH_COLOR_##type
42+
43+
////////////////////////////////////////////////////////////////////////////////
44+
// Private helper functions
45+
////////////////////////////////////////////////////////////////////////////////
46+
attribute_store_node_t
47+
get_state_node_by_unid_endpoint(dotdot_unid_t unid,
48+
attribute_store_node_t endpoint)
49+
{
50+
attribute_store::attribute endpoint_node
51+
= attribute_store_network_helper_get_endpoint_node(unid, endpoint);
52+
return endpoint_node.child_by_type(ATTRIBUTE(STATE));
53+
}
54+
55+
attribute_store_node_t
56+
get_duration_node_by_unid_endpoint(dotdot_unid_t unid,
57+
attribute_store_node_t endpoint)
58+
{
59+
attribute_store::attribute state_node
60+
= get_state_node_by_unid_endpoint(unid, endpoint);
61+
attribute_store::attribute duration_node
62+
= state_node.child_by_type(ATTRIBUTE(DURATION));
63+
64+
return duration_node;
65+
}
66+
67+
attribute_store_node_t
68+
get_up_down_node_by_unid_endpoint(dotdot_unid_t unid,
69+
attribute_store_node_t endpoint)
70+
{
71+
attribute_store::attribute state_node
72+
= get_state_node_by_unid_endpoint(unid, endpoint);
73+
attribute_store::attribute up_down
74+
= state_node.child_by_type(ATTRIBUTE(UP_DOWN));
75+
76+
return up_down;
77+
}
78+
79+
attribute_store_node_t
80+
get_ignore_start_level_node_by_unid_endpoint(dotdot_unid_t unid,
81+
attribute_store_node_t endpoint)
82+
{
83+
attribute_store::attribute state_node
84+
= get_state_node_by_unid_endpoint(unid, endpoint);
85+
attribute_store::attribute ignore_start_level_node
86+
= state_node.child_by_type(ATTRIBUTE(IGNORE_START_LEVEL));
87+
88+
return ignore_start_level_node;
89+
}
90+
91+
attribute_store_node_t
92+
get_start_level_node_by_unid_endpoint(dotdot_unid_t unid,
93+
attribute_store_node_t endpoint)
94+
{
95+
attribute_store::attribute state_node
96+
= get_state_node_by_unid_endpoint(unid, endpoint);
97+
attribute_store::attribute start_level_node
98+
= state_node.child_by_type(ATTRIBUTE(START_LEVEL));
99+
100+
return start_level_node;
101+
}
102+
103+
attribute_store_node_t
104+
get_start_change_node_by_unid_endpoint_color_component_id(
105+
dotdot_unid_t unid,
106+
attribute_store_node_t endpoint,
107+
uint8_t color_component_id)
108+
{
109+
attribute_store::attribute state_node
110+
= get_state_node_by_unid_endpoint(unid, endpoint);
111+
attribute_store::attribute color_component_id_node
112+
= state_node.child_by_type_and_value(ATTRIBUTE(COLOR_COMPONENT_ID),
113+
color_component_id);
114+
115+
attribute_store::attribute start_change_node
116+
= color_component_id_node.child_by_type(ATTRIBUTE(START_CHANGE));
117+
118+
return start_change_node;
119+
}
120+
121+
attribute_store_node_t get_stop_change_node_by_unid_endpoint_color_component_id(
122+
dotdot_unid_t unid,
123+
attribute_store_node_t endpoint,
124+
uint8_t color_component_id)
125+
{
126+
attribute_store::attribute state_node
127+
= get_state_node_by_unid_endpoint(unid, endpoint);
128+
attribute_store::attribute color_component_id_node
129+
= state_node.child_by_type_and_value(ATTRIBUTE(COLOR_COMPONENT_ID),
130+
color_component_id);
131+
132+
attribute_store::attribute stop_change_node
133+
= color_component_id_node.child_by_type(ATTRIBUTE(STOP_CHANGE));
134+
135+
return stop_change_node;
136+
}
137+
138+
sl_status_t unify_switch_color_cluster_set_color_command(
139+
const dotdot_unid_t unid,
140+
const dotdot_endpoint_id_t endpoint,
141+
uic_mqtt_dotdot_callback_call_type_t callback_type,
142+
uint8_t color_component_id,
143+
uint8_t value,
144+
uint32_t duration)
145+
{
146+
try {
147+
if (callback_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) {
148+
return dotdot_is_any_unify_switch_color_attribute_supported(unid,
149+
endpoint)
150+
? SL_STATUS_OK
151+
: SL_STATUS_FAIL;
152+
}
153+
154+
sl_log_debug(LOG_TAG,
155+
"Updating ZCL desired values after Unify_SwitchColor::Set "
156+
"command. color_component_id: %d, value :%d, duration : %d",
157+
color_component_id,
158+
value,
159+
duration);
160+
161+
sl_status_t result = SL_STATUS_FAIL;
162+
163+
//Set value for attribute by color component id
164+
switch (color_component_id) {
165+
case WARM_WHITE:
166+
result = dotdot_set_unify_switch_color_warm_white(unid,
167+
endpoint,
168+
DESIRED_ATTRIBUTE,
169+
value);
170+
break;
171+
case COLD_WHITE:
172+
result = dotdot_set_unify_switch_color_cold_white(unid,
173+
endpoint,
174+
DESIRED_ATTRIBUTE,
175+
value);
176+
break;
177+
case RED:
178+
result = dotdot_set_unify_switch_color_red(unid,
179+
endpoint,
180+
DESIRED_ATTRIBUTE,
181+
value);
182+
break;
183+
case GREEN:
184+
result = dotdot_set_unify_switch_color_green(unid,
185+
endpoint,
186+
DESIRED_ATTRIBUTE,
187+
value);
188+
break;
189+
case BLUE:
190+
result = dotdot_set_unify_switch_color_blue(unid,
191+
endpoint,
192+
DESIRED_ATTRIBUTE,
193+
value);
194+
break;
195+
case AMBER:
196+
result = dotdot_set_unify_switch_color_amber(unid,
197+
endpoint,
198+
DESIRED_ATTRIBUTE,
199+
value);
200+
break;
201+
case CYAN:
202+
result = dotdot_set_unify_switch_color_cyan(unid,
203+
endpoint,
204+
DESIRED_ATTRIBUTE,
205+
value);
206+
break;
207+
case PURPLE:
208+
result = dotdot_set_unify_switch_color_purple(unid,
209+
endpoint,
210+
DESIRED_ATTRIBUTE,
211+
value);
212+
break;
213+
default:
214+
sl_log_debug(
215+
LOG_TAG,
216+
"Invalid Colol Component ID Unify_SwitchColor::Set command");
217+
break;
218+
}
219+
220+
if (result != SL_STATUS_OK) {
221+
sl_log_warning(LOG_TAG, "Can't set value for Unify Switch Color cluster");
222+
return SL_STATUS_FAIL;
223+
}
224+
// Find duration node and set desired value
225+
attribute_store::attribute duration_node
226+
= get_duration_node_by_unid_endpoint(unid, endpoint);
227+
if (duration_node.is_valid()) {
228+
duration_node.set_desired<uint32_t>(duration);
229+
}
230+
} catch (const std::exception &e) {
231+
sl_log_error(
232+
LOG_TAG,
233+
"Error while handle unify_switch_color_cluster_set_color_command : %s",
234+
e.what());
235+
return SL_STATUS_FAIL;
236+
}
237+
return SL_STATUS_OK;
238+
}
239+
240+
sl_status_t unify_switch_color_cluster_start_stop_change_command(
241+
const dotdot_unid_t unid,
242+
const dotdot_endpoint_id_t endpoint,
243+
uic_mqtt_dotdot_callback_call_type_t callback_type,
244+
bool start_stop,
245+
bool up_down,
246+
bool ignor_start_level,
247+
uint8_t color_component_id,
248+
uint8_t start_level,
249+
uint32_t duration)
250+
{
251+
try {
252+
if (callback_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) {
253+
return dotdot_is_any_unify_switch_color_attribute_supported(unid,
254+
endpoint)
255+
? SL_STATUS_OK
256+
: SL_STATUS_FAIL;
257+
}
258+
259+
sl_log_debug(LOG_TAG,
260+
"Updating ZCL desired values after Unify_SwitchColor::Start "
261+
"Stop Change command");
262+
263+
// Find duration node and set desired value
264+
attribute_store::attribute duration_node
265+
= get_duration_node_by_unid_endpoint(unid, endpoint);
266+
if (duration_node.is_valid()) {
267+
duration_node.set_desired<uint32_t>(duration);
268+
}
269+
270+
// Find up down node and set desired value
271+
attribute_store::attribute up_down_node
272+
= get_up_down_node_by_unid_endpoint(unid, endpoint);
273+
up_down_node.set_desired<uint8_t>(up_down);
274+
275+
// Find irnore start level node and set desired value
276+
attribute_store::attribute ignore_start_level_node
277+
= get_ignore_start_level_node_by_unid_endpoint(unid, endpoint);
278+
ignore_start_level_node.set_desired<uint8_t>(ignor_start_level);
279+
280+
// Find start level node and set desired value
281+
attribute_store::attribute start_level_node
282+
= get_start_level_node_by_unid_endpoint(unid, endpoint);
283+
start_level_node.set_desired<uint8_t>(start_level);
284+
285+
if (start_stop) {
286+
attribute_store::attribute start_change_node
287+
= get_start_change_node_by_unid_endpoint_color_component_id(
288+
unid,
289+
endpoint,
290+
color_component_id);
291+
start_change_node.set_desired<uint8_t>(start_stop);
292+
} else {
293+
attribute_store::attribute stop_change_node
294+
= get_stop_change_node_by_unid_endpoint_color_component_id(
295+
unid,
296+
endpoint,
297+
color_component_id);
298+
stop_change_node.set_desired<uint8_t>(!start_stop);
299+
}
300+
} catch (const std::exception &e) {
301+
sl_log_error(LOG_TAG,
302+
"Error while handle "
303+
"unify_switch_color_cluster_start_stop_change_command : %s",
304+
e.what());
305+
return SL_STATUS_FAIL;
306+
}
307+
return SL_STATUS_OK;
308+
}
309+
310+
///////////////////////////////////////////////////////////////////////////////
311+
// Init and teardown functions
312+
///////////////////////////////////////////////////////////////////////////////
313+
sl_status_t switch_color_cluster_server_init()
314+
{
315+
sl_log_debug(LOG_TAG, "SwitchColor cluster (ZWave) server initialization");
316+
317+
uic_mqtt_dotdot_unify_switch_color_set_color_callback_set(
318+
&unify_switch_color_cluster_set_color_command);
319+
uic_mqtt_dotdot_unify_switch_color_start_stop_change_callback_set(
320+
&unify_switch_color_cluster_start_stop_change_command);
321+
return SL_STATUS_OK;
322+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/******************************************************************************
2+
* # License
3+
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
4+
******************************************************************************
5+
* The licensor of this software is Silicon Laboratories Inc. Your use of this
6+
* software is governed by the terms of Silicon Labs Master Software License
7+
* Agreement (MSLA) available at
8+
* www.silabs.com/about-us/legal/master-software-license-agreement. This
9+
* software is distributed to you in Source Code format and is governed by the
10+
* sections of the MSLA applicable to Source Code.
11+
*
12+
*****************************************************************************/
13+
14+
/**
15+
* @defgroup zpc_on_off_cluster_mapper ZPC Fan Control
16+
* @ingroup dotdot_mapper
17+
* @brief Maps OnOff Cluster incoming Commands to attribute modifications.
18+
*
19+
* @{
20+
*/
21+
22+
#ifndef SWITCH_COLOR_CLUSTER_SERVER_H
23+
#define SWITCH_COLOR_CLUSTER_SERVER_H
24+
25+
// Generic includes
26+
#include "sl_status.h"
27+
28+
#ifdef __cplusplus
29+
extern "C" {
30+
#endif
31+
32+
/**
33+
* @brief Initialize the FanControl cluster server
34+
*
35+
* @returns true on success
36+
* @returns false on failure
37+
*
38+
*/
39+
sl_status_t switch_color_cluster_server_init(void);
40+
41+
#ifdef __cplusplus
42+
}
43+
#endif
44+
45+
#endif //SWITCH_COLOR_CLUSTER_SERVER_H
46+
/** @} end switch_color_cluster_server */

applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "zcl_OTA_cluster_server.hpp"
2020
#include "user_code_cluster_server.h"
2121
#include "fan_control_cluster_server.h"
22+
#include "switch_color_cluster_server.cpp"
2223

2324
//Includes from other components
2425
#include "attribute_store.h"
@@ -42,7 +43,8 @@ sl_status_t zcl_cluster_servers_init()
4243
init_status |= zcl_scenes_cluster_server_init();
4344
init_status |= user_code_cluster_server_init();
4445
init_status |= fan_control_cluster_server_init();
45-
46+
init_status |= switch_color_cluster_server_init();
47+
4648
return init_status;
4749
}
4850

0 commit comments

Comments
 (0)