Skip to content

Commit 432b6bc

Browse files
su-shankarzr
authored andcommitted
SwitchAll: Pull request #2834: UIC-3412: Created attribute resolver rules and write handling
Relate-to: #145 Signed-off-by: Philippe Coval <philippe.coval@silabs.com>
1 parent 0d86887 commit 432b6bc

File tree

1 file changed

+152
-40
lines changed

1 file changed

+152
-40
lines changed

applications/zpc/components/zwave_command_classes/src/zwave_command_class_switch_all.cpp

Lines changed: 152 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@
4545
// Log tag
4646
constexpr char LOG_TAG[] = "zwave_command_class_switch_all";
4747

48+
enum class switch_all_mode_t : uint8_t {
49+
DEVICE_EXCLUDED = 0x00,
50+
DEVICE_ONLY_ON = 0x01,
51+
DEVICE_ONLY_OFF = 0x02,
52+
DEVICE_ON_OFF = 0xFF
53+
};
54+
55+
constexpr uint8_t SWITCH_ALL_ON_VALUE = 1;
56+
constexpr uint8_t SWITCH_ALL_OFF_VALUE = 0;
4857

4958
namespace
5059
{
@@ -68,39 +77,87 @@ zwave_cc_version_t get_current_switch_all_version(attribute_store_node_t node)
6877
///////////////////////////////////////////////////////////////////////////////
6978
// Resolution functions
7079
///////////////////////////////////////////////////////////////////////////////
71-
//static sl_status_t zwave_command_class_switch_all_get(
72-
// attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
73-
//{
74-
// return frame_generator.generate_no_args_frame(switch_all_GET,
75-
// frame,
76-
// frame_length);
77-
//}
80+
static sl_status_t zwave_command_class_switch_all_set_on_off(
81+
attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
82+
{
83+
try {
84+
attribute_store::attribute value_node(node);
85+
// Creating the frame
86+
if (value_node.type() != ATTRIBUTE(ON_OFF)) {
87+
return SL_STATUS_INVALID_TYPE;
88+
}
89+
auto mode = static_cast<switch_all_mode_t>(
90+
value_node.parent().child_by_type(ATTRIBUTE(MODE)).reported<uint8_t>());
91+
bool send_command = false;
92+
uint8_t zwave_command_id;
93+
auto on_off_desired = value_node.desired<uint8_t>();
7894

79-
// static sl_status_t zwave_command_class_switch_all_set(
80-
// attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
81-
// {
82-
// try {
83-
// attribute_store::attribute value_node(node);
84-
// auto current_version = get_current_switch_all_version(node);
85-
//
86-
// // Compute expected size for set frame
87-
// const uint8_t expected_frame_size = 12;
88-
//
89-
// // Creating the frame
90-
// frame_generator.initialize_frame(switch_all_SET,
91-
// frame,
92-
// expected_frame_size);
93-
// frame_generator.add_value(value_node, DESIRED_OR_REPORTED_ATTRIBUTE);
94-
// frame_generator.validate_frame(frame_length);
95-
// } catch (const std::exception &e) {
96-
// sl_log_error(LOG_TAG,
97-
// "Error while generating switch_all Set frame : %s",
98-
// e.what());
99-
// return SL_STATUS_FAIL;
100-
// }
101-
//
102-
// return SL_STATUS_OK;
103-
//}
95+
switch (on_off_desired) {
96+
case SWITCH_ALL_ON_VALUE:
97+
zwave_command_id = SWITCH_ALL_ON;
98+
send_command = (mode == switch_all_mode_t::DEVICE_ONLY_ON
99+
|| mode == switch_all_mode_t::DEVICE_ON_OFF);
100+
break;
101+
case SWITCH_ALL_OFF_VALUE:
102+
zwave_command_id = SWITCH_ALL_OFF;
103+
send_command = (mode == switch_all_mode_t::DEVICE_ONLY_OFF
104+
|| mode == switch_all_mode_t::DEVICE_ON_OFF);
105+
break;
106+
default:
107+
return SL_STATUS_INVALID_RANGE;
108+
}
109+
if (!send_command) {
110+
sl_log_debug(LOG_TAG,
111+
"Not sending command %d since mode is %d",
112+
zwave_command_id,
113+
mode);
114+
return SL_STATUS_OK;
115+
}
116+
return frame_generator.generate_no_args_frame(zwave_command_id,
117+
frame,
118+
frame_length);
119+
} catch (const std::exception &e) {
120+
sl_log_error(LOG_TAG,
121+
"Error while generating switch_all Set frame : %s",
122+
e.what());
123+
return SL_STATUS_FAIL;
124+
}
125+
126+
return SL_STATUS_OK;
127+
}
128+
129+
static sl_status_t zwave_command_class_switch_all_get(
130+
attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
131+
{
132+
if (attribute_store_get_node_type(node) == ATTRIBUTE(MODE)) {
133+
return frame_generator.generate_no_args_frame(SWITCH_ALL_GET,
134+
frame,
135+
frame_length);
136+
}
137+
return SL_STATUS_INVALID_TYPE;
138+
}
139+
140+
static sl_status_t zwave_command_class_switch_all_set(
141+
attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
142+
{
143+
try {
144+
attribute_store::attribute value_node(node);
145+
// Creating the frame
146+
if (value_node.type() == ATTRIBUTE(MODE)) {
147+
frame_generator.initialize_frame(SWITCH_ALL_SET, frame, 3);
148+
frame_generator.add_value(value_node, DESIRED_ATTRIBUTE);
149+
frame_generator.validate_frame(frame_length);
150+
}
151+
return SL_STATUS_INVALID_TYPE;
152+
} catch (const std::exception &e) {
153+
sl_log_error(LOG_TAG,
154+
"Error while generating switch_all Set frame : %s",
155+
e.what());
156+
return SL_STATUS_FAIL;
157+
}
158+
159+
return SL_STATUS_OK;
160+
}
104161

105162
///////////////////////////////////////////////////////////////////////////////
106163
// Frame parsing functions
@@ -187,13 +244,65 @@ static void zwave_command_class_switch_all_on_version_attribute_update(
187244

188245
// Now we know we have a switch_all supporting endpoint.
189246
attribute_store::attribute endpoint_node
190-
= version_node.first_parent(ATTRIBUTE_ENDPOINT_ID);
247+
= version_node.first_parent(ATTRIBUTE_ENDPOINT_ID);
191248

192249
// Create the switch_all attributes
193250
endpoint_node.emplace_node(ATTRIBUTE(MODE));
194251

195252
endpoint_node.emplace_node(ATTRIBUTE(ON_OFF));
253+
}
254+
255+
sl_status_t
256+
zwave_command_class_check_ep_support(const dotdot_unid_t unid,
257+
const dotdot_endpoint_id_t endpoint)
258+
{
259+
attribute_store::attribute node
260+
= attribute_store_network_helper_get_node_id_node(unid);
261+
attribute_store::attribute ep
262+
= node.child_by_type_and_value<>(ATTRIBUTE_ENDPOINT_ID, endpoint);
263+
264+
if (ep.child_by_type(ATTRIBUTE(MODE)).is_valid())
265+
return SL_STATUS_OK;
266+
return SL_STATUS_FAIL;
267+
}
196268

269+
sl_status_t zwave_command_class_unify_switch_all_write_attributes_callback(
270+
const dotdot_unid_t unid,
271+
const dotdot_endpoint_id_t endpoint,
272+
uic_mqtt_dotdot_callback_call_type_t call_type,
273+
uic_mqtt_dotdot_unify_switch_all_state_t value,
274+
uic_mqtt_dotdot_unify_switch_all_updated_state_t changed)
275+
{
276+
if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) {
277+
return zwave_command_class_check_ep_support(unid, endpoint);
278+
}
279+
280+
attribute_store::attribute home
281+
= attribute_store_network_helper_get_home_id_node(unid);
282+
283+
if (changed.mode) {
284+
attribute_store::attribute node
285+
= attribute_store_network_helper_get_node_id_node(unid);
286+
attribute_store::attribute ep
287+
= node.child_by_type_and_value<>(ATTRIBUTE_ENDPOINT_ID, endpoint);
288+
attribute_store::attribute mode
289+
= ep.emplace_node(DOTDOT_ATTRIBUTE_ID_UNIFY_SWITCH_ALL_MODE);
290+
291+
sl_log_debug(LOG_TAG, "write callback set desired mode");
292+
mode.set_desired<>(value.mode);
293+
}
294+
if (changed.on_off) {
295+
for (auto node: home.children()) {
296+
auto ep = node.child_by_type(ATTRIBUTE_ENDPOINT_ID);
297+
auto on_off
298+
= ep.emplace_node(DOTDOT_ATTRIBUTE_ID_UNIFY_SWITCH_ALL_ON_OFF);
299+
300+
sl_log_debug(LOG_TAG, "write callback set desired on_off");
301+
on_off.set_desired<>(value.on_off);
302+
}
303+
}
304+
305+
return SL_STATUS_OK;
197306
}
198307

199308
///////////////////////////////////////////////////////////////////////////////
@@ -207,19 +316,22 @@ sl_status_t zwave_command_class_switch_all_init()
207316
ATTRIBUTE(VERSION));
208317

209318
// Attribute resolver rules
210-
// attribute_resolver_register_rule(ATTRIBUTE(MODE),
211-
// zwave_command_class_switch_all_set,
212-
// zwave_command_class_switch_all_get);
213-
// attribute_resolver_register_rule(ATTRIBUTE(ON_OFF),
214-
// zwave_command_class_switch_all_set,
215-
// nullptr);
319+
attribute_resolver_register_rule(ATTRIBUTE(MODE),
320+
zwave_command_class_switch_all_set,
321+
zwave_command_class_switch_all_get);
322+
attribute_resolver_register_rule(ATTRIBUTE(ON_OFF),
323+
zwave_command_class_switch_all_set_on_off,
324+
nullptr);
325+
// Attribute write callback
326+
uic_mqtt_dotdot_set_unify_switch_all_write_attributes_callback(
327+
zwave_command_class_unify_switch_all_write_attributes_callback);
216328

217329
// The support side of things: Register our handler to the Z-Wave CC framework:
218330
zwave_command_handler_t handler = {};
219331
handler.support_handler = NULL;
220332
handler.control_handler = &zwave_command_class_switch_all_control_handler;
221333
// Not supported, so this does not really matter
222-
handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NETWORK_SCHEME;
334+
handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NETWORK_SCHEME;
223335
handler.manual_security_validation = false;
224336
handler.command_class = COMMAND_CLASS_SWITCH_ALL;
225337
handler.version = SWITCH_ALL_VERSION;

0 commit comments

Comments
 (0)