Skip to content

Commit 049707c

Browse files
ptphan28rzr
authored andcommitted
UIC-3273: Custom Unify_MultilevelSensor cluster
[Philippe Coval] This patch was split in two, this version is the change that apply to Unify, please refer to previous commit to undestand the flow, I after the failed cherry-pick, I just used patch -p1 < patch and commited only the changes that applies to Unify, the same operation should be done for z-p-c project (in the opposite way). Origin: ver_1.7.0-unstable-23-g38f24ffb48 Bug-SiliconLabs: UIC-3273 Origin: s.s.com/projects/UIC/repos/uic/pull-requests/2855 Relate-to: SiliconLabsSoftware/z-wave-protocol-controller#44 Forwarded: https://github.com/rzr/UnifySDK/tree/z-wave/core/zpc/main Forwarded: SiliconLabsSoftware/z-wave-protocol-controller#143 Signed-off-by: Philippe Coval <[email protected]>
1 parent f1b677b commit 049707c

File tree

7 files changed

+449
-0
lines changed

7 files changed

+449
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/******************************************************************************
2+
* # License
3+
* <b>Copyright 2022 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+
#include "multilevel_sensor_cluster_server.h"
14+
#include "zcl_cluster_servers_helpers.hpp"
15+
16+
// Interfaces
17+
#include "zwave_command_class_version_types.h"
18+
#include "zwave_command_class_configuration_types.h"
19+
20+
// ZPC includes
21+
#include "zpc_attribute_store.h"
22+
#include "zpc_attribute_store_network_helper.h"
23+
#include "zwave_command_class_generic_types.h"
24+
#include "attribute_store_defined_attribute_types.h"
25+
26+
// Includes from Unify shared components
27+
#include "attribute.hpp"
28+
#include "attribute_store_helper.h"
29+
#include "sl_log.h"
30+
31+
// Includes from auto-generated files
32+
#include "dotdot_mqtt.h"
33+
#include "zap-types.h"
34+
#include "dotdot_mqtt_helpers.hpp"
35+
36+
// Generic includes
37+
#include <string>
38+
#include <stdlib.h>
39+
#include <vector>
40+
41+
using namespace attribute_store;
42+
43+
// Setup Log ID
44+
constexpr char LOG_TAG[] = "multilevel_sensor_cluster_server";
45+
46+
// Attribute macro, shortening those long defines for attribute types:
47+
#define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_SENSOR_MULTILEVEL_##type
48+
49+
// List of attributes of SensorValues
50+
namespace
51+
{
52+
const std::vector<attribute_store_type_t> sensor_values_attributes
53+
= {ATTRIBUTE(SENSOR_VALUE), ATTRIBUTE(SCALE)};
54+
}
55+
56+
///////////////////////////////////////////////////////////////////////////////
57+
// Attribute publication functions
58+
//////////////////////////////////////////////////////////////////////////////
59+
60+
/**
61+
* @brief Publishes the Multilevel Sensor Cluster Server attributes
62+
*
63+
* @param unid unid for which we want to publish the
64+
* SensorValues attributes.
65+
* @param endpoint_id Endpoint ID for which we want to publish the
66+
* SensorValues attributes.
67+
* @param sensor_type Sensor Type node ID for which we want to publish the
68+
* SensorValues attributes.
69+
*/
70+
static sl_status_t publish_multilevel_sensor_cluster_attributes(
71+
const std::string &unid,
72+
attribute_store::attribute sensor_type_node,
73+
zwave_endpoint_id_t endpoint_id)
74+
{
75+
// Do not publish any state supported commands for ourselves.
76+
if (is_zpc_unid(unid.c_str())) {
77+
return SL_STATUS_FAIL;
78+
}
79+
80+
// Build the base topic and pass it on to DotDot MQTT.
81+
try {
82+
// Get reported sensor type ID
83+
uint8_t sensor_type = sensor_type_node.reported<uint8_t>();
84+
85+
// Get SensorType name
86+
const std::string sensor_type_str
87+
= multilevel_sensor_sensor_type_get_enum_value_name(sensor_type);
88+
89+
// Added sensor type name to base topic
90+
const std::string base_topic = "ucl/by-unid/" + std::string(unid) + "/ep"
91+
+ std::to_string(endpoint_id) + "/"
92+
+ std::string(sensor_type_str);
93+
94+
SensorValue value = {0, 0};
95+
// Get report sensor value
96+
attribute_store::attribute sensor_value_node
97+
= sensor_type_node.child_by_type(ATTRIBUTE(SENSOR_VALUE));
98+
if (sensor_value_node.reported_exists()) {
99+
value.Value = sensor_value_node.reported<int32_t>();
100+
}
101+
// Get report sensor scale
102+
attribute_store::attribute sensor_scale_node
103+
= sensor_type_node.child_by_type(ATTRIBUTE(SCALE));
104+
if (sensor_scale_node.reported_exists()) {
105+
value.Scale = static_cast<uint8_t>(sensor_scale_node.reported<int32_t>());
106+
}
107+
108+
// Pulish the sensor value attribute
109+
if (SL_STATUS_OK
110+
!= uic_mqtt_dotdot_multilevel_sensor_sensor_values_publish(
111+
base_topic.c_str(),
112+
value,
113+
UCL_MQTT_PUBLISH_TYPE_REPORTED)) {
114+
return SL_STATUS_FAIL;
115+
}
116+
} catch (const std::exception &e) {
117+
sl_log_error(LOG_TAG,
118+
"Error while get base topic and sensor data : %s",
119+
e.what());
120+
121+
return SL_STATUS_FAIL;
122+
}
123+
return SL_STATUS_OK;
124+
}
125+
126+
///////////////////////////////////////////////////////////////////////////////
127+
// Attribute store callback functions
128+
//////////////////////////////////////////////////////////////////////////////
129+
/**
130+
* @brief Listens to updates to the SensorValues then publishes the attributes.
131+
*
132+
* @param updated_node Attribute Store node that was modified.
133+
* @param change Type of change applied to the node.
134+
*/
135+
void on_sensor_values_update(attribute_store_node_t updated_node,
136+
attribute_store_change_t change)
137+
{
138+
if (change == ATTRIBUTE_CREATED || change == ATTRIBUTE_DELETED) {
139+
return;
140+
}
141+
142+
// Go up and find the UNID/Endpoint and its network status.
143+
unid_t unid;
144+
zwave_endpoint_id_t endpoint_id = 0;
145+
if (SL_STATUS_OK
146+
!= attribute_store_network_helper_get_unid_endpoint_from_node(
147+
updated_node,
148+
unid,
149+
&endpoint_id)) {
150+
return;
151+
}
152+
153+
attribute_store::attribute sensor_type_node
154+
= attribute_store_get_first_parent_with_type(updated_node,
155+
ATTRIBUTE(SENSOR_TYPE));
156+
157+
// Publish the multilevel sensor values:
158+
if (SL_STATUS_OK
159+
!= publish_multilevel_sensor_cluster_attributes(std::string(unid),
160+
sensor_type_node,
161+
endpoint_id)) {
162+
return;
163+
}
164+
}
165+
166+
///////////////////////////////////////////////////////////////////////////////
167+
// Init and teardown functions.
168+
//////////////////////////////////////////////////////////////////////////////
169+
sl_status_t multilevel_sensor_cluster_server_init(void)
170+
{
171+
sl_log_debug(LOG_TAG, "Multilevel sensor server initialization");
172+
173+
// Register attribute updates
174+
175+
attribute_store_register_callback_by_type_to_array(
176+
&on_sensor_values_update,
177+
sensor_values_attributes.data(),
178+
static_cast<uint32_t>(sensor_values_attributes.size()));
179+
180+
return SL_STATUS_OK;
181+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/******************************************************************************
2+
* # License
3+
* <b>Copyright 2022 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 multilevel_sensor_cluster_server ZCL Multilevel Sensor cluster
16+
* @ingroup zcl_cluster_servers
17+
* @brief The module handlers the Multilevel Sensor Cluster attribute and
18+
* publish directly the attribute via MQTT.
19+
*
20+
* @{
21+
*/
22+
23+
#ifndef MULTILEVEL_SENSOR_CLUSTER_SERVER_H
24+
#define MULTILEVEL_SENSOR_CLUSTER_SERVER_H
25+
26+
#include "sl_status.h"
27+
28+
#ifdef __cplusplus
29+
extern "C" {
30+
#endif
31+
32+
/**
33+
* @brief Initialize the Multilevel Sensor Cluster Commands handler.
34+
*
35+
* @returns SL_STATUS_OK on success, any other code on failure
36+
*/
37+
sl_status_t multilevel_sensor_cluster_server_init(void);
38+
39+
#ifdef __cplusplus
40+
}
41+
#endif
42+
43+
#endif //MULTILEVEL_SENSOR_CLUSTER_SERVER_H
44+
/** @} end configuration_cluster_mapper */
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
find_package(Boost REQUIRED)
2+
3+
# Find nlohmann_json, unfortunately the find_package doesn't work for this when
4+
# cross compiling, thus we use the simplified method find_path instead
5+
find_path(nlohmann_json_include nlohmann/json.hpp REQUIRED)
6+
7+
# ZCL Cluster server library
8+
add_library(
9+
zcl_cluster_servers
10+
src/configuration_parameter_cluster_server.cpp
11+
src/humidity_control_cluster_server.c
12+
src/user_code_cluster_server.cpp
13+
src/fan_control_cluster_server.c
14+
src/zcl_binding_cluster_server.cpp
15+
src/zcl_cluster_servers.cpp
16+
src/zcl_cluster_servers_helpers.cpp
17+
src/zcl_OTA_cluster_server.cpp
18+
src/zcl_rf_telemetry_cluster_server.c
19+
src/zcl_scenes_cluster_server.cpp
20+
src/multilevel_sensor_cluster_server.cpp
21+
)
22+
23+
target_include_directories(
24+
zcl_cluster_servers
25+
PUBLIC include
26+
PRIVATE src ${nlohmann_json_include} ${Boost_INCLUDE_DIRS})
27+
28+
target_link_libraries(
29+
zcl_cluster_servers
30+
PUBLIC zwave_handlers zwave_definitions
31+
PRIVATE unify
32+
zpc_attribute_store
33+
zpc_utils
34+
ucl_mqtt
35+
zwave_command_classes
36+
zwave_api_transport
37+
dotdot_mapper
38+
zwave_network_management)
39+
40+
if(BUILD_TESTING)
41+
# Unit tests
42+
add_subdirectory(test)
43+
44+
# Mocks
45+
target_add_mock(zcl_cluster_servers)
46+
endif()
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/******************************************************************************
2+
* # License
3+
* <b>Copyright 2021 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+
//Include from this component
14+
#include "zcl_cluster_servers.h"
15+
#include "zcl_rf_telemetry_cluster_server.h"
16+
#include "configuration_parameter_cluster_server.h"
17+
#include "zcl_binding_cluster_server.h"
18+
#include "zcl_scenes_cluster_server.h"
19+
#include "zcl_OTA_cluster_server.hpp"
20+
#include "user_code_cluster_server.h"
21+
#include "fan_control_cluster_server.h"
22+
#include "multilevel_sensor_cluster_server.h"
23+
24+
//Includes from other components
25+
#include "attribute_store.h"
26+
#include "attribute_store_helper.h"
27+
#include "zpc_attribute_store_network_helper.h"
28+
#include "attribute_store_defined_attribute_types.h"
29+
30+
// Interfaces
31+
#include "zwave_controller_types.h"
32+
33+
///////////////////////////////////////////////////////////////////////////////
34+
// Init and teardown functions.
35+
//////////////////////////////////////////////////////////////////////////////
36+
sl_status_t zcl_cluster_servers_init()
37+
{
38+
sl_status_t init_status = SL_STATUS_OK;
39+
init_status |= zcl_OTA_cluster_server_init();
40+
init_status |= zcl_rf_telemetry_cluster_server_init();
41+
init_status |= configuration_parameter_cluster_server_init();
42+
init_status |= binding_cluster_server_init();
43+
init_status |= zcl_scenes_cluster_server_init();
44+
init_status |= user_code_cluster_server_init();
45+
init_status |= fan_control_cluster_server_init();
46+
init_status |= multilevel_sensor_cluster_server_init();
47+
48+
return init_status;
49+
}
50+
51+
int zcl_cluster_servers_teardown()
52+
{
53+
zcl_scenes_cluster_server_teardown();
54+
return 0;
55+
}

0 commit comments

Comments
 (0)