Skip to content

Commit 5c9fd87

Browse files
committed
GH-33: Thermostat Fan State CC
Forwarded: #33 Bug-SiliconLabs: UIC-3070 Bug-Github: #33
1 parent f43e152 commit 5c9fd87

File tree

8 files changed

+424
-0
lines changed

8 files changed

+424
-0
lines changed

applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,17 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_MODE_SUPPORTED_MODES,
705705
/// Off flag (v2+)
706706
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_MODE_OFF_FLAG,
707707
((COMMAND_CLASS_THERMOSTAT_FAN_MODE << 8) | 0x05))
708+
709+
/////////////////////////////////////////////////
710+
// Thermostat Fan State Command Class
711+
/// zwave_cc_version_t
712+
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_VERSION,
713+
ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_THERMOSTAT_FAN_STATE))
714+
/// Current Fan operating state
715+
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_FAN_OPERATING_STATE,
716+
((COMMAND_CLASS_THERMOSTAT_FAN_STATE << 8) | 0x02))
717+
718+
708719
/////////////////////////////////////////////////
709720
// Wakeup command class
710721
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_WAKE_UP_VERSION,

applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,12 @@ static const std::vector<attribute_schema_t> attribute_schema = {
313313
{ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_MODE_SUPPORTED_MODES, "Thermostat Supported Fan Mode Bitmask", ATTRIBUTE_ENDPOINT_ID, U32_STORAGE_TYPE},
314314
{ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_MODE_OFF_FLAG, "Thermostat Fan Off Flag", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE },
315315

316+
/////////////////////////////////////////////////////////////////////
317+
// Thermostat Fan State Command Class attributes
318+
/////////////////////////////////////////////////////////////////////
319+
{ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_VERSION, "Thermostat Fan State Version", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
320+
{ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_FAN_OPERATING_STATE, "Thermostat Fan Operating State", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
321+
316322
/////////////////////////////////////////////////////////////////////
317323
// Supervision Command Class attributes
318324
/////////////////////////////////////////////////////////////////////

applications/zpc/components/zwave_command_classes/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ add_library(
4646
src/zwave_command_class_switch_multilevel.c
4747
src/zwave_command_class_thermostat_mode.c
4848
src/zwave_command_class_thermostat_fan_mode.c
49+
src/zwave_command_class_thermostat_fan_state.c
4950
src/zwave_command_class_thermostat_setpoint.c
5051
src/zwave_command_class_time.c
5152
src/zwave_command_class_user_code.c
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
2+
/******************************************************************************
3+
* # License
4+
* <b>Copyright 2024 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+
15+
// System
16+
#include <stdlib.h>
17+
18+
#include "zwave_command_class_thermostat_fan_state.h"
19+
#include "zwave_command_class_thermostat_fan_types.h"
20+
#include "zwave_command_classes_utils.h"
21+
#include "ZW_classcmd.h"
22+
23+
// Includes from other ZPC Components
24+
#include "zwave_command_class_indices.h"
25+
#include "zwave_command_handler.h"
26+
#include "zwave_command_class_version_types.h"
27+
#include "zpc_attribute_store_network_helper.h"
28+
#include "attribute_store_defined_attribute_types.h"
29+
30+
// Unify
31+
#include "attribute_resolver.h"
32+
#include "attribute_store.h"
33+
#include "attribute_store_helper.h"
34+
#include "sl_log.h"
35+
36+
#define LOG_TAG "zwave_command_class_thermostat_fan_state"
37+
38+
/////////////////////////////////////////////////////////////////////////////
39+
// Version & Attribute Creation
40+
/////////////////////////////////////////////////////////////////////////////
41+
static void zwave_command_class_thermostat_fan_state_on_version_attribute_update(
42+
attribute_store_node_t updated_node, attribute_store_change_t change)
43+
{
44+
if (change == ATTRIBUTE_DELETED) {
45+
return;
46+
}
47+
48+
if (is_zwave_command_class_filtered_for_root_device(
49+
COMMAND_CLASS_THERMOSTAT_FAN_STATE,
50+
updated_node)
51+
== true) {
52+
return;
53+
}
54+
55+
zwave_cc_version_t version = 0;
56+
attribute_store_get_reported(updated_node, &version, sizeof(version));
57+
58+
if (version == 0) {
59+
return;
60+
}
61+
62+
attribute_store_node_t endpoint_node
63+
= attribute_store_get_first_parent_with_type(updated_node,
64+
ATTRIBUTE_ENDPOINT_ID);
65+
66+
// The order of the attribute matter since it defines the order of the
67+
// Z-Wave get command order.
68+
const attribute_store_type_t attributes[]
69+
= {ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_FAN_OPERATING_STATE};
70+
71+
attribute_store_add_if_missing(endpoint_node,
72+
attributes,
73+
COUNT_OF(attributes));
74+
75+
}
76+
77+
/////////////////////////////////////////////////////////////////////////////
78+
// Thermostat Fan State Get/Report
79+
/////////////////////////////////////////////////////////////////////////////
80+
81+
static sl_status_t zwave_command_class_thermostat_fan_state_get(
82+
attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
83+
{
84+
(void)node; // unused.
85+
ZW_THERMOSTAT_FAN_STATE_GET_FRAME *get_frame
86+
= (ZW_THERMOSTAT_FAN_STATE_GET_FRAME *)frame;
87+
get_frame->cmdClass = COMMAND_CLASS_THERMOSTAT_FAN_STATE;
88+
get_frame->cmd = THERMOSTAT_FAN_STATE_GET;
89+
*frame_length = sizeof(ZW_THERMOSTAT_FAN_STATE_GET_FRAME);
90+
return SL_STATUS_OK;
91+
}
92+
93+
sl_status_t zwave_command_class_thermostat_fan_state_handle_report(
94+
const zwave_controller_connection_info_t *connection_info,
95+
const uint8_t *frame_data,
96+
uint16_t frame_length)
97+
{
98+
if (frame_length < 3) {
99+
return SL_STATUS_FAIL;
100+
}
101+
102+
thermostat_fan_state_t fan_state = frame_data[2] & THERMOSTAT_FAN_STATE_REPORT_LEVEL_FAN_OPERATING_STATE_MASK;
103+
104+
attribute_store_node_t endpoint_node
105+
= zwave_command_class_get_endpoint_node(connection_info);
106+
107+
attribute_store_set_child_reported(
108+
endpoint_node,
109+
ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_FAN_OPERATING_STATE,
110+
&fan_state,
111+
sizeof(fan_state));
112+
113+
return SL_STATUS_OK;
114+
}
115+
116+
sl_status_t zwave_command_class_thermostat_fan_state_control_handler(
117+
const zwave_controller_connection_info_t *connection_info,
118+
const uint8_t *frame_data,
119+
uint16_t frame_length)
120+
{
121+
if (frame_length <= COMMAND_INDEX) {
122+
return SL_STATUS_NOT_SUPPORTED;
123+
}
124+
125+
switch (frame_data[COMMAND_INDEX]) {
126+
case THERMOSTAT_FAN_STATE_REPORT:
127+
return zwave_command_class_thermostat_fan_state_handle_report(
128+
connection_info,
129+
frame_data,
130+
frame_length);
131+
default:
132+
return SL_STATUS_NOT_SUPPORTED;
133+
}
134+
}
135+
136+
137+
sl_status_t zwave_command_class_thermostat_fan_state_init()
138+
{
139+
attribute_store_register_callback_by_type(
140+
&zwave_command_class_thermostat_fan_state_on_version_attribute_update,
141+
ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_VERSION);
142+
143+
attribute_resolver_register_rule(
144+
ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_FAN_OPERATING_STATE,
145+
NULL,
146+
&zwave_command_class_thermostat_fan_state_get);
147+
148+
149+
zwave_command_handler_t handler = {};
150+
handler.support_handler = NULL;
151+
handler.control_handler
152+
= zwave_command_class_thermostat_fan_state_control_handler;
153+
handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NONE;
154+
handler.manual_security_validation = false;
155+
handler.command_class = COMMAND_CLASS_THERMOSTAT_FAN_STATE;
156+
handler.version = 2;
157+
handler.command_class_name = "Thermostat Fan State";
158+
handler.comments = "Experimental";
159+
160+
return zwave_command_handler_register_handler(handler);
161+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
/******************************************************************************
3+
* # License
4+
* <b>Copyright 2024 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+
15+
/**
16+
* @defgroup zwave_command_class_thermostat_fan_state
17+
* @brief Sound Switch Command Class handlers and control function
18+
*
19+
* This module implement some of the functions to control the
20+
* Sound Switch Command Class
21+
*
22+
* @{
23+
*/
24+
25+
#ifndef ZWAVE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_H
26+
#define ZWAVE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_H
27+
28+
#include "sl_status.h"
29+
30+
#ifdef __cplusplus
31+
extern "C" {
32+
#endif
33+
34+
sl_status_t zwave_command_class_thermostat_fan_state_init();
35+
36+
#ifdef __cplusplus
37+
}
38+
#endif
39+
40+
#endif //ZWAVE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_H
41+
/** @} end zwave_command_class_thermostat_fan_state */

applications/zpc/components/zwave_command_classes/src/zwave_command_classes_fixt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "zwave_command_class_switch_multilevel.h"
4242
#include "zwave_command_class_thermostat_mode.h"
4343
#include "zwave_command_class_thermostat_fan_mode.h"
44+
#include "zwave_command_class_thermostat_fan_state.h"
4445
#include "zwave_command_class_thermostat_setpoint.h"
4546
#include "zwave_command_class_version.h"
4647
#include "zwave_command_class_wake_up.h"
@@ -110,6 +111,7 @@ sl_status_t zwave_command_classes_init()
110111
status |= zwave_command_class_switch_multilevel_init();
111112
status |= zwave_command_class_thermostat_mode_init();
112113
status |= zwave_command_class_thermostat_fan_mode_init();
114+
status |= zwave_command_class_thermostat_fan_state_init();
113115
status |= zwave_command_class_thermostat_setpoint_init();
114116
status |= zwave_command_class_time_init();
115117
status |= zwave_command_class_transport_service_init();

applications/zpc/components/zwave_command_classes/test/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,22 @@ target_add_unittest(
651651
uic_attribute_resolver_mock
652652
zpc_attribute_resolver_mock
653653
uic_dotdot_mqtt_mock)
654+
655+
# Thermostat fan state test
656+
target_add_unittest(
657+
zwave_command_classes
658+
NAME
659+
zwave_command_class_thermostat_fan_state_test
660+
SOURCES
661+
zwave_command_class_thermostat_fan_state_test.c
662+
DEPENDS
663+
zpc_attribute_store_test_helper
664+
zwave_controller
665+
zwave_command_handler_mock
666+
uic_attribute_resolver_mock
667+
zpc_attribute_resolver_mock
668+
uic_dotdot_mqtt_mock)
669+
654670
# Tests for generated command classes
655671
set(GEN_TEST_INCLUDES
656672
"${CMAKE_SOURCE_DIR}/applications/zpc/components/zwave_controller/include"

0 commit comments

Comments
 (0)