diff --git a/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-type-attributes.ts b/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-type-attributes.ts
index 15eb5413cb..339469d26c 100644
--- a/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-type-attributes.ts
+++ b/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-type-attributes.ts
@@ -15863,5 +15863,5 @@ export let ClusterTypeAttrs: any = {
commands: [
]
}
- }
+ },
}
diff --git a/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-type-attributes.ts.rej b/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-type-attributes.ts.rej
new file mode 100644
index 0000000000..a1c746e1ef
--- /dev/null
+++ b/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-type-attributes.ts.rej
@@ -0,0 +1,12 @@
+diff a/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-type-attributes.ts b/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-type-attributes.ts (rejected hunks)
+@@ -1,8 +1,8 @@
+ //This file is generated automatically. Don't try to change something here.
+ //To add support for new clusters, modify addon-helper.js
+ //To change the stucture of the ClusterTypeAttrs, modify cluster-type-attributes.zapt
+-
+-
++
++
+ //generate ClusterTypes
+ export let ClusterTypeAttrs: any = {
+ Basic: {
diff --git a/applications/zpc/components/dotdot_mapper/rules/Humidity.uam b/applications/zpc/components/dotdot_mapper/rules/Humidity.uam
new file mode 100644
index 0000000000..d7e27a05b4
--- /dev/null
+++ b/applications/zpc/components/dotdot_mapper/rules/Humidity.uam
@@ -0,0 +1,130 @@
+// Humidity setpoint CC
+def zwHUMIDITY_CONTROL_SETPOINT_VERSION 0x6401
+def zwHUMIDITY_CONTROL_SUPPORTED_SETPOINT_SUPPORTED_TYPES 0x6402
+def zwHUMIDITY_CONTROL_SETPOINT_TYPE 0x6403
+def zwHUMIDITY_CONTROL_SETPOINT_VALUE 0x6405
+def zwHUMIDITY_CONTROL_SETPOINT_VALUE_SCALE 0x6406
+def zwHUMIDITY_CONTROL_SETPOINT_VALUE_PRECISION 0x6407
+def zwHUMIDITY_CONTROL_SETPOINT_MIN_VALUE 0x6408
+def zwHUMIDITY_CONTROL_SETPOINT_MIN_VALUE_SCALE 0x6409
+def zwHUMIDITY_CONTROL_SETPOINT_MIN_VALUE_PRECISION 0x640A
+def zwHUMIDITY_CONTROL_SETPOINT_MAX_VALUE 0x640B
+def zwHUMIDITY_CONTROL_SETPOINT_MAX_VALUE_SCALE 0x640C
+def zwHUMIDITY_CONTROL_SETPOINT_MAX_VALUE_PRECISION 0x640D
+
+// Humidity Mode CC
+def zwHUMIDITY_CONTROL_MODE_VERSION 0x6D01
+def zwHUMIDITY_CONTROL_SUPPORTED_MODES 0x6D02
+def zwHUMIDITY_CONTROL_MODE 0x6D03
+
+// Humidity Operating State CC
+def zwHUMIDITY_CONTROL_OPERATING_STATE_VERSION 0x6D01
+def zwHUMIDITY_CONTROL_OPERATING_STATE 0x6D02
+
+
+// Humidity Cluster
+def zb_ReportingMode 0xfda00001
+def zb_SupportedReportingMode 0xfda00002
+def zb_CurrentState 0xfda00003
+def zb_SupportedSetPoints 0xfda00004
+def zb_HumidifierSetpointMin 0xfda00005
+def zb_HumidifierSetpointMax 0xfda00006
+def zb_HumidifierSetpoint 0xfda00007
+def zb_HumidifierSetpointScale 0xfda00008
+def zb_HumidifierSetpointPrecision 0xfda00009
+def zb_DehumidifierSetpointMin 0xfda0000a
+def zb_DehumidifierSetpointMax 0xfda0000b
+def zb_DehumidifierSetpoint 0xfda0000c
+def zb_DehumidifierSetpointScale 0xfda0000d
+def zb_DehumidifierSetpointPrecision 0xfda0000e
+def zb_AutoSetpointMin 0xfda0000f
+def zb_AutoSetpointMax 0xfda00010
+def zb_AutoSetpoint 0xfda00011
+def zb_AutoSetpointScale 0xfda00012
+def zb_AutoSetpointPrecision 0xfda00013
+
+def humidity_control_setpoint_humidify_exists (e'zwHUMIDITY_CONTROL_SETPOINT_TYPE[1])
+def humidity_control_setpoint_dehumidify_exists (e'zwHUMIDITY_CONTROL_SETPOINT_TYPE[2])
+def humidity_control_setpoint_auto_exists (e'zwHUMIDITY_CONTROL_SETPOINT_TYPE[3])
+
+
+scope 0 chain_reaction(0) {
+ //// Setpoints
+
+ // Humidifier
+ r'zb_HumidifierSetpoint =
+ if (humidity_control_setpoint_humidify_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[1].zwHUMIDITY_CONTROL_SETPOINT_VALUE
+ undefined
+ r'zb_HumidifierSetpointMin =
+ if (humidity_control_setpoint_humidify_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[1].zwHUMIDITY_CONTROL_SETPOINT_MIN_VALUE
+ undefined
+ r'zb_HumidifierSetpointMax =
+ if (humidity_control_setpoint_humidify_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[1].zwHUMIDITY_CONTROL_SETPOINT_MAX_VALUE
+ undefined
+ r'zb_HumidifierSetpointScale =
+ if (humidity_control_setpoint_humidify_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[1].zwHUMIDITY_CONTROL_SETPOINT_VALUE_SCALE
+ undefined
+ r'zb_HumidifierSetpointPrecision =
+ if (humidity_control_setpoint_humidify_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[1].zwHUMIDITY_CONTROL_SETPOINT_VALUE_PRECISION
+ undefined
+
+ // Humidifier
+ r'zb_DehumidifierSetpoint =
+ if (humidity_control_setpoint_dehumidify_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[2].zwHUMIDITY_CONTROL_SETPOINT_VALUE
+ undefined
+ r'zb_DehumidifierSetpointMin =
+ if (humidity_control_setpoint_dehumidify_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[2].zwHUMIDITY_CONTROL_SETPOINT_MIN_VALUE
+ undefined
+ r'zb_DehumidifierSetpointMax =
+ if (humidity_control_setpoint_dehumidify_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[2].zwHUMIDITY_CONTROL_SETPOINT_MAX_VALUE
+ undefined
+ r'zb_DehumidifierSetpointScale =
+ if (humidity_control_setpoint_dehumidify_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[2].zwHUMIDITY_CONTROL_SETPOINT_VALUE_SCALE
+ undefined
+ r'zb_DehumidifierSetpointPrecision =
+ if (humidity_control_setpoint_dehumidify_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[2].zwHUMIDITY_CONTROL_SETPOINT_VALUE_PRECISION
+ undefined
+
+ // Humidifier
+ r'zb_AutoSetpoint =
+ if (humidity_control_setpoint_auto_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[2].zwHUMIDITY_CONTROL_SETPOINT_VALUE
+ undefined
+ r'zb_AutoSetpointMin =
+ if (humidity_control_setpoint_auto_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[2].zwHUMIDITY_CONTROL_SETPOINT_MIN_VALUE
+ undefined
+ r'zb_AutoSetpointMax =
+ if (humidity_control_setpoint_auto_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[2].zwHUMIDITY_CONTROL_SETPOINT_MAX_VALUE
+ undefined
+ r'zb_AutoSetpointScale =
+ if (humidity_control_setpoint_auto_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[2].zwHUMIDITY_CONTROL_SETPOINT_VALUE_SCALE
+ undefined
+ r'zb_AutoSetpointPrecision =
+ if (humidity_control_setpoint_auto_exists)
+ r'zwHUMIDITY_CONTROL_SETPOINT_TYPE[2].zwHUMIDITY_CONTROL_SETPOINT_VALUE_PRECISION
+ undefined
+
+ // Supported setpoints
+ r'zb_SupportedSetPoints = r'zwHUMIDITY_CONTROL_SUPPORTED_SETPOINT_SUPPORTED_TYPES
+
+ //// State
+ r'zb_CurrentState = r'zwHUMIDITY_CONTROL_OPERATING_STATE
+
+ //// Mode
+ r'zb_ReportingMode = r'zwHUMIDITY_CONTROL_MODE
+ r'zb_SupportedReportingMode = r'zwHUMIDITY_CONTROL_SUPPORTED_MODES
+}
+
diff --git a/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt b/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt
index 663f04f7fc..962fa7ded3 100644
--- a/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt
+++ b/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt
@@ -14,7 +14,9 @@ add_library(
src/zcl_cluster_servers_helpers.cpp
src/zcl_OTA_cluster_server.cpp
src/zcl_rf_telemetry_cluster_server.c
- src/zcl_scenes_cluster_server.cpp)
+ src/zcl_scenes_cluster_server.cpp
+ src/humidity_control_cluster_server.c
+ )
target_include_directories(
zcl_cluster_servers
diff --git a/applications/zpc/components/zcl_cluster_servers/src/humidity_control_cluster_server.c b/applications/zpc/components/zcl_cluster_servers/src/humidity_control_cluster_server.c
new file mode 100644
index 0000000000..cbd4c7f977
--- /dev/null
+++ b/applications/zpc/components/zcl_cluster_servers/src/humidity_control_cluster_server.c
@@ -0,0 +1,133 @@
+
+/******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+// Includes from this component
+#include "humidity_control_cluster_server.h"
+
+// Includes from Unify
+#include "sl_log.h"
+#include "sl_status.h"
+#include "attribute_store_helper.h"
+#include "zpc_attribute_store_network_helper.h"
+#include "zwave_command_class_humidity_control_types.h"
+
+#include "attribute_store_defined_attribute_types.h"
+#include "unify_dotdot_defined_attribute_types.h"
+#include "unify_dotdot_attribute_store.h"
+#include "unify_dotdot_attribute_store_node_state.h"
+
+// Includes from auto-generated files
+#include "dotdot_mqtt.h"
+
+// Setup Log ID
+#define LOG_TAG "unify_humidity_control_cluster_server"
+
+sl_status_t unify_humidity_control_mode_set(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ uic_mqtt_dotdot_callback_call_type_t call_type,
+ ModeType mode)
+{
+ attribute_store_node_t endpoint_node
+ = attribute_store_network_helper_get_endpoint_node(unid, endpoint);
+
+ attribute_store_node_t current_mode_node
+ = attribute_store_get_first_child_by_type(
+ endpoint_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE);
+
+ // First check the call type. If this is a support check support call,
+ // we check the attributes
+ if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) {
+ // Check user option automatic_deduction_of_supported_commands
+ return attribute_store_node_exists(current_mode_node) ? SL_STATUS_OK
+ : SL_STATUS_FAIL;
+ }
+
+ humidity_control_mode_t mode_value = mode;
+ return attribute_store_set_desired(current_mode_node,
+ &mode_value,
+ sizeof(mode_value));
+}
+
+sl_status_t unify_humidity_control_setpoint_set(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ uic_mqtt_dotdot_callback_call_type_t call_type,
+ SetpointType type,
+ uint8_t precision,
+ uint8_t scale,
+ int32_t value)
+{
+ // First check the call type. This command have too many requirements
+ // so we support it by default
+ if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) {
+ return SL_STATUS_OK;
+ }
+
+ attribute_store_node_t endpoint_node
+ = attribute_store_network_helper_get_endpoint_node(unid, endpoint);
+
+ humidity_control_setpoint_type_t setpoint_type = type;
+
+ attribute_store_node_t setpoint_type_node
+ = attribute_store_get_node_child_by_value(
+ endpoint_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_TYPE,
+ REPORTED_ATTRIBUTE,
+ &setpoint_type,
+ sizeof(setpoint_type),
+ 0);
+
+ if (setpoint_type == ATTRIBUTE_STORE_INVALID_NODE) {
+ sl_log_warning(LOG_TAG,
+ "Can't find humidity setpoint type %d",
+ setpoint_type);
+ return SL_STATUS_FAIL;
+ }
+
+ attribute_store_set_child_reported(
+ setpoint_type_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE_PRECISION,
+ &precision,
+ sizeof(precision));
+
+ attribute_store_set_child_reported(
+ setpoint_type_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE_SCALE,
+ &scale,
+ sizeof(scale));
+
+ return attribute_store_set_child_desired(
+ setpoint_type_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE,
+ &value,
+ sizeof(value));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Init and teardown functions
+///////////////////////////////////////////////////////////////////////////////
+sl_status_t humidity_control_cluster_server_init()
+{
+ sl_log_debug(LOG_TAG, "Humidity Control cluster (ZWave) server initialization");
+
+ // Listen to the BASIC Value attribute is created
+ uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_set(
+ &unify_humidity_control_mode_set);
+
+ uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_set(
+ &unify_humidity_control_setpoint_set);
+
+ return SL_STATUS_OK;
+}
diff --git a/applications/zpc/components/zcl_cluster_servers/src/humidity_control_cluster_server.h b/applications/zpc/components/zcl_cluster_servers/src/humidity_control_cluster_server.h
new file mode 100644
index 0000000000..43a408af2c
--- /dev/null
+++ b/applications/zpc/components/zcl_cluster_servers/src/humidity_control_cluster_server.h
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+
+#ifndef HUMIDITY_CONTROL_CLUSTER_SERVER_H
+#define HUMIDITY_CONTROL_CLUSTER_SERVER_H
+
+// Generic includes
+#include "sl_status.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialize the FanControl cluster server
+ *
+ * @returns true on success
+ * @returns false on failure
+ *
+ */
+sl_status_t humidity_control_cluster_server_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //HUMIDITY_CONTROL_CLUSTER_SERVER_H
+/** @} end humidity_control_cluster_server */
diff --git a/applications/zpc/components/zcl_cluster_servers/test/CMakeLists.txt b/applications/zpc/components/zcl_cluster_servers/test/CMakeLists.txt
index ff9d893c81..c8a60bf1f2 100644
--- a/applications/zpc/components/zcl_cluster_servers/test/CMakeLists.txt
+++ b/applications/zpc/components/zcl_cluster_servers/test/CMakeLists.txt
@@ -102,4 +102,16 @@ target_add_unittest(
zcl_cluster_servers_fixture_test.c
DEPENDS
unify
- zpc_config_mock)
\ No newline at end of file
+ zpc_config_mock)
+
+ # Humidity Control Cluster Mapper test
+target_add_unittest(
+ zcl_cluster_servers
+ NAME
+ humidity_control_cluster_server_test
+ SOURCES
+ humidity_control_cluster_server_test.c
+ DEPENDS
+ zpc_attribute_store_test_helper
+ uic_dotdot_mqtt_mock
+ unify_dotdot_attribute_store)
\ No newline at end of file
diff --git a/applications/zpc/components/zcl_cluster_servers/test/humidity_control_cluster_server_test.c b/applications/zpc/components/zcl_cluster_servers/test/humidity_control_cluster_server_test.c
new file mode 100644
index 0000000000..bb8d6a59cf
--- /dev/null
+++ b/applications/zpc/components/zcl_cluster_servers/test/humidity_control_cluster_server_test.c
@@ -0,0 +1,224 @@
+/******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+#include "humidity_control_cluster_server.h"
+#include "unify_dotdot_attribute_store.h"
+#include "unity.h"
+
+// Unify components
+#include "datastore.h"
+#include "attribute_store_fixt.h"
+#include "attribute_store_helper.h"
+#include "unify_dotdot_defined_attribute_types.h"
+#include "dotdot_mqtt_mock.h"
+
+// ZPC Components
+#include "zwave_unid.h"
+#include "zwave_command_class_humidity_control_types.h"
+
+// Test helpers
+#include "zpc_attribute_store_test_helper.h"
+#include "attribute_store_defined_attribute_types.h"
+
+uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_t
+ uic_mqtt_dotdot_unify_humidity_control_mode_set_callback;
+
+uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_t
+ uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback;
+
+void uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_set_stub(
+ const uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_t callback,
+ int cmock_num_calls)
+{
+ uic_mqtt_dotdot_unify_humidity_control_mode_set_callback = callback;
+}
+
+void uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_set_stub(
+ const uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_t callback,
+ int cmock_num_calls)
+{
+ uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback = callback;
+}
+/// Setup the test suite (called once before all test_xxx functions are called)
+void suiteSetUp()
+{
+ datastore_init(":memory:");
+ attribute_store_init();
+}
+
+/// Teardown the test suite (called once after all test_xxx functions are called)
+int suiteTearDown(int num_failures)
+{
+ attribute_store_teardown();
+ datastore_teardown();
+ return num_failures;
+}
+
+/// Called before each and every test
+void setUp()
+{
+ zpc_attribute_store_test_helper_create_network();
+ uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_set_Stub(
+ &uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_set_stub);
+ uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_set_Stub(
+ &uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_set_stub);
+
+ // Call init
+ TEST_ASSERT_EQUAL(SL_STATUS_OK, humidity_control_cluster_server_init());
+}
+
+/// Called after each and every test
+void tearDown()
+{
+ attribute_store_delete_node(attribute_store_get_root());
+}
+
+void test_humidity_control_set_mode_command_mapping()
+{
+ TEST_ASSERT_NOT_NULL(
+ uic_mqtt_dotdot_unify_humidity_control_mode_set_callback);
+
+ ModeType expected_current_mode = ZCL_MODE_TYPE_DEHUMIDIFY;
+
+ TEST_ASSERT_EQUAL(SL_STATUS_FAIL,
+ uic_mqtt_dotdot_unify_humidity_control_mode_set_callback(
+ supporting_node_unid,
+ endpoint_id,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK,
+ expected_current_mode));
+
+ attribute_store_node_t current_mode_node = attribute_store_add_node(
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE,
+ endpoint_id_node);
+
+ // test support
+ TEST_ASSERT_EQUAL(SL_STATUS_OK,
+ uic_mqtt_dotdot_unify_humidity_control_mode_set_callback(
+ supporting_node_unid,
+ endpoint_id,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK,
+ expected_current_mode));
+ // Test callback
+ TEST_ASSERT_EQUAL(SL_STATUS_OK,
+ uic_mqtt_dotdot_unify_humidity_control_mode_set_callback(
+ supporting_node_unid,
+ endpoint_id,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL,
+ expected_current_mode));
+
+ humidity_control_mode_t current_mode = 0;
+
+ TEST_ASSERT_EQUAL_MESSAGE(SL_STATUS_OK,
+ attribute_store_get_desired(current_mode_node,
+ ¤t_mode,
+ sizeof(current_mode)),
+ "Can't get current mode value");
+
+ // Test value
+ TEST_ASSERT_EQUAL(expected_current_mode, current_mode);
+}
+
+void test_humidity_control_setpoint_set_command_mapping()
+{
+ TEST_ASSERT_NOT_NULL(
+ uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback);
+
+ SetpointType expected_setpoint_type_ucl = ZCL_SETPOINT_TYPE_DEHUMIDIFIER;
+ uint8_t expected_precision_ucl = 2;
+ uint8_t expected_scale_ucl = 1;
+ int32_t expected_value_ucl = 10;
+
+ // Always supported
+ TEST_ASSERT_EQUAL(
+ SL_STATUS_OK,
+ uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback(
+ supporting_node_unid,
+ endpoint_id,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK,
+ expected_setpoint_type_ucl,
+ expected_precision_ucl,
+ expected_scale_ucl,
+ expected_value_ucl));
+
+ humidity_control_setpoint_type_t expected_type
+ = expected_setpoint_type_ucl + 1;
+ // Emplace with wrong setpoint type
+ attribute_store_emplace(
+ endpoint_id_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_TYPE,
+ &expected_type,
+ sizeof(expected_type));
+
+ // Should fail
+ TEST_ASSERT_EQUAL(
+ SL_STATUS_FAIL,
+ uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback(
+ supporting_node_unid,
+ endpoint_id,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL,
+ expected_setpoint_type_ucl,
+ expected_precision_ucl,
+ expected_scale_ucl,
+ expected_value_ucl));
+
+ expected_type = expected_setpoint_type_ucl;
+ // Emplace with wrong setpoint type
+ attribute_store_node_t current_mode_node = attribute_store_emplace(
+ endpoint_id_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_TYPE,
+ &expected_type,
+ sizeof(expected_type));
+
+ TEST_ASSERT_EQUAL(
+ SL_STATUS_OK,
+ uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback(
+ supporting_node_unid,
+ endpoint_id,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL,
+ expected_setpoint_type_ucl,
+ expected_precision_ucl,
+ expected_scale_ucl,
+ expected_value_ucl));
+
+ humidity_control_setpoint_scale_t reported_scale;
+ humidity_control_setpoint_value_t reported_value;
+ humidity_control_setpoint_precision_t reported_precision;
+
+ attribute_store_get_child_reported(
+ current_mode_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE_PRECISION,
+ &reported_precision,
+ sizeof(reported_precision));
+ TEST_ASSERT_EQUAL_MESSAGE(expected_precision_ucl,
+ reported_precision,
+ "Precision reported value mismatch");
+ attribute_store_get_child_reported(
+ current_mode_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE_SCALE,
+ &reported_scale,
+ sizeof(reported_scale));
+ TEST_ASSERT_EQUAL_MESSAGE(expected_scale_ucl,
+ reported_scale,
+ "Scale reported value mismatch");
+
+ // Value is desired since it will be sent to end-device
+ attribute_store_node_t value_node = attribute_store_get_first_child_by_type(
+ current_mode_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE);
+
+ attribute_store_get_desired(value_node,
+ &reported_value,
+ sizeof(reported_value));
+ TEST_ASSERT_EQUAL_MESSAGE(expected_value_ucl,
+ reported_value,
+ "Value desired value mismatch");
+}
\ No newline at end of file
diff --git a/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h b/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h
index 78ca2909e5..b140159e97 100644
--- a/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h
+++ b/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h
@@ -529,6 +529,67 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_CRC16_VERSION,
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_DEVICE_RESET_LOCALLY_VERSION,
((COMMAND_CLASS_DEVICE_RESET_LOCALLY << 8) | 0x01))
+/////////////////////////////////////////////////
+// Humidity Control Mode Command Class
+///< This represents the version of the Humidity Control Mode Command class.
+/// zwave_cc_version_t
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_VERSION,
+ ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_HUMIDITY_CONTROL_MODE))
+
+// Supported mode
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_MODE << 8) | 0x02))
+
+// Current mode
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_MODE << 8) | 0x03))
+
+/////////////////////////////////////////////////
+// Humidity Control Operating State Command Class
+///< This represents the version of the Humidity Control Mode Command class.
+/// zwave_cc_version_t
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_VERSION,
+ ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE))
+
+// Current state
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_CURRENT_STATE,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE << 8) | 0x02))
+
+/////////////////////////////////////////////////
+// Humidity Control Setpoint Command Class
+///< This represents the version of the Humidity Control Mode Command class.
+/// zwave_cc_version_t
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VERSION,
+ ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT))
+
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_SUPPORTED_TYPES,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x02))
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_TYPE,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x03))
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_SUPPORTED_SCALE,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x04))
+
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x05))
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE_SCALE,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x06))
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE_PRECISION,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x07))
+
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x08))
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE_SCALE,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x09))
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE_PRECISION,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x0A))
+
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x0B))
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE_SCALE,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x0C))
+DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE_PRECISION,
+ ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x0D))
+
/////////////////////////////////////////////////
// Inclusion Controller Command Class
///< This represents the version of the Inclusion Controller Command class.
diff --git a/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_humidity_control_types.h b/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_humidity_control_types.h
new file mode 100644
index 0000000000..15a8bc6a09
--- /dev/null
+++ b/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_humidity_control_types.h
@@ -0,0 +1,69 @@
+/******************************************************************************
+ * # License
+ * Copyright 2023 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+
+/**
+ * @defgroup zpc_attribute_store_command_classes_types Type definitions for attribute storage of Command Classes
+ * @ingroup zpc_attribute_store
+ * @brief Type definitions for Command Classes, used for @ref attribute_store storage.
+ *
+ */
+
+/**
+ * @defgroup zwave_command_class_humidity_control_mode_types Type definitions for attribute storage of the Humidity Control Command Class
+ * @ingroup zpc_attribute_store_command_classes_types
+ * @brief Type definitions for the Humidity Control Command Class (Mode, State and Setpoint).
+ *
+ * @{
+ */
+
+#ifndef ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_TYPES_H
+#define ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_TYPES_H
+
+#include
+
+//>> Humidity Control Mode CC
+///> Humidity Control Mode. uint8_t
+typedef uint8_t humidity_control_mode_t;
+///> Humidity Control Suppoted Mode Bitmask. uint8_t
+typedef uint8_t humidity_control_supported_modes_t;
+
+//>> Humidity Control Operating State CC
+///> Humidity Control Operating State. uint8_t
+typedef uint8_t humidity_control_operating_state_t;
+
+//>> Humidity Control Setpoint CC
+///> Humidity Control Setpoint Supported Types Bitmask. uint8_t
+typedef uint8_t humidity_control_setpoint_supported_types_t;
+///> Humidity Control Setpoint Supported Scale Bitmask. uint8_t
+typedef uint8_t humidity_control_setpoint_supported_scales_t;
+///> Humidity Control Setpoint Type. uint8_t
+typedef uint8_t humidity_control_setpoint_type_t;
+///> Humidity Control Setpoint Value. int32_t
+typedef int32_t humidity_control_setpoint_value_t;
+///> Humidity Control Setpoint Scale. uint8_t
+typedef uint8_t humidity_control_setpoint_scale_t;
+///> Humidity Control Setpoint Precision. uint8_t
+typedef uint8_t humidity_control_setpoint_precision_t;
+///> Humidity Control Setpoint Size. uint8_t
+typedef uint8_t humidity_control_setpoint_size_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_TYPES_H
+/** @} end zwave_command_class_humidity_control_mode_types */
diff --git a/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp b/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp
index 774ba2882d..57a97d77c7 100644
--- a/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp
+++ b/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp
@@ -193,6 +193,42 @@ static const std::vector attribute_schema = {
{ATTRIBUTE_INDICATOR_INDICATOR_VALUE, "Value", ATTRIBUTE_INDICATOR_PROPERTY_ID, U32_STORAGE_TYPE},
{ATTRIBUTE_INDICATOR_SUPPORTED_PROPERTY_SUPPORTED_BIT_MASK, "Supported Properties bitmask", ATTRIBUTE_INDICATOR_INDICATOR_ID, BYTE_ARRAY_STORAGE_TYPE},
{ATTRIBUTE_COMMAND_CLASS_INDICATOR_TIMEOUT, "Indicator timeout", ATTRIBUTE_INDICATOR_INDICATOR_ID, U32_STORAGE_TYPE},
+
+ /////////////////////////////////////////////////////////////////////
+ // Humidity Control Mode Command Class attributes
+ /////////////////////////////////////////////////////////////////////
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_VERSION, "Humidity Control Mode Version", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES, "Humidity Control Mode Supported Modes", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE, "Humidity Control Mode Current Mode", ATTRIBUTE_INDICATOR_INDICATOR_ID, U8_STORAGE_TYPE},
+
+ /////////////////////////////////////////////////////////////////////
+ // Humidity Control Operating State Command Class attributes
+ /////////////////////////////////////////////////////////////////////
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_VERSION, "Humidity Control Operating State Version", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_CURRENT_STATE, "Humidity Control Operating State Current State", ATTRIBUTE_INDICATOR_INDICATOR_ID, U8_STORAGE_TYPE},
+
+ /////////////////////////////////////////////////////////////////////
+ // Humidity Control Setpoint Command Class attributes
+ /////////////////////////////////////////////////////////////////////
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VERSION, "Humidity Control Setpoint Version", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_SUPPORTED_TYPES, "Humidity Control Supported Setpoint Types", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_TYPE, "Humidity Control Setpoint Type", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
+
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_SUPPORTED_SCALE, "Humidity Control Supported Scales", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
+
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE, "Value", ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_TYPE, I32_STORAGE_TYPE},
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE_SCALE, "Value Scale", ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE, U8_STORAGE_TYPE},
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE_PRECISION, "Value Precision", ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE, U8_STORAGE_TYPE},
+
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE, "Min Value", ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_TYPE, I32_STORAGE_TYPE},
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE_SCALE, "Min Value Scale", ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE, U8_STORAGE_TYPE},
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE_PRECISION, "Min Value Precision", ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE, U8_STORAGE_TYPE},
+
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE, "Max Value", ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_TYPE, I32_STORAGE_TYPE},
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE_SCALE, "Max Value Scale", ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE, U8_STORAGE_TYPE},
+ {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE_PRECISION, "Max Value Precision", ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE, U8_STORAGE_TYPE},
+
+
/////////////////////////////////////////////////////////////////////
// Meter Command Class attributes
/////////////////////////////////////////////////////////////////////
diff --git a/applications/zpc/components/zwave_command_classes/CMakeLists.txt b/applications/zpc/components/zwave_command_classes/CMakeLists.txt
index 90bec52fee..c417dfbaa4 100644
--- a/applications/zpc/components/zwave_command_classes/CMakeLists.txt
+++ b/applications/zpc/components/zwave_command_classes/CMakeLists.txt
@@ -21,6 +21,9 @@ add_library(
src/zwave_command_class_device_reset_locally.cpp
src/zwave_command_class_door_lock_control.cpp
src/zwave_command_class_firmware_update.c
+ src/zwave_command_class_humidity_control_mode.c
+ src/zwave_command_class_humidity_control_operating_state.c
+ src/zwave_command_class_humidity_control_setpoint.c
src/zwave_command_class_indicator.c
src/zwave_command_class_indicator_control.cpp
src/zwave_command_class_manufacturer_specific.c
diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_mode.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_mode.c
new file mode 100644
index 0000000000..37f50b9e8c
--- /dev/null
+++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_mode.c
@@ -0,0 +1,356 @@
+/******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+
+// System
+#include
+
+#include "zwave_command_class_humidity_control_mode.h"
+#include "zwave_command_class_humidity_control_types.h"
+#include "zwave_command_classes_utils.h"
+#include "ZW_classcmd.h"
+
+// Includes from other ZPC Components
+#include "zwave_command_class_indices.h"
+#include "zwave_command_handler.h"
+#include "zwave_command_class_version_types.h"
+#include "zpc_attribute_store_network_helper.h"
+#include "attribute_store_defined_attribute_types.h"
+
+// Unify
+#include "attribute_resolver.h"
+#include "attribute_store.h"
+#include "attribute_store_helper.h"
+#include "sl_log.h"
+
+#define LOG_TAG "zwave_command_class_humidity_control_mode"
+
+/////////////////////////////////////////////////////////////////////////////
+// Utils
+/////////////////////////////////////////////////////////////////////////////
+/**
+ * @brief Get current humidity control mode version of the CC
+ *
+ * @param node Endpoint node
+ *
+ * @returns zwave_cc_version_t 0 if anything goes wrong, version number otherwise
+ */
+static zwave_cc_version_t
+ get_humidity_control_mode_version(attribute_store_node_t endpoint_node)
+{
+ attribute_store_node_t version_node = attribute_store_get_first_child_by_type(
+ endpoint_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_VERSION);
+ // We need to check the version of the supporting node:
+ zwave_cc_version_t supporting_node_version = 0;
+ attribute_store_get_reported(version_node,
+ &supporting_node_version,
+ sizeof(supporting_node_version));
+
+ return supporting_node_version;
+}
+
+// Return true if supported_humidity_control_mode_type is compatible with current_version
+// False otherwise
+static bool is_humidity_control_mode_compatible_with_version(
+ humidity_control_mode_t supported_humidity_control_mode_type,
+ zwave_cc_version_t current_version)
+{
+ bool compatibility = false;
+
+ switch (current_version) {
+ case 1:
+ compatibility = (supported_humidity_control_mode_type <= 0x02);
+ break;
+ case 2:
+ compatibility = (supported_humidity_control_mode_type <= 0x03);
+ break;
+ default:
+ compatibility = false;
+ }
+
+ if (!compatibility) {
+ sl_log_warning(LOG_TAG,
+ "Humidity Control Mode %#04x is not compatible with "
+ "Humidity Control Mode Version %d",
+ supported_humidity_control_mode_type,
+ current_version);
+ }
+
+ return compatibility;
+}
+
+static bool is_humidity_control_mode_supported(
+ humidity_control_mode_t humidity_control_mode_type,
+ attribute_store_node_t endpoint_id_node)
+{
+ // First check version
+ zwave_cc_version_t current_version
+ = get_humidity_control_mode_version(endpoint_id_node);
+
+ // Check version compatibility
+ if (!is_humidity_control_mode_compatible_with_version(
+ humidity_control_mode_type,
+ current_version)) {
+ return false;
+ }
+
+ attribute_store_node_t supported_type_node
+ = attribute_store_get_first_child_by_type(
+ endpoint_id_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES);
+
+ if (supported_type_node == ATTRIBUTE_STORE_INVALID_NODE) {
+ sl_log_warning(
+ LOG_TAG,
+ "Can't get ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES "
+ "from attribute store.");
+ return false;
+ }
+
+ humidity_control_supported_modes_t supported_types;
+ sl_status_t status = attribute_store_get_reported(supported_type_node,
+ &supported_types,
+ sizeof(supported_types));
+
+ if (status != ATTRIBUTE_STORE_INVALID_NODE) {
+ sl_log_warning(
+ LOG_TAG,
+ "Can't get reported value of "
+ "ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES.");
+ return false;
+ }
+
+ switch (humidity_control_mode_type) {
+ case HUMIDITY_CONTROL_MODE_SET_MODE_HUMIDIFY:
+ return supported_types & 0x01;
+ case HUMIDITY_CONTROL_MODE_SET_MODE_DEHUMIDIFY:
+ return supported_types & 0x02;
+ case HUMIDITY_CONTROL_MODE_SET_MODE_AUTO_V2:
+ return supported_types & 0x04;
+ default:
+ return false;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Version & Attribute Creation
+/////////////////////////////////////////////////////////////////////////////
+static void
+ zwave_command_class_humidity_control_mode_on_version_attribute_update(
+ attribute_store_node_t updated_node, attribute_store_change_t change)
+{
+ if (change == ATTRIBUTE_DELETED) {
+ return;
+ }
+
+ if (is_zwave_command_class_filtered_for_root_device(
+ COMMAND_CLASS_HUMIDITY_CONTROL_MODE,
+ updated_node)
+ == true) {
+ return;
+ }
+
+ zwave_cc_version_t version = 0;
+ attribute_store_get_reported(updated_node, &version, sizeof(version));
+
+ if (version == 0) {
+ return;
+ }
+
+ attribute_store_node_t endpoint_node
+ = attribute_store_get_first_parent_with_type(updated_node,
+ ATTRIBUTE_ENDPOINT_ID);
+
+ // The order of the attribute matter since it defines the order of the
+ // Z-Wave get command order.
+ const attribute_store_type_t attributes[]
+ = {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE};
+
+ attribute_store_add_if_missing(endpoint_node,
+ attributes,
+ COUNT_OF(attributes));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Humidity Conntrol Mode Get/Set/Report
+/////////////////////////////////////////////////////////////////////////////
+
+static sl_status_t zwave_command_class_humidity_control_mode_get(
+ attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
+{
+ (void)node; // unused.
+ ZW_HUMIDITY_CONTROL_MODE_GET_FRAME *get_frame
+ = (ZW_HUMIDITY_CONTROL_MODE_GET_FRAME *)frame;
+ get_frame->cmdClass = COMMAND_CLASS_HUMIDITY_CONTROL_MODE;
+ get_frame->cmd = HUMIDITY_CONTROL_MODE_GET;
+ *frame_length = sizeof(ZW_HUMIDITY_CONTROL_MODE_GET_FRAME);
+ return SL_STATUS_OK;
+}
+
+static sl_status_t zwave_command_class_humidity_control_mode_set(
+ attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
+{
+ attribute_store_node_t endpoint_node
+ = attribute_store_get_first_parent_with_type(node, ATTRIBUTE_ENDPOINT_ID);
+
+ humidity_control_mode_t humidity_control_mode = 0;
+ sl_status_t result
+ = attribute_store_get_desired_else_reported(node,
+ &humidity_control_mode,
+ sizeof(humidity_control_mode));
+
+ if (result != SL_STATUS_OK) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ if (!is_humidity_control_mode_supported(humidity_control_mode,
+ endpoint_node)) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ ZW_HUMIDITY_CONTROL_MODE_SET_FRAME *set_frame
+ = (ZW_HUMIDITY_CONTROL_MODE_SET_FRAME *)frame;
+ set_frame->cmdClass = COMMAND_CLASS_HUMIDITY_CONTROL_MODE;
+ set_frame->cmd = HUMIDITY_CONTROL_MODE_SET;
+ set_frame->properties1 = humidity_control_mode;
+ *frame_length = sizeof(ZW_HUMIDITY_CONTROL_MODE_SET_FRAME);
+
+ return SL_STATUS_OK;
+}
+
+sl_status_t zwave_command_class_humidity_control_mode_handle_report(
+ const zwave_controller_connection_info_t *connection_info,
+ const uint8_t *frame_data,
+ uint16_t frame_length)
+{
+ if (frame_length < 3) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ humidity_control_mode_t humidity_control_mode
+ = frame_data[2] & HUMIDITY_CONTROL_MODE_REPORT_PROPERTIES1_MODE_MASK;
+
+ attribute_store_node_t endpoint_node
+ = zwave_command_class_get_endpoint_node(connection_info);
+
+
+ if (!is_humidity_control_mode_supported(humidity_control_mode, endpoint_node)) {
+ sl_log_warning(LOG_TAG, "Reported humidity control mode mismatch.");
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ attribute_store_set_child_reported(
+ endpoint_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE,
+ &humidity_control_mode,
+ sizeof(humidity_control_mode));
+
+ return SL_STATUS_OK;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Humidity Control Mode Supported Get/Report
+/////////////////////////////////////////////////////////////////////////////
+
+static sl_status_t zwave_command_class_humidity_control_mode_supported_get(
+ attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
+{
+ (void)node; // unused.
+ ZW_HUMIDITY_CONTROL_MODE_SUPPORTED_GET_FRAME *get_frame
+ = (ZW_HUMIDITY_CONTROL_MODE_SUPPORTED_GET_FRAME *)frame;
+ get_frame->cmdClass = COMMAND_CLASS_HUMIDITY_CONTROL_MODE;
+ get_frame->cmd = HUMIDITY_CONTROL_MODE_SUPPORTED_GET;
+ *frame_length = sizeof(ZW_HUMIDITY_CONTROL_MODE_SUPPORTED_GET_FRAME);
+ return SL_STATUS_OK;
+}
+
+sl_status_t zwave_command_class_humidity_control_mode_supported_handle_report(
+ const zwave_controller_connection_info_t *connection_info,
+ const uint8_t *frame_data,
+ uint16_t frame_length)
+{
+ if (frame_length < 3) {
+ return SL_STATUS_FAIL;
+ }
+
+ uint8_t supported_modes = frame_data[2];
+
+ attribute_store_node_t endpoint_node
+ = zwave_command_class_get_endpoint_node(connection_info);
+
+ attribute_store_set_child_reported(
+ endpoint_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES,
+ &supported_modes,
+ sizeof(supported_modes));
+
+ return SL_STATUS_OK;
+}
+
+sl_status_t zwave_command_class_humidity_control_mode_control_handler(
+ const zwave_controller_connection_info_t *connection_info,
+ const uint8_t *frame_data,
+ uint16_t frame_length)
+{
+ if (frame_length <= COMMAND_INDEX) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ switch (frame_data[COMMAND_INDEX]) {
+ case HUMIDITY_CONTROL_MODE_REPORT:
+ return zwave_command_class_humidity_control_mode_handle_report(
+ connection_info,
+ frame_data,
+ frame_length);
+ case HUMIDITY_CONTROL_MODE_SUPPORTED_REPORT:
+ return zwave_command_class_humidity_control_mode_supported_handle_report(
+ connection_info,
+ frame_data,
+ frame_length);
+ default:
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ return SL_STATUS_FAIL;
+}
+
+sl_status_t zwave_command_class_humidity_control_mode_init()
+{
+ attribute_store_register_callback_by_type(
+ &zwave_command_class_humidity_control_mode_on_version_attribute_update,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_VERSION);
+
+ attribute_resolver_register_rule(
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE,
+ &zwave_command_class_humidity_control_mode_set,
+ &zwave_command_class_humidity_control_mode_get);
+
+ attribute_resolver_register_rule(
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES,
+ NULL,
+ &zwave_command_class_humidity_control_mode_supported_get);
+
+ zwave_command_handler_t handler = {};
+ handler.support_handler = NULL;
+ handler.control_handler
+ = zwave_command_class_humidity_control_mode_control_handler;
+ handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NONE;
+ handler.manual_security_validation = false;
+ handler.command_class = COMMAND_CLASS_HUMIDITY_CONTROL_MODE;
+ handler.version = 2;
+ handler.command_class_name = "Humidity Control Mode";
+ handler.comments = "Experimental";
+
+ return zwave_command_handler_register_handler(handler);
+}
\ No newline at end of file
diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_mode.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_mode.h
new file mode 100644
index 0000000000..53e07fa588
--- /dev/null
+++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_mode.h
@@ -0,0 +1,41 @@
+
+/******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+
+/**
+ * @defgroup zwave_command_class_humidity_control_mode
+ * @brief Humidity Control Mode Command Class handlers and control function
+ *
+ * This module implement some of the functions to control the
+ * Humidity Control Mode Command Class
+ *
+ * @{
+ */
+
+#ifndef ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_H
+#define ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_H
+
+#include "sl_status.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+sl_status_t zwave_command_class_humidity_control_mode_init();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_H
+ /** @} end zwave_command_class_humidity_control_mode */
\ No newline at end of file
diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_operating_state.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_operating_state.c
new file mode 100644
index 0000000000..8ede12930b
--- /dev/null
+++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_operating_state.c
@@ -0,0 +1,155 @@
+
+/******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+
+// System
+#include
+
+#include "zwave_command_class_humidity_control_operating_state.h"
+#include "zwave_command_class_humidity_control_types.h"
+#include "zwave_command_classes_utils.h"
+#include "ZW_classcmd.h"
+
+// Includes from other ZPC Components
+#include "zwave_command_class_indices.h"
+#include "zwave_command_handler.h"
+#include "zwave_command_class_version_types.h"
+#include "zpc_attribute_store_network_helper.h"
+#include "attribute_store_defined_attribute_types.h"
+
+// Unify
+#include "attribute_resolver.h"
+#include "attribute_store.h"
+#include "attribute_store_helper.h"
+#include "sl_log.h"
+
+#define LOG_TAG "zwave_command_class_humidity_control_operating_state"
+
+/////////////////////////////////////////////////////////////////////////////
+// Version & Attribute Creation
+/////////////////////////////////////////////////////////////////////////////
+static void
+ zwave_command_class_humidity_control_operating_state_on_version_attribute_update(
+ attribute_store_node_t updated_node, attribute_store_change_t change)
+{
+ if (change == ATTRIBUTE_DELETED) {
+ return;
+ }
+
+ zwave_cc_version_t version = 0;
+ attribute_store_get_reported(updated_node, &version, sizeof(version));
+
+ if (version == 0) {
+ return;
+ }
+
+ attribute_store_node_t endpoint_node
+ = attribute_store_get_first_parent_with_type(updated_node,
+ ATTRIBUTE_ENDPOINT_ID);
+
+ // The order of the attribute matter since it defines the order of the
+ // Z-Wave get command order.
+ const attribute_store_type_t attributes[]
+ = {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_CURRENT_STATE};
+
+ attribute_store_add_if_missing(endpoint_node,
+ attributes,
+ COUNT_OF(attributes));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Humidity Control Operating State State Get/Report
+/////////////////////////////////////////////////////////////////////////////
+
+static sl_status_t zwave_command_class_humidity_control_operating_state_get(
+ attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
+{
+ (void)node; // unused.
+ ZW_HUMIDITY_CONTROL_OPERATING_STATE_GET_FRAME *get_frame
+ = (ZW_HUMIDITY_CONTROL_OPERATING_STATE_GET_FRAME *)frame;
+ get_frame->cmdClass = COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE;
+ get_frame->cmd = HUMIDITY_CONTROL_OPERATING_STATE_GET;
+ *frame_length = sizeof(ZW_HUMIDITY_CONTROL_OPERATING_STATE_GET_FRAME);
+ return SL_STATUS_OK;
+}
+
+sl_status_t zwave_command_class_humidity_control_operating_state_handle_report(
+ const zwave_controller_connection_info_t *connection_info,
+ const uint8_t *frame_data,
+ uint16_t frame_length)
+{
+ if (frame_length < 3) {
+ return SL_STATUS_FAIL;
+ }
+
+ humidity_control_operating_state_t fan_state
+ = frame_data[2]
+ & HUMIDITY_CONTROL_OPERATING_STATE_REPORT_PROPERTIES1_OPERATING_STATE_MASK;
+
+ attribute_store_node_t endpoint_node
+ = zwave_command_class_get_endpoint_node(connection_info);
+
+ attribute_store_set_child_reported(
+ endpoint_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_CURRENT_STATE,
+ &fan_state,
+ sizeof(fan_state));
+
+ return SL_STATUS_OK;
+}
+
+sl_status_t
+ zwave_command_class_humidity_control_operating_state_control_handler(
+ const zwave_controller_connection_info_t *connection_info,
+ const uint8_t *frame_data,
+ uint16_t frame_length)
+{
+ if (frame_length <= COMMAND_INDEX) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ switch (frame_data[COMMAND_INDEX]) {
+ case HUMIDITY_CONTROL_OPERATING_STATE_REPORT:
+ return zwave_command_class_humidity_control_operating_state_handle_report(
+ connection_info,
+ frame_data,
+ frame_length);
+ default:
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+}
+
+sl_status_t zwave_command_class_humidity_control_operating_state_init()
+{
+ attribute_store_register_callback_by_type(
+ &zwave_command_class_humidity_control_operating_state_on_version_attribute_update,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_VERSION);
+
+ attribute_resolver_register_rule(
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_CURRENT_STATE,
+ NULL,
+ &zwave_command_class_humidity_control_operating_state_get);
+
+ zwave_command_handler_t handler = {};
+ handler.support_handler = NULL;
+ handler.control_handler
+ = zwave_command_class_humidity_control_operating_state_control_handler;
+ handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NONE;
+ handler.manual_security_validation = false;
+ handler.command_class = COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE;
+ handler.version = 1;
+ handler.command_class_name = "Humidity Control Operating State";
+ handler.comments = "Experimental";
+
+ return zwave_command_handler_register_handler(handler);
+}
\ No newline at end of file
diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_operating_state.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_operating_state.h
new file mode 100644
index 0000000000..505b594612
--- /dev/null
+++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_operating_state.h
@@ -0,0 +1,41 @@
+
+/******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+
+/**
+ * @defgroup zwave_command_class_humidity_control_operating_state
+ * @brief Humidity Control Operating State Command Class handlers and control function
+ *
+ * This module implement some of the functions to control the
+ * Humidity Control Operating State Command Class
+ *
+ * @{
+ */
+
+#ifndef ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_H
+#define ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_H
+
+#include "sl_status.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+sl_status_t zwave_command_class_humidity_control_operating_state_init();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_H
+ /** @} end zwave_command_class_humidity_control_operating_state */
\ No newline at end of file
diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_setpoint.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_setpoint.c
new file mode 100644
index 0000000000..423426e2af
--- /dev/null
+++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_setpoint.c
@@ -0,0 +1,796 @@
+
+/******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+
+// System
+#include
+
+#include "zwave_command_class_humidity_control_setpoint.h"
+#include "zwave_command_class_humidity_control_types.h"
+#include "zwave_command_classes_utils.h"
+#include "ZW_classcmd.h"
+
+// Includes from other ZPC Components
+#include "zwave_command_class_indices.h"
+#include "zwave_command_handler.h"
+#include "zwave_command_class_version_types.h"
+#include "zpc_attribute_store_network_helper.h"
+#include "attribute_store_defined_attribute_types.h"
+
+// Unify
+#include "attribute_resolver.h"
+#include "attribute_store.h"
+#include "attribute_store_helper.h"
+#include "sl_log.h"
+
+#define LOG_TAG "zwave_command_class_humidity_control_setpoint"
+#define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_##type
+
+// Aliases
+#define MASK_PRECISION \
+ HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT_PROPERTIES2_PRECISION1_MASK
+#define MASK_SCALE \
+ HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT_PROPERTIES2_SCALE1_MASK
+#define MASK_SIZE \
+ HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT_PROPERTIES2_SIZE1_MASK
+
+// Max values in Humidity Control Setpoint Supported Report values
+#define MAX_SUPPORTED_SETPOINT_MODES 4
+
+enum humidity_control_setpoint_value_type {
+ SETPOINT_CURRENT_VALUE,
+ SETPOINT_MIN_VALUE,
+ SETPOINT_MAX_VALUE
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Utils
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Get setpoint real value from raw value and precision
+ *
+ * get_setpoint_value(10, 0) => 10.0
+ * get_setpoint_value(10, 1) => 1.0
+ * get_setpoint_value(10, 2) => 0.1
+ *
+ * @param value Raw value
+ * @param precision Precision of value
+ *
+ * @return double Real value
+ */
+double get_setpoint_value(humidity_control_setpoint_value_t value,
+ humidity_control_setpoint_precision_t precision)
+{
+ double current_value = value;
+ for (uint8_t i = 0; i < precision; i++) {
+ current_value /= 10.;
+ }
+ return current_value;
+}
+/**
+ * @brief Check if current value can be set (in bounds of value_min and value_max)
+ *
+ * If value_min and value_max field doesn't exists, it will return false
+ *
+ * @param setpoint_node Current setpoint node
+ * @param value_raw Value to check (precision will be applied to it)
+ * @param precision Precision of value
+ *
+ * @return true Value in bounds
+ * @return false Value not in bounds or bounds cannot be found
+ */
+bool check_setpoint_value_bounds(
+ attribute_store_node_t setpoint_node,
+ humidity_control_setpoint_value_t value_raw,
+ humidity_control_setpoint_precision_t precision)
+{
+ humidity_control_setpoint_value_t min_value_raw;
+ humidity_control_setpoint_precision_t min_value_precision;
+ humidity_control_setpoint_value_t max_value_raw;
+ humidity_control_setpoint_precision_t max_value_precision;
+
+ attribute_store_node_t min_value_node
+ = attribute_store_get_first_child_by_type(setpoint_node,
+ ATTRIBUTE(MIN_VALUE));
+
+ sl_status_t status = attribute_store_get_reported(min_value_node,
+ &min_value_raw,
+ sizeof(min_value_raw));
+
+ if (status != SL_STATUS_OK) {
+ sl_log_error(LOG_TAG, "Can't get MIN_VALUE attribute value");
+ return false;
+ }
+
+ status = attribute_store_get_child_reported(min_value_node,
+ ATTRIBUTE(MIN_VALUE_PRECISION),
+ &min_value_precision,
+ sizeof(min_value_precision));
+
+ if (status != SL_STATUS_OK) {
+ sl_log_error(LOG_TAG, "Can't get MIN_VALUE_PRECISION attribute value");
+ return false;
+ }
+
+ attribute_store_node_t max_value_node
+ = attribute_store_get_first_child_by_type(setpoint_node,
+ ATTRIBUTE(MAX_VALUE));
+
+ status = attribute_store_get_reported(max_value_node,
+ &max_value_raw,
+ sizeof(max_value_raw));
+
+ if (status != SL_STATUS_OK) {
+ sl_log_error(LOG_TAG, "Can't get MAX_VALUE attribute value");
+ return false;
+ }
+
+ status = attribute_store_get_child_reported(max_value_node,
+ ATTRIBUTE(MAX_VALUE_PRECISION),
+ &max_value_precision,
+ sizeof(max_value_precision));
+
+ if (status != SL_STATUS_OK) {
+ sl_log_error(LOG_TAG, "Can't get MAX_VALUE_PRECISION attribute value");
+ return false;
+ }
+
+ double min_value = get_setpoint_value(min_value_raw, min_value_precision);
+ double max_value = get_setpoint_value(max_value_raw, max_value_precision);
+ double value = get_setpoint_value(value_raw, precision);
+
+ bool result = value >= min_value && value <= max_value;
+
+ if (!result) {
+ sl_log_error(LOG_TAG,
+ "Value %f is out of bounds. Should be between %f, %f.",
+ value,
+ min_value,
+ max_value);
+ }
+
+ return result;
+}
+
+/**
+ * @brief Interpret value from a report frame and store it in the attribute store
+ *
+ * @warning This function doesn't check any bounds in frame_data
+ *
+ * @param setpoint_node Current setpoint node
+ * @param value_type Determines the attribute field of value report (min_value, max_value or value)
+ * @param frame_data Frame raw data
+ * @param start_index Starting index in the frame raw data
+ *
+ * @return uint8_t Byte read count
+ */
+uint8_t interpret_value_from_report(
+ attribute_store_node_t setpoint_node,
+ enum humidity_control_setpoint_value_type value_type,
+ const uint8_t *frame_data,
+ uint8_t start_index)
+{
+ // Save current index
+ uint8_t current_index = start_index;
+ // Determine used types
+ attribute_store_type_t value_store_type;
+ attribute_store_type_t value_scale_type;
+ attribute_store_type_t value_precision_type;
+ switch (value_type) {
+ case SETPOINT_CURRENT_VALUE:
+ value_store_type = ATTRIBUTE(VALUE);
+ value_scale_type = ATTRIBUTE(VALUE_SCALE);
+ value_precision_type = ATTRIBUTE(VALUE_PRECISION);
+ break;
+ case SETPOINT_MIN_VALUE:
+ value_store_type = ATTRIBUTE(MIN_VALUE);
+ value_scale_type = ATTRIBUTE(MIN_VALUE_SCALE);
+ value_precision_type = ATTRIBUTE(MIN_VALUE_PRECISION);
+ break;
+ case SETPOINT_MAX_VALUE:
+ value_store_type = ATTRIBUTE(MAX_VALUE);
+ value_scale_type = ATTRIBUTE(MAX_VALUE_SCALE);
+ value_precision_type = ATTRIBUTE(MAX_VALUE_PRECISION);
+ break;
+ default:
+ sl_log_error(LOG_TAG, "Invalid humidity_control_setpoint_value_type");
+ return 0;
+ }
+
+ humidity_control_setpoint_precision_t precision
+ = (frame_data[current_index] & MASK_PRECISION) >> 5;
+
+ humidity_control_setpoint_scale_t scale
+ = (frame_data[current_index] & MASK_SCALE) >> 3;
+
+ humidity_control_setpoint_size_t size = frame_data[current_index] & MASK_SIZE;
+
+ if (size > 4) {
+ sl_log_error(LOG_TAG, "Incorrect reported size for setpoint capabilities");
+ return 0;
+ }
+
+ // Next field(s) (value)
+ current_index++;
+
+ humidity_control_setpoint_value_t value
+ = get_signed_value_from_frame_and_size(&frame_data[current_index], size);
+
+ // Check bounds
+ if (value_type == SETPOINT_CURRENT_VALUE
+ && !check_setpoint_value_bounds(setpoint_node, value, precision)) {
+ return 0;
+ }
+
+ // Create the value node if missing
+ attribute_store_node_t value_node
+ = attribute_store_create_child_if_missing(setpoint_node, value_store_type);
+
+ // Set computed value
+ attribute_store_set_reported(value_node, &value, sizeof(value));
+
+ // Set scale value
+ attribute_store_set_child_reported(value_node,
+ value_scale_type,
+ &scale,
+ sizeof(scale));
+ // Set precision value
+ attribute_store_set_child_reported(value_node,
+ value_precision_type,
+ &precision,
+ sizeof(precision));
+ // Return # of bytes read
+ return 1 + size;
+}
+
+// Remove all ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_TYPE from attribute store
+void remove_all_humidity_setpoint_type_attributes(
+ attribute_store_node_t endpoint_node)
+{
+ attribute_store_node_t type_node;
+ do {
+ type_node = attribute_store_get_node_child_by_type(endpoint_node,
+ ATTRIBUTE(TYPE),
+ 0);
+ attribute_store_delete_node(type_node);
+ } while (type_node != ATTRIBUTE_STORE_INVALID_NODE);
+}
+
+// Create humidity setpoint
+void create_humidity_setpoint_type_node(
+ attribute_store_node_t endpoint_node,
+ humidity_control_setpoint_type_t setpoint_type)
+{
+ // Check compatibility
+ // if (!is_thermostat_setpoint_mode_compatible_with_version(type, version)) {
+ // return ATTRIBUTE_STORE_INVALID_NODE;
+ // }
+
+ attribute_store_node_t type_node
+ = attribute_store_emplace(endpoint_node,
+ ATTRIBUTE(TYPE),
+ &setpoint_type,
+ sizeof(setpoint_type));
+
+ // Add the six other nodes under the type.
+ const attribute_store_type_t additional_nodes[]
+ = {// Scale support to check value reported (Not supported for now)
+ // ATTRIBUTE(SUPPORTED_SCALE),
+ // Min and Max attribute first to check value reported
+ ATTRIBUTE(MIN_VALUE),
+ ATTRIBUTE(MAX_VALUE),
+ // Finally, actual value
+ ATTRIBUTE(VALUE)};
+
+ attribute_store_add_if_missing(type_node,
+ additional_nodes,
+ COUNT_OF(additional_nodes));
+}
+
+// Create ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_TYPE based on bitmask in supported_types
+// This function will also check version
+void create_all_supported_humidity_setpoint_type(
+ attribute_store_node_t endpoint_node,
+ humidity_control_setpoint_supported_types_t supported_types)
+{
+ // Contains current bit tested
+ uint8_t setpoint_mode_current_bit = 0x0;
+
+ for (uint8_t i = 0; i <= MAX_SUPPORTED_SETPOINT_MODES; i++) {
+ setpoint_mode_current_bit = 1 << i;
+ setpoint_mode_current_bit &= supported_types;
+ humidity_control_setpoint_type_t current_type;
+
+ // Check if current bit tested correspond to a registered type
+ switch (setpoint_mode_current_bit) {
+ case 0x02:
+ current_type
+ = HUMIDITY_CONTROL_SETPOINT_REPORT_SETPOINT_TYPE_HUMIDIFIER;
+ break;
+ case 0x04:
+ current_type
+ = HUMIDITY_CONTROL_SETPOINT_REPORT_SETPOINT_TYPE_DEHUMIDIFIER;
+ break;
+ case 0x08:
+ current_type = HUMIDITY_CONTROL_SETPOINT_REPORT_SETPOINT_TYPE_AUTO_V2;
+ break;
+ default:
+ sl_log_error(
+ LOG_TAG,
+ "Invalid bit in Humidity Control SetPoint supported types");
+ continue;
+ }
+
+ create_humidity_setpoint_type_node(endpoint_node, current_type);
+ }
+}
+
+// Get associated ATTRIBUTE(TYPE) from current_node.
+// The ATTRIBUTE(TYPE) should be a parent of current_node
+humidity_control_setpoint_type_t
+ get_associated_setpoint_type(attribute_store_node_t current_node)
+{
+ attribute_store_node_t type_node
+ = attribute_store_get_first_parent_with_type(current_node, ATTRIBUTE(TYPE));
+
+ if (type_node == ATTRIBUTE_STORE_INVALID_NODE) {
+ sl_log_error(LOG_TAG, "Can't get type node.");
+ return 0;
+ }
+
+ humidity_control_setpoint_type_t current_type;
+ sl_status_t status = attribute_store_get_reported(type_node,
+ ¤t_type,
+ sizeof(current_type));
+
+ if (status != SL_STATUS_OK) {
+ sl_log_error(LOG_TAG, "Can't get type node reported value.");
+ return 0;
+ }
+
+ return current_type;
+}
+
+// Get setpoint node with specified value
+attribute_store_node_t
+ get_setpoint_node(attribute_store_node_t endpoint_node,
+ humidity_control_setpoint_type_t setpoint_type)
+{
+ return attribute_store_get_node_child_by_value(endpoint_node,
+ ATTRIBUTE(TYPE),
+ REPORTED_ATTRIBUTE,
+ &setpoint_type,
+ sizeof(setpoint_type),
+ 0);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Version & Attribute Creation
+/////////////////////////////////////////////////////////////////////////////
+static void
+ zwave_command_class_humidity_control_setpoint_on_version_attribute_update(
+ attribute_store_node_t updated_node, attribute_store_change_t change)
+{
+ if (change == ATTRIBUTE_DELETED) {
+ return;
+ }
+
+ zwave_cc_version_t version = 0;
+ attribute_store_get_reported(updated_node, &version, sizeof(version));
+
+ if (version == 0) {
+ return;
+ }
+
+ attribute_store_node_t endpoint_node
+ = attribute_store_get_first_parent_with_type(updated_node,
+ ATTRIBUTE_ENDPOINT_ID);
+
+ // The order of the attribute matter since it defines the order of the
+ // Z-Wave get command order.
+ const attribute_store_type_t attributes[] = {ATTRIBUTE(SUPPORTED_TYPES)};
+
+ attribute_store_add_if_missing(endpoint_node,
+ attributes,
+ COUNT_OF(attributes));
+}
+
+static void
+ zwave_command_class_humidity_control_setpoint_on_scale_attribute_update(
+ attribute_store_node_t updated_node, attribute_store_change_t change)
+{
+ if (change == ATTRIBUTE_DELETED) {
+ return;
+ }
+
+ humidity_control_setpoint_scale_t scale;
+ attribute_store_get_reported(updated_node, &scale, sizeof(scale));
+
+ // Nothing to do here
+ if (scale <= 1) {
+ return;
+ }
+
+ sl_log_warning(LOG_TAG, "Unsupported scale value, setting scale to 0.");
+
+ // Default value
+ scale = 0;
+ // Else if value is not supported
+ attribute_store_set_reported(updated_node, &scale, sizeof(scale));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Humidity Control SetPoint Supported Types Get/Report
+/////////////////////////////////////////////////////////////////////////////
+static sl_status_t
+ zwave_command_class_humidity_control_setpoint_supported_types_get(
+ attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
+{
+ (void)node; // unused.
+ ZW_HUMIDITY_CONTROL_SETPOINT_SUPPORTED_GET_FRAME *get_frame
+ = (ZW_HUMIDITY_CONTROL_SETPOINT_SUPPORTED_GET_FRAME *)frame;
+ get_frame->cmdClass = COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT;
+ get_frame->cmd = HUMIDITY_CONTROL_SETPOINT_SUPPORTED_GET;
+ *frame_length = sizeof(ZW_HUMIDITY_CONTROL_SETPOINT_SUPPORTED_GET_FRAME);
+ return SL_STATUS_OK;
+}
+
+sl_status_t
+ zwave_command_class_humidity_control_setpoint_supported_handle_report(
+ const zwave_controller_connection_info_t *connection_info,
+ const uint8_t *frame_data,
+ uint16_t frame_length)
+{
+ // We expect a frame length of 3 since the bitmask is supposed to be on a single byte
+ if (frame_length != 3) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ humidity_control_setpoint_supported_types_t supported_types = frame_data[2];
+
+ attribute_store_node_t endpoint_node
+ = zwave_command_class_get_endpoint_node(connection_info);
+
+ attribute_store_set_child_reported(endpoint_node,
+ ATTRIBUTE(SUPPORTED_TYPES),
+ &supported_types,
+ sizeof(supported_types));
+
+ // First remove all existing type nodes
+ // This is done to easily update the bitmask or bitmask interpretation so we don't have any leftovers.
+ remove_all_humidity_setpoint_type_attributes(endpoint_node);
+ // Then create all type nodes
+ create_all_supported_humidity_setpoint_type(endpoint_node, supported_types);
+
+ return SL_STATUS_OK;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Humidity Control SetPoint Capabilities Get/Report
+/////////////////////////////////////////////////////////////////////////////
+static sl_status_t
+ zwave_command_class_humidity_control_setpoint_capabilities_get(
+ attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
+{
+ humidity_control_setpoint_type_t setpoint_type
+ = get_associated_setpoint_type(node);
+
+ if (setpoint_type == 0) {
+ sl_log_error(LOG_TAG, "Can't get setpoint type for GET Capabilities.");
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ ZW_HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_GET_FRAME *get_frame
+ = (ZW_HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_GET_FRAME *)frame;
+ get_frame->cmdClass = COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT;
+ get_frame->cmd = HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_GET;
+ get_frame->properties1 = setpoint_type;
+ *frame_length = sizeof(ZW_HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_GET_FRAME);
+ return SL_STATUS_OK;
+}
+
+sl_status_t
+ zwave_command_class_humidity_control_setpoint_capabilities_handle_report(
+ const zwave_controller_connection_info_t *connection_info,
+ const uint8_t *frame_data,
+ uint16_t frame_length)
+{
+ if (frame_length < 5) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ humidity_control_setpoint_type_t setpoint_type
+ = frame_data[2]
+ & HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT_PROPERTIES1_SETPOINT_TYPE_MASK;
+
+ attribute_store_node_t endpoint_node
+ = zwave_command_class_get_endpoint_node(connection_info);
+
+ attribute_store_node_t setpoint_node
+ = get_setpoint_node(endpoint_node, setpoint_type);
+
+ if (setpoint_node == ATTRIBUTE_STORE_INVALID_NODE) {
+ sl_log_error(
+ LOG_TAG,
+ "Can't get setpoint type node for setpoint capabilities report");
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ const uint8_t current_index = 3;
+ uint8_t byte_read_count = interpret_value_from_report(setpoint_node,
+ SETPOINT_MIN_VALUE,
+ frame_data,
+ current_index);
+
+ // If we didn't read anything or if we will go OOB
+ if (byte_read_count == 0
+ || (current_index + byte_read_count + 1) >= frame_length) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ byte_read_count
+ = interpret_value_from_report(setpoint_node,
+ SETPOINT_MAX_VALUE,
+ frame_data,
+ current_index + byte_read_count);
+
+ if (byte_read_count == 0) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ return SL_STATUS_OK;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Humidity Control SetPoint Capabilities Set/Get/Report
+/////////////////////////////////////////////////////////////////////////////
+static sl_status_t zwave_command_class_humidity_control_setpoint_set(
+ attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
+{
+ humidity_control_setpoint_type_t setpoint_type
+ = get_associated_setpoint_type(node);
+
+ if (setpoint_type == 0) {
+ sl_log_error(LOG_TAG, "Can't get setpoint type for SET.");
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ humidity_control_setpoint_value_t desired_value;
+ attribute_store_get_desired(node, &desired_value, sizeof(desired_value));
+
+ attribute_store_node_t precision_node
+ = attribute_store_get_first_child_by_type(node, ATTRIBUTE(VALUE_PRECISION));
+
+ humidity_control_setpoint_precision_t precision = 0;
+ sl_status_t status
+ = attribute_store_get_desired_else_reported(precision_node,
+ &precision,
+ sizeof(precision));
+ if (status != SL_STATUS_OK) {
+ sl_log_error(LOG_TAG, "Can't get precision value for SET.");
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ attribute_store_node_t setpoint_node = attribute_store_get_node_parent(node);
+ if (!check_setpoint_value_bounds(setpoint_node, desired_value, precision)) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ if (status != SL_STATUS_OK) {
+ sl_log_error(LOG_TAG, "Can't get precision for SET.");
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ humidity_control_setpoint_scale_t scale;
+ attribute_store_node_t scale_node
+ = attribute_store_get_first_child_by_type(node, ATTRIBUTE(VALUE_SCALE));
+
+ status = attribute_store_get_desired_else_reported(scale_node,
+ &scale,
+ sizeof(scale));
+
+ if (status != SL_STATUS_OK) {
+ sl_log_error(LOG_TAG, "Can't get scale value for SET.");
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ uint8_t value_properties_field = (precision << 5) | (scale << 3);
+
+ if (abs(desired_value) < INT8_MAX) {
+ ZW_HUMIDITY_CONTROL_SETPOINT_SET_1BYTE_FRAME *set_frame
+ = (ZW_HUMIDITY_CONTROL_SETPOINT_SET_1BYTE_FRAME *)frame;
+ set_frame->cmdClass = COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT;
+ set_frame->cmd = HUMIDITY_CONTROL_SETPOINT_SET;
+ set_frame->properties1 = setpoint_type;
+ set_frame->properties2 = value_properties_field | 1;
+
+ set_frame->value1 = (uint8_t)(desired_value & 0x000000FF);
+ *frame_length = sizeof(ZW_HUMIDITY_CONTROL_SETPOINT_SET_1BYTE_FRAME);
+
+ } else if (abs(desired_value) < INT16_MAX) {
+ ZW_HUMIDITY_CONTROL_SETPOINT_SET_2BYTE_FRAME *set_frame
+ = (ZW_HUMIDITY_CONTROL_SETPOINT_SET_2BYTE_FRAME *)frame;
+ set_frame->cmdClass = COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT;
+ set_frame->cmd = HUMIDITY_CONTROL_SETPOINT_SET;
+ set_frame->properties1 = setpoint_type;
+ set_frame->properties2 = value_properties_field | 2;
+
+ set_frame->value1 = (uint8_t)((desired_value & 0x0000FF00) >> 8);
+ set_frame->value2 = (uint8_t)(desired_value & 0x000000FF);
+
+ *frame_length = sizeof(ZW_HUMIDITY_CONTROL_SETPOINT_SET_2BYTE_FRAME);
+ } else if (abs(desired_value) < INT32_MAX) {
+ ZW_HUMIDITY_CONTROL_SETPOINT_SET_4BYTE_FRAME *set_frame
+ = (ZW_HUMIDITY_CONTROL_SETPOINT_SET_4BYTE_FRAME *)frame;
+ set_frame->cmdClass = COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT;
+ set_frame->cmd = HUMIDITY_CONTROL_SETPOINT_SET;
+ set_frame->properties1 = setpoint_type;
+ set_frame->properties2 = value_properties_field | 4;
+
+ set_frame->value1 = (uint8_t)((desired_value & 0xFF000000) >> 24); // MSB
+ set_frame->value2 = (uint8_t)((desired_value & 0x00FF0000) >> 16);
+ set_frame->value3 = (uint8_t)((desired_value & 0x0000FF00) >> 8);
+ set_frame->value4 = (uint8_t)(desired_value & 0x000000FF); // LSB
+
+ *frame_length = sizeof(ZW_HUMIDITY_CONTROL_SETPOINT_SET_4BYTE_FRAME);
+ } else {
+ sl_log_error(LOG_TAG, "Invalid desired value size");
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ return SL_STATUS_OK;
+}
+
+static sl_status_t zwave_command_class_humidity_control_setpoint_get(
+ attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length)
+{
+ humidity_control_setpoint_type_t setpoint_type
+ = get_associated_setpoint_type(node);
+
+ if (setpoint_type == 0) {
+ sl_log_error(LOG_TAG, "Can't get setpoint type for GET.");
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ ZW_HUMIDITY_CONTROL_SETPOINT_GET_FRAME *set_frame
+ = (ZW_HUMIDITY_CONTROL_SETPOINT_GET_FRAME *)frame;
+ set_frame->cmdClass = COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT;
+ set_frame->cmd = HUMIDITY_CONTROL_SETPOINT_GET;
+ set_frame->properties1 = setpoint_type;
+ *frame_length = sizeof(ZW_HUMIDITY_CONTROL_SETPOINT_GET_FRAME);
+ return SL_STATUS_OK;
+}
+
+sl_status_t zwave_command_class_humidity_control_setpoint_handle_report(
+ const zwave_controller_connection_info_t *connection_info,
+ const uint8_t *frame_data,
+ uint16_t frame_length)
+{
+ if (frame_length < 5) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ humidity_control_setpoint_type_t setpoint_type
+ = frame_data[2]
+ & HUMIDITY_CONTROL_SETPOINT_REPORT_PROPERTIES1_SETPOINT_TYPE_MASK;
+
+ attribute_store_node_t endpoint_node
+ = zwave_command_class_get_endpoint_node(connection_info);
+
+ attribute_store_node_t setpoint_node
+ = get_setpoint_node(endpoint_node, setpoint_type);
+
+ if (setpoint_node == ATTRIBUTE_STORE_INVALID_NODE) {
+ sl_log_error(LOG_TAG, "Can't get setpoint type node for setpoint report");
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ const uint8_t current_index = 3;
+ uint8_t byte_read_count = interpret_value_from_report(setpoint_node,
+ SETPOINT_CURRENT_VALUE,
+ frame_data,
+ current_index);
+
+ // If we didn't read anything
+ if (byte_read_count == 0) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ return SL_STATUS_OK;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Class logic
+/////////////////////////////////////////////////////////////////////////////
+
+// Control handler
+sl_status_t zwave_command_class_humidity_control_setpoint_control_handler(
+ const zwave_controller_connection_info_t *connection_info,
+ const uint8_t *frame_data,
+ uint16_t frame_length)
+{
+ if (frame_length <= COMMAND_INDEX) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ switch (frame_data[COMMAND_INDEX]) {
+ case HUMIDITY_CONTROL_SETPOINT_SUPPORTED_REPORT:
+ return zwave_command_class_humidity_control_setpoint_supported_handle_report(
+ connection_info,
+ frame_data,
+ frame_length);
+ case HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT:
+ return zwave_command_class_humidity_control_setpoint_capabilities_handle_report(
+ connection_info,
+ frame_data,
+ frame_length);
+ case HUMIDITY_CONTROL_SETPOINT_REPORT:
+ return zwave_command_class_humidity_control_setpoint_handle_report(
+ connection_info,
+ frame_data,
+ frame_length);
+ default:
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+}
+
+// Entry point
+sl_status_t zwave_command_class_humidity_control_setpoint_init()
+{
+ attribute_store_register_callback_by_type(
+ &zwave_command_class_humidity_control_setpoint_on_version_attribute_update,
+ ATTRIBUTE(VERSION));
+
+ attribute_resolver_register_rule(
+ ATTRIBUTE(SUPPORTED_TYPES),
+ NULL,
+ &zwave_command_class_humidity_control_setpoint_supported_types_get);
+
+ // Only monitor one of ATTRIBUTE(MIN_VALUE) or ATTRIBUTE(MAX_VALUE) we don't need both
+ attribute_resolver_register_rule(
+ ATTRIBUTE(MIN_VALUE),
+ NULL,
+ &zwave_command_class_humidity_control_setpoint_capabilities_get);
+
+ // Only monitor one of ATTRIBUTE(MIN_VALUE) or ATTRIBUTE(MAX_VALUE) we don't need both
+ attribute_resolver_register_rule(
+ ATTRIBUTE(VALUE),
+ &zwave_command_class_humidity_control_setpoint_set,
+ &zwave_command_class_humidity_control_setpoint_get);
+
+ // Scale limits
+ attribute_store_register_callback_by_type(
+ &zwave_command_class_humidity_control_setpoint_on_scale_attribute_update,
+ ATTRIBUTE(VALUE_SCALE));
+ attribute_store_register_callback_by_type(
+ &zwave_command_class_humidity_control_setpoint_on_scale_attribute_update,
+ ATTRIBUTE(MIN_VALUE_SCALE));
+ attribute_store_register_callback_by_type(
+ &zwave_command_class_humidity_control_setpoint_on_scale_attribute_update,
+ ATTRIBUTE(MAX_VALUE_SCALE));
+
+ zwave_command_handler_t handler = {};
+ handler.support_handler = NULL;
+ handler.control_handler
+ = zwave_command_class_humidity_control_setpoint_control_handler;
+ handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NONE;
+ handler.manual_security_validation = false;
+ handler.command_class = COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT;
+ handler.version = 2;
+ handler.command_class_name = "Humidity Control SetPoint";
+ handler.comments = "Experimental. Supported Scale command not supported "
+ "since the report doesn't contain Setpoint type.";
+
+ return zwave_command_handler_register_handler(handler);
+}
\ No newline at end of file
diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_setpoint.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_setpoint.h
new file mode 100644
index 0000000000..f7521a97ab
--- /dev/null
+++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_setpoint.h
@@ -0,0 +1,41 @@
+
+/******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+
+/**
+ * @defgroup zwave_command_class_humidity_control_setpoint
+ * @brief Humidity Control Setpoint Command Class handlers and control function
+ *
+ * This module implement some of the functions to control the
+ * Humidity Control Setpoint Command Class
+ *
+ * @{
+ */
+
+#ifndef ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_H
+#define ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_H
+
+#include "sl_status.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+sl_status_t zwave_command_class_humidity_control_setpoint_init();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //ZWAVE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_H
+ /** @} end zwave_command_class_humidity_control_setpoint */
\ No newline at end of file
diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_classes_fixt.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_classes_fixt.c
index cac0a8c665..1c7254169e 100644
--- a/applications/zpc/components/zwave_command_classes/src/zwave_command_classes_fixt.c
+++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_classes_fixt.c
@@ -53,6 +53,8 @@
#include "zwave_command_class_transport_service.h"
#include "zwave_command_class_indicator_control.h"
#include "zwave_command_class_manufacturer_specific_control.h"
+#include "zwave_command_class_humidity_control_mode.h"
+
// Generic includes
#include
@@ -88,6 +90,7 @@ sl_status_t zwave_command_classes_init()
status |= zwave_command_class_central_scene_init();
status |= zwave_command_class_configuration_init();
status |= zwave_command_class_device_reset_locally_init();
+ status |= zwave_command_class_humidity_control_mode_init();
status |= zwave_command_class_inclusion_controller_init();
status |= zwave_command_class_indicator_init();
status |= zwave_command_class_manufacturer_specific_init();
diff --git a/applications/zpc/components/zwave_command_classes/test/CMakeLists.txt b/applications/zpc/components/zwave_command_classes/test/CMakeLists.txt
index 4d72dfb0ef..54a1d9f033 100644
--- a/applications/zpc/components/zwave_command_classes/test/CMakeLists.txt
+++ b/applications/zpc/components/zwave_command_classes/test/CMakeLists.txt
@@ -726,3 +726,50 @@ target_add_unittest(
uic_attribute_resolver_mock
zpc_attribute_resolver_mock
)
+
+# Humidity Control Mode test
+target_add_unittest(
+ zwave_command_classes
+ NAME
+ zwave_command_class_humidity_control_mode_test
+ SOURCES
+ zwave_command_class_humidity_control_mode_test.c
+ DEPENDS
+ zpc_attribute_store_test_helper
+ zwave_controller
+ zwave_command_handler_mock
+ uic_attribute_resolver_mock
+ zpc_attribute_resolver_mock
+ uic_dotdot_mqtt_mock)
+
+ # Humidity Control Operating State test
+target_add_unittest(
+ zwave_command_classes
+ NAME
+ zwave_command_class_humidity_control_operating_state_test
+ SOURCES
+ zwave_command_class_humidity_control_operating_state_test.c
+ DEPENDS
+ zpc_attribute_store_test_helper
+ zwave_controller
+ zwave_command_handler_mock
+ uic_attribute_resolver_mock
+ zpc_attribute_resolver_mock
+ uic_dotdot_mqtt_mock)
+
+ # Humidity Control SetPoint test
+ target_add_unittest(
+ zwave_command_classes
+ NAME
+ zwave_command_class_humidity_control_setpoint_test
+ SOURCES
+ zwave_command_class_humidity_control_setpoint_test.cpp
+ DEPENDS
+ zpc_attribute_store_test_helper
+ zwave_controller
+ zwave_command_handler_mock
+ uic_attribute_resolver_mock
+ zpc_attribute_resolver_mock
+ uic_dotdot_mqtt_mock)
+
+
\ No newline at end of file
diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_mode_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_mode_test.c
new file mode 100644
index 0000000000..497a08c833
--- /dev/null
+++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_mode_test.c
@@ -0,0 +1,495 @@
+/******************************************************************************
+ * # License
+ * Copyright 2023 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+
+#include "zwave_command_class_humidity_control_mode.h"
+#include "zwave_command_class_humidity_control_types.h"
+#include "zwave_command_classes_utils.h"
+#include "unity.h"
+
+// Generic includes
+#include
+
+// Includes from other components
+#include "datastore.h"
+#include "attribute_store.h"
+#include "attribute_store_helper.h"
+#include "attribute_store_fixt.h"
+#include "zpc_attribute_store_type_registration.h"
+
+// Interface includes
+#include "attribute_store_defined_attribute_types.h"
+#include "ZW_classcmd.h"
+#include "zwave_utils.h"
+#include "zwave_controller_types.h"
+
+// Test helpers
+#include "zpc_attribute_store_test_helper.h"
+
+// Mock includes
+#include "attribute_resolver_mock.h"
+#include "zpc_attribute_resolver_mock.h"
+#include "zwave_command_handler_mock.h"
+#include "dotdot_mqtt_mock.h"
+#include "dotdot_mqtt_generated_commands_mock.h"
+
+static zwave_command_handler_t handler = {};
+
+static attribute_resolver_function_t current_expected_humidity_control_mode_get
+ = NULL;
+static attribute_resolver_function_t current_expected_humidity_control_mode_set
+ = NULL;
+static attribute_resolver_function_t
+ supported_expected_humidity_control_modes_get
+ = NULL;
+
+// Buffer for frame
+static uint8_t received_frame[255] = {};
+static uint16_t received_frame_size = 0;
+
+// Stub functions
+static sl_status_t
+ attribute_resolver_register_rule_stub(attribute_store_type_t node_type,
+ attribute_resolver_function_t set_func,
+ attribute_resolver_function_t get_func,
+ int cmock_num_calls)
+{
+ if (node_type == ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE) {
+ TEST_ASSERT_NOT_NULL(set_func);
+ TEST_ASSERT_NOT_NULL(get_func);
+ current_expected_humidity_control_mode_get = get_func;
+ current_expected_humidity_control_mode_set = set_func;
+ } else if (node_type
+ == ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES) {
+ TEST_ASSERT_NULL(set_func);
+ TEST_ASSERT_NOT_NULL(get_func);
+ supported_expected_humidity_control_modes_get = get_func;
+ }
+
+ return SL_STATUS_OK;
+}
+
+static sl_status_t zwave_command_handler_register_handler_stub(
+ zwave_command_handler_t new_command_class_handler, int cmock_num_calls)
+{
+ handler = new_command_class_handler;
+
+ TEST_ASSERT_EQUAL(ZWAVE_CONTROLLER_ENCAPSULATION_NONE,
+ handler.minimal_scheme);
+ TEST_ASSERT_EQUAL(COMMAND_CLASS_HUMIDITY_CONTROL_MODE, handler.command_class);
+ TEST_ASSERT_EQUAL(2, handler.version);
+ TEST_ASSERT_NOT_NULL(handler.control_handler);
+ TEST_ASSERT_NULL(handler.support_handler);
+ TEST_ASSERT_FALSE(handler.manual_security_validation);
+
+ return SL_STATUS_OK;
+}
+
+/// Setup the test suite (called once before all test_xxx functions are called)
+void suiteSetUp()
+{
+ datastore_init(":memory:");
+ attribute_store_init();
+ zpc_attribute_store_register_known_attribute_types();
+}
+
+/// Teardown the test suite (called once after all test_xxx functions are called)
+int suiteTearDown(int num_failures)
+{
+ attribute_store_teardown();
+ datastore_teardown();
+ return num_failures;
+}
+
+/// Called before each and every test
+void setUp()
+{
+ zpc_attribute_store_test_helper_create_network();
+
+ // Unset previous definition get/set functions
+ current_expected_humidity_control_mode_get = NULL;
+ current_expected_humidity_control_mode_set = NULL;
+ supported_expected_humidity_control_modes_get = NULL;
+ memset(received_frame, 0, sizeof(received_frame));
+ received_frame_size = 0;
+ // Unset previous definition of handler
+ memset(&handler, 0, sizeof(zwave_command_handler_t));
+
+ // Resolution functions
+ attribute_resolver_register_rule_Stub(&attribute_resolver_register_rule_stub);
+ // Handler registration
+ zwave_command_handler_register_handler_Stub(
+ &zwave_command_handler_register_handler_stub);
+ // Call init
+ TEST_ASSERT_EQUAL(SL_STATUS_OK,
+ zwave_command_class_humidity_control_mode_init());
+}
+
+/// Called after each and every test
+void tearDown() {}
+
+////////////////////////////////////////////////////////////////////////////
+// UTILS
+////////////////////////////////////////////////////////////////////////////
+
+// Set version and thus initialize the attribute tree
+void set_version(zwave_cc_version_t version)
+{
+ attribute_store_node_t version_node = attribute_store_add_node(
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_VERSION,
+ endpoint_id_node);
+
+ attribute_store_set_reported(version_node, &version, sizeof(version));
+}
+
+void set_current_mode(humidity_control_mode_t humidity_control_mode)
+{
+ sl_status_t reported_status = attribute_store_set_child_reported(
+ endpoint_id_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE,
+ &humidity_control_mode,
+ sizeof(humidity_control_mode));
+
+ TEST_ASSERT_EQUAL_MESSAGE(
+ SL_STATUS_OK,
+ reported_status,
+ "Should be able to set humidity control mode value");
+}
+
+void set_supported_modes(
+ humidity_control_supported_modes_t supported_modes)
+{
+ sl_status_t status = attribute_store_set_child_reported(
+ endpoint_id_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES,
+ &supported_modes,
+ sizeof(supported_modes));
+
+ TEST_ASSERT_EQUAL_MESSAGE(SL_STATUS_OK,
+ status,
+ "Should be able to set supported mode node");
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Helper
+////////////////////////////////////////////////////////////////////////////
+void helper_humidity_control_mode_report(zwave_cc_version_t version,
+ bool happy_case)
+{
+ printf("Testing report version %d. Happy case : %d\n", version, happy_case);
+
+ set_version(version);
+
+ zwave_controller_connection_info_t info = {};
+ info.remote.node_id = node_id;
+ info.remote.endpoint_id = endpoint_id;
+ info.local.is_multicast = false;
+
+ TEST_ASSERT_NOT_NULL(handler.control_handler);
+ TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED,
+ handler.control_handler(&info, NULL, 0));
+
+ // Set supported mode based on the happy case flag
+ // If not happy case, no supported mode
+ humidity_control_supported_modes_t supported_modes;
+ humidity_control_mode_t expected_humidity_control_mode;
+ switch (version) {
+ case 1:
+ supported_modes = happy_case ? 0b00000110 : 0b00000000;
+ expected_humidity_control_mode
+ = HUMIDITY_CONTROL_MODE_SET_MODE_DEHUMIDIFY;
+ break;
+ case 2:
+ supported_modes = happy_case ? 0b00001110 : 0b00000000;
+ expected_humidity_control_mode = HUMIDITY_CONTROL_MODE_SET_MODE_AUTO_V2;
+ break;
+ default:
+ TEST_ABORT();
+ }
+
+ set_supported_modes(supported_modes);
+
+ uint8_t frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_MODE,
+ HUMIDITY_CONTROL_MODE_REPORT,
+ expected_humidity_control_mode};
+
+ sl_status_t expected_status
+ = happy_case ? SL_STATUS_OK : SL_STATUS_NOT_SUPPORTED;
+ TEST_ASSERT_EQUAL(expected_status,
+ handler.control_handler(&info, frame, sizeof(frame)));
+
+ humidity_control_mode_t reported_humidity_control_mode = 0;
+ sl_status_t reported_get_status = attribute_store_get_child_reported(
+ endpoint_id_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE,
+ &reported_humidity_control_mode,
+ sizeof(reported_humidity_control_mode));
+
+ expected_status = happy_case ? SL_STATUS_OK : SL_STATUS_FAIL;
+ // Test if value is defined or not
+ TEST_ASSERT_EQUAL(expected_status, reported_get_status);
+ if (happy_case) {
+ TEST_ASSERT_EQUAL_MESSAGE(
+ expected_humidity_control_mode,
+ reported_humidity_control_mode,
+ "Humidity control mode should be equal to reported one");
+ } else {
+ // Test version mismatch even if supported says ok
+ switch (version) {
+ case 1:
+ supported_modes = 0b00001111;
+ // Not supported in v1
+ expected_humidity_control_mode = HUMIDITY_CONTROL_MODE_SET_MODE_AUTO_V2;
+ break;
+ case 2:
+ supported_modes = 0b00011111;
+ // Not supported in v2
+ expected_humidity_control_mode = 0x04;
+ break;
+ default:
+ TEST_ABORT();
+ }
+ set_supported_modes(supported_modes);
+
+ uint8_t frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_MODE,
+ HUMIDITY_CONTROL_MODE_REPORT,
+ expected_humidity_control_mode};
+
+ TEST_ASSERT_EQUAL_MESSAGE(
+ SL_STATUS_NOT_SUPPORTED,
+ handler.control_handler(&info, frame, sizeof(frame)),
+ "Report should return SL_STATUS_NOT_SUPPORTED for version mismatch");
+
+ reported_get_status = attribute_store_get_child_reported(
+ endpoint_id_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE,
+ &reported_humidity_control_mode,
+ sizeof(reported_humidity_control_mode));
+
+ TEST_ASSERT_EQUAL_MESSAGE(SL_STATUS_FAIL,
+ reported_get_status,
+ "ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_"
+ "CURRENT_MODE should not have a value");
+ }
+}
+
+void helper_humidity_control_mode_set(zwave_cc_version_t version,
+ bool happy_case)
+{
+ TEST_ASSERT_NOT_NULL(current_expected_humidity_control_mode_set);
+ set_version(version);
+
+ attribute_store_node_t current_mode_node
+ = attribute_store_get_first_child_by_type(
+ endpoint_id_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE);
+
+ // Set supported mode based on the happy case flag
+ // If not happy case, no supported mode
+ humidity_control_supported_modes_t supported_modes;
+ humidity_control_mode_t expected_humidity_control_mode;
+ switch (version) {
+ case 1:
+ supported_modes = happy_case ? 0b00000110 : 0b00000000;
+ expected_humidity_control_mode
+ = HUMIDITY_CONTROL_MODE_SET_MODE_DEHUMIDIFY;
+ break;
+ case 2:
+ supported_modes = happy_case ? 0b00001110 : 0b00000000;
+ expected_humidity_control_mode = HUMIDITY_CONTROL_MODE_SET_MODE_AUTO_V2;
+ break;
+ default:
+ TEST_ABORT();
+ }
+ set_supported_modes(supported_modes);
+ set_current_mode(expected_humidity_control_mode);
+
+ // Call set
+ sl_status_t reported_set_status
+ = current_expected_humidity_control_mode_set(current_mode_node,
+ received_frame,
+ &received_frame_size);
+
+ if (happy_case) {
+ TEST_ASSERT_EQUAL(SL_STATUS_OK, reported_set_status);
+ const uint8_t expected_frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_MODE,
+ HUMIDITY_CONTROL_MODE_SET,
+ expected_humidity_control_mode};
+ TEST_ASSERT_EQUAL(sizeof(expected_frame), received_frame_size);
+ TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_frame,
+ received_frame,
+ received_frame_size);
+ } else {
+ TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, reported_set_status);
+
+ // Test version mismatch even if supported says ok
+ switch (version) {
+ case 1:
+ supported_modes = 0b00001111;
+ // Not supported in v1
+ expected_humidity_control_mode = HUMIDITY_CONTROL_MODE_SET_MODE_AUTO_V2;
+ break;
+ case 2:
+ supported_modes = 0b00011111;
+ // Not supported in v2
+ expected_humidity_control_mode = 0x04;
+ break;
+ default:
+ TEST_ABORT();
+ }
+ set_supported_modes(supported_modes);
+ set_current_mode(expected_humidity_control_mode);
+
+ // Call set
+ reported_set_status
+ = current_expected_humidity_control_mode_set(current_mode_node,
+ received_frame,
+ &received_frame_size);
+ TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, reported_set_status);
+ }
+}
+////////////////////////////////////////////////////////////////////////////
+// Humidity Control Mode Supported
+////////////////////////////////////////////////////////////////////////////
+void test_humidity_control_mode_supported_get_happy_case()
+{
+ // Ask for a Get Command, should always be the same
+ TEST_ASSERT_NOT_NULL(supported_expected_humidity_control_modes_get);
+ supported_expected_humidity_control_modes_get(0,
+ received_frame,
+ &received_frame_size);
+ const uint8_t expected_frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_MODE,
+ HUMIDITY_CONTROL_MODE_SUPPORTED_GET};
+ TEST_ASSERT_EQUAL(sizeof(expected_frame), received_frame_size);
+ TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_frame,
+ received_frame,
+ received_frame_size);
+}
+
+void test_humidity_control_mode_supported_report_happy_case()
+{
+ zwave_controller_connection_info_t info = {};
+ info.remote.node_id = node_id;
+ info.remote.endpoint_id = endpoint_id;
+ info.local.is_multicast = false;
+
+ humidity_control_supported_modes_t expected_supported_modes = 0b00000110;
+
+ uint8_t frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_MODE,
+ HUMIDITY_CONTROL_MODE_SUPPORTED_REPORT,
+ expected_supported_modes};
+
+ // test with invalid frame
+ TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED,
+ handler.control_handler(&info, NULL, 0));
+
+ // test with valid frame
+ TEST_ASSERT_EQUAL(SL_STATUS_OK,
+ handler.control_handler(&info, frame, sizeof(frame)));
+
+ humidity_control_supported_modes_t reported_supported_modes;
+ sl_status_t reported_status = attribute_store_get_child_reported(
+ endpoint_id_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES,
+ &reported_supported_modes,
+ sizeof(reported_supported_modes));
+ TEST_ASSERT_EQUAL(SL_STATUS_OK,reported_status);
+ TEST_ASSERT_EQUAL(expected_supported_modes,reported_supported_modes);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
+// Humidity Control Mode Get/Set/Report
+////////////////////////////////////////////////////////////////////////////
+void test_humidity_control_mode_get_happy_case()
+{
+ // Ask for a Get Command, should always be the same
+ TEST_ASSERT_NOT_NULL(current_expected_humidity_control_mode_get);
+ current_expected_humidity_control_mode_get(0,
+ received_frame,
+ &received_frame_size);
+ const uint8_t expected_frame[]
+ = {COMMAND_CLASS_HUMIDITY_CONTROL_MODE, HUMIDITY_CONTROL_MODE_GET};
+ TEST_ASSERT_EQUAL(sizeof(expected_frame), received_frame_size);
+ TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_frame,
+ received_frame,
+ received_frame_size);
+}
+
+void test_humidity_control_mode_report_v1_happy_case()
+{
+ helper_humidity_control_mode_report(HUMIDITY_CONTROL_MODE_VERSION, true);
+}
+
+void test_humidity_control_mode_report_v2_happy_case()
+{
+ helper_humidity_control_mode_report(HUMIDITY_CONTROL_MODE_VERSION_V2, true);
+}
+
+void test_humidity_control_mode_report_v1_version_and_supported_mismatch()
+{
+ helper_humidity_control_mode_report(HUMIDITY_CONTROL_MODE_VERSION, false);
+}
+
+void test_humidity_control_mode_report_v2_version_and_supported_mismatch()
+{
+ helper_humidity_control_mode_report(HUMIDITY_CONTROL_MODE_VERSION_V2, false);
+}
+
+void test_humidity_control_mode_set_v1_happy_case()
+{
+ helper_humidity_control_mode_set(HUMIDITY_CONTROL_MODE_VERSION, true);
+}
+
+void test_humidity_control_mode_set_v2_happy_case()
+{
+ helper_humidity_control_mode_set(HUMIDITY_CONTROL_MODE_VERSION_V2, true);
+}
+
+void test_humidity_control_mode_set_v1_version_and_supported_mismatch()
+{
+ helper_humidity_control_mode_set(HUMIDITY_CONTROL_MODE_VERSION, false);
+}
+
+void test_humidity_control_mode_set_v2_version_and_supported_mismatch()
+{
+ helper_humidity_control_mode_set(HUMIDITY_CONTROL_MODE_VERSION_V2, false);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Attribute creation
+////////////////////////////////////////////////////////////////////////////
+void test_attribute_creation_happy_case()
+{
+ attribute_store_type_t testing_types[]
+ = {ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE};
+ const int testing_types_count = 2;
+
+ for (int i = 0; i < testing_types_count; i++) {
+ attribute_store_node_t current_testing_node
+ = attribute_store_get_first_child_by_type(endpoint_id_node,
+ testing_types[i]);
+ TEST_ASSERT_EQUAL(ATTRIBUTE_STORE_INVALID_NODE, current_testing_node);
+ }
+
+ // Trigger version attribute that creates those attributes
+ set_version(1);
+
+ for (int i = 0; i < testing_types_count; i++) {
+ attribute_store_node_t current_testing_node
+ = attribute_store_get_first_child_by_type(endpoint_id_node,
+ testing_types[i]);
+ TEST_ASSERT_NOT_EQUAL(ATTRIBUTE_STORE_INVALID_NODE, current_testing_node);
+ }
+}
\ No newline at end of file
diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_operating_state_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_operating_state_test.c
new file mode 100644
index 0000000000..cca8833b7b
--- /dev/null
+++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_operating_state_test.c
@@ -0,0 +1,192 @@
+/******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+
+#include "zwave_command_class_humidity_control_operating_state.h"
+#include "zwave_command_class_humidity_control_types.h"
+#include "zwave_command_classes_utils.h"
+#include "unity.h"
+
+// Generic includes
+#include
+
+// Includes from other components
+#include "datastore.h"
+#include "attribute_store.h"
+#include "attribute_store_helper.h"
+#include "attribute_store_fixt.h"
+#include "zpc_attribute_store_type_registration.h"
+
+// Interface includes
+#include "attribute_store_defined_attribute_types.h"
+#include "ZW_classcmd.h"
+#include "zwave_utils.h"
+#include "zwave_controller_types.h"
+
+// Test helpers
+#include "zpc_attribute_store_test_helper.h"
+
+// Mock includes
+#include "attribute_resolver_mock.h"
+#include "zpc_attribute_resolver_mock.h"
+#include "zwave_command_handler_mock.h"
+#include "dotdot_mqtt_mock.h"
+#include "dotdot_mqtt_generated_commands_mock.h"
+
+static zwave_command_handler_t handler = {};
+
+static attribute_resolver_function_t current_humidity_control_state_get = NULL;
+
+// Buffer for frame
+static uint8_t received_frame[255] = {};
+static uint16_t received_frame_size = 0;
+
+// Stub functions
+static sl_status_t
+ attribute_resolver_register_rule_stub(attribute_store_type_t node_type,
+ attribute_resolver_function_t set_func,
+ attribute_resolver_function_t get_func,
+ int cmock_num_calls)
+{
+ if (
+ node_type
+ == ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_CURRENT_STATE) {
+ TEST_ASSERT_NULL(set_func);
+ TEST_ASSERT_NOT_NULL(get_func);
+ current_humidity_control_state_get = get_func;
+ }
+
+ return SL_STATUS_OK;
+}
+
+static sl_status_t zwave_command_handler_register_handler_stub(
+ zwave_command_handler_t new_command_class_handler, int cmock_num_calls)
+{
+ handler = new_command_class_handler;
+
+ TEST_ASSERT_EQUAL(ZWAVE_CONTROLLER_ENCAPSULATION_NONE,
+ handler.minimal_scheme);
+ TEST_ASSERT_EQUAL(COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE,
+ handler.command_class);
+ TEST_ASSERT_EQUAL(1, handler.version);
+ TEST_ASSERT_NOT_NULL(handler.control_handler);
+ TEST_ASSERT_NULL(handler.support_handler);
+ TEST_ASSERT_FALSE(handler.manual_security_validation);
+
+ return SL_STATUS_OK;
+}
+
+/// Setup the test suite (called once before all test_xxx functions are called)
+void suiteSetUp()
+{
+ datastore_init(":memory:");
+ attribute_store_init();
+ zpc_attribute_store_register_known_attribute_types();
+}
+
+/// Teardown the test suite (called once after all test_xxx functions are called)
+int suiteTearDown(int num_failures)
+{
+ attribute_store_teardown();
+ datastore_teardown();
+ return num_failures;
+}
+
+/// Called before each and every test
+void setUp()
+{
+ zpc_attribute_store_test_helper_create_network();
+
+ // Unset previous definition get/set functions
+ current_humidity_control_state_get = NULL;
+ memset(received_frame, 0, sizeof(received_frame));
+ received_frame_size = 0;
+ // Unset previous definition of handler
+ memset(&handler, 0, sizeof(zwave_command_handler_t));
+
+ // Resolution functions
+ attribute_resolver_register_rule_Stub(&attribute_resolver_register_rule_stub);
+ // Handler registration
+ zwave_command_handler_register_handler_Stub(
+ &zwave_command_handler_register_handler_stub);
+ // Call init
+ TEST_ASSERT_EQUAL(
+ SL_STATUS_OK,
+ zwave_command_class_humidity_control_operating_state_init());
+}
+
+/// Called after each and every test
+void tearDown() {}
+
+////////////////////////////////////////////////////////////////////////////
+// HELPERS
+////////////////////////////////////////////////////////////////////////////
+// Happy case : not setting reserved bit to 1
+void helper_humidity_control_state_report(
+ humidity_control_operating_state_t expected_state, bool happy_case)
+{
+ uint8_t happy_case_mask = happy_case ? 0x00 : 0xF0;
+
+ const uint8_t frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE,
+ HUMIDITY_CONTROL_OPERATING_STATE_REPORT,
+ expected_state | happy_case_mask};
+
+ zwave_controller_connection_info_t info = {};
+ info.remote.node_id = node_id;
+ info.remote.endpoint_id = endpoint_id;
+ info.local.is_multicast = false;
+
+ TEST_ASSERT_EQUAL(SL_STATUS_OK,
+ handler.control_handler(&info, frame, sizeof(frame)));
+
+ attribute_store_node_t humidity_control_state_node
+ = attribute_store_get_node_child_by_type(
+ endpoint_id_node,
+ ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_CURRENT_STATE,
+ 0);
+
+ TEST_ASSERT_NOT_EQUAL(ATTRIBUTE_STORE_INVALID_NODE,
+ humidity_control_state_node);
+
+ humidity_control_operating_state_t reported_state = 0x00;
+ attribute_store_get_reported(humidity_control_state_node,
+ &reported_state,
+ sizeof(reported_state));
+ TEST_ASSERT_EQUAL(expected_state, reported_state);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// THERMOSTAT_FAN_STATE
+////////////////////////////////////////////////////////////////////////////
+void test_humidity_control_operating_state_get_happy_case()
+{
+ // Ask for a Get Command, should always be the same
+ TEST_ASSERT_NOT_NULL(current_humidity_control_state_get);
+ current_humidity_control_state_get(0, received_frame, &received_frame_size);
+ const uint8_t expected_frame[]
+ = {COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE,
+ HUMIDITY_CONTROL_OPERATING_STATE_GET};
+ TEST_ASSERT_EQUAL(sizeof(expected_frame), received_frame_size);
+ TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_frame,
+ received_frame,
+ received_frame_size);
+}
+
+void test_humidity_control_operating_state_report_happy_case()
+{
+ helper_humidity_control_state_report(0x02, true);
+}
+
+void test_humidity_control_operating_state_report_off_bit()
+{
+ helper_humidity_control_state_report(0x03, false);
+}
\ No newline at end of file
diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_setpoint_test.cpp b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_setpoint_test.cpp
new file mode 100644
index 0000000000..204824fd22
--- /dev/null
+++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_setpoint_test.cpp
@@ -0,0 +1,940 @@
+/******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ ******************************************************************************
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ *****************************************************************************/
+#include
+#include "workaround_for_test.hpp"
+
+extern "C" {
+#include "zwave_command_class_humidity_control_setpoint.h"
+#include "zwave_command_class_humidity_control_types.h"
+#include "zwave_command_classes_utils.h"
+#include "unity.h"
+
+// Generic includes
+#include
+
+// Includes from other components
+#include "datastore.h"
+#include "attribute_store.h"
+#include "attribute_store_helper.h"
+#include "attribute_store_fixt.h"
+#include "zpc_attribute_store_type_registration.h"
+
+// Interface includes
+#include "attribute_store_defined_attribute_types.h"
+#include "ZW_classcmd.h"
+#include "zwave_utils.h"
+#include "zwave_controller_types.h"
+
+// Test helpers
+#include "zpc_attribute_store_test_helper.h"
+
+// Mock includes
+#include "attribute_resolver_mock.h"
+#include "zpc_attribute_resolver_mock.h"
+#include "zwave_command_handler_mock.h"
+#include "dotdot_mqtt_mock.h"
+#include "dotdot_mqtt_generated_commands_mock.h"
+
+#define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_##type
+
+constexpr uint8_t PRECISION_SHIFT = 5;
+constexpr uint8_t SCALE_SHIFT = 3;
+
+static zwave_command_handler_t handler = {};
+
+static attribute_resolver_function_t supported_types_get = NULL;
+static attribute_resolver_function_t capabilities_get = NULL;
+static attribute_resolver_function_t setpoint_get = NULL;
+static attribute_resolver_function_t setpoint_set = NULL;
+// Buffer for frame
+static uint8_t received_frame[255] = {};
+static uint16_t received_frame_size = 0;
+// Custom types
+enum humidity_control_setpoint_value_type {
+ SETPOINT_CURRENT_VALUE,
+ SETPOINT_MIN_VALUE,
+ SETPOINT_MAX_VALUE
+};
+enum set_bytes { SET_1BYTES = 1, SET_2BYTES = 2, SET_4BYTES = 4 };
+
+/////////////////////////////////////////////////////
+// HELPERS
+/////////////////////////////////////////////////////
+attribute_store_node_t create_type_node(humidity_control_setpoint_type_t type)
+{
+ attribute_store_node_t type_node = attribute_store_emplace(endpoint_id_node,
+ ATTRIBUTE(TYPE),
+ &type,
+ sizeof(type));
+
+ TEST_ASSERT_NOT_EQUAL_MESSAGE(ATTRIBUTE_STORE_INVALID_NODE,
+ type_node,
+ "Should be able to crate ATTRIBUTE(TYPE)");
+ return type_node;
+}
+
+void helper_test_type_values(
+ enum humidity_control_setpoint_value_type value_type,
+ attribute_store_node_t value_node,
+ humidity_control_setpoint_precision_t precision,
+ humidity_control_setpoint_scale_t scale,
+ humidity_control_setpoint_size_t size,
+ uint8_t *value_buffer)
+{
+ // Determine used types
+ attribute_store_type_t value_scale_type;
+ attribute_store_type_t value_precision_type;
+ switch (value_type) {
+ case SETPOINT_CURRENT_VALUE:
+ printf("Testing current value type\n");
+ value_scale_type = ATTRIBUTE(VALUE_SCALE);
+ value_precision_type = ATTRIBUTE(VALUE_PRECISION);
+ break;
+ case SETPOINT_MIN_VALUE:
+ printf("Testing min value type\n");
+ value_scale_type = ATTRIBUTE(MIN_VALUE_SCALE);
+ value_precision_type = ATTRIBUTE(MIN_VALUE_PRECISION);
+ break;
+ case SETPOINT_MAX_VALUE:
+ printf("Testing max value type\n");
+ value_scale_type = ATTRIBUTE(MAX_VALUE_SCALE);
+ value_precision_type = ATTRIBUTE(MAX_VALUE_PRECISION);
+ break;
+ default:
+ TEST_ABORT();
+ }
+
+ // Check Value
+ humidity_control_setpoint_value_t reported_value, expected_value;
+ attribute_store_get_reported(value_node,
+ &reported_value,
+ sizeof(reported_value));
+
+ expected_value = get_signed_value_from_frame_and_size(&value_buffer[0], size);
+
+ TEST_ASSERT_EQUAL_MESSAGE(expected_value,
+ reported_value,
+ "VALUE is incorrect");
+
+ humidity_control_setpoint_scale_t reported_scale;
+ sl_status_t status
+ = attribute_store_get_child_reported(value_node,
+ value_scale_type,
+ &reported_scale,
+ sizeof(reported_scale));
+ TEST_ASSERT_EQUAL_MESSAGE(
+ SL_STATUS_OK,
+ status,
+ "Should have access to reported value of SCALE attribute");
+
+ TEST_ASSERT_EQUAL_MESSAGE(scale, reported_scale, "SCALE value is incorrect");
+
+ humidity_control_setpoint_precision_t reported_precision;
+ status = attribute_store_get_child_reported(value_node,
+ value_precision_type,
+ &reported_precision,
+ sizeof(reported_precision));
+ TEST_ASSERT_EQUAL_MESSAGE(
+ SL_STATUS_OK,
+ status,
+ "Should have access to reported value of PRECISION attribute");
+
+ TEST_ASSERT_EQUAL_MESSAGE(precision,
+ reported_precision,
+ "PRECISION value is incorrect");
+}
+
+// Return value node
+attribute_store_node_t
+ create_setpoint_structure(humidity_control_setpoint_type_t type,
+ humidity_control_setpoint_value_t current_value,
+ humidity_control_setpoint_precision_t precision,
+ humidity_control_setpoint_scale_t scale,
+ humidity_control_setpoint_value_t min_value,
+ humidity_control_setpoint_value_t max_value)
+{
+ attribute_store_node_t type_node = create_type_node(type);
+
+ auto min_value_node = attribute_store_emplace(type_node,
+ ATTRIBUTE(MIN_VALUE),
+ &min_value,
+ sizeof(min_value));
+ attribute_store_emplace(min_value_node,
+ ATTRIBUTE(MIN_VALUE_PRECISION),
+ &precision,
+ sizeof(precision));
+ auto max_value_node = attribute_store_emplace(type_node,
+ ATTRIBUTE(MAX_VALUE),
+ &max_value,
+ sizeof(max_value));
+ attribute_store_emplace(max_value_node,
+ ATTRIBUTE(MAX_VALUE_PRECISION),
+ &precision,
+ sizeof(precision));
+
+ attribute_store_node_t value_node
+ = attribute_store_emplace_desired(type_node,
+ ATTRIBUTE(VALUE),
+ ¤t_value,
+ sizeof(current_value));
+ attribute_store_emplace(value_node,
+ ATTRIBUTE(VALUE_PRECISION),
+ &precision,
+ sizeof(precision));
+ attribute_store_emplace(value_node,
+ ATTRIBUTE(VALUE_SCALE),
+ &scale,
+ sizeof(scale));
+
+ return value_node;
+}
+
+uint8_t
+ helper_get_attribute_field(humidity_control_setpoint_precision_t precision,
+ humidity_control_setpoint_scale_t scale,
+ humidity_control_setpoint_size_t size)
+{
+ return (precision << PRECISION_SHIFT) | (scale << SCALE_SHIFT) | size;
+}
+
+std::vector explode_value(uint8_t size,
+ humidity_control_setpoint_value_t value)
+{
+ std::vector exploded_value;
+ for (uint8_t i = size; i > 0; i--) {
+ uint8_t offset = i - 1;
+ uint8_t shift = 8 * offset;
+ uint32_t bitmask = 0xFF << shift;
+
+ uint8_t value_8bit = (value & bitmask) >> shift;
+ exploded_value.push_back(value_8bit);
+ }
+
+ return exploded_value;
+}
+
+void helper_set_setpoint(enum set_bytes bytes_count, bool happy_case)
+{
+ // Ask for a Get Command, should always be the same
+ TEST_ASSERT_NOT_NULL(setpoint_set);
+ // Not supported with invalid node
+ TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED,
+ setpoint_set(0, received_frame, &received_frame_size));
+
+ humidity_control_setpoint_type_t type
+ = HUMIDITY_CONTROL_SETPOINT_GET_SETPOINT_TYPE_HUMIDIFIER;
+ humidity_control_setpoint_value_t current_value = 50;
+ humidity_control_setpoint_precision_t precision = 3;
+ humidity_control_setpoint_scale_t scale = 1;
+ humidity_control_setpoint_value_t min_value = -100;
+ humidity_control_setpoint_value_t max_value = 100;
+ std::vector expected_value;
+
+ switch (bytes_count) {
+ case SET_1BYTES:
+ current_value = -50;
+ precision = 3;
+ scale = 1;
+ min_value = happy_case ? -100 : -10;
+ max_value = 10;
+ break;
+ case SET_2BYTES:
+ current_value = INT16_MAX - 2;
+ precision = 4;
+ scale = 1;
+ min_value = -100;
+ max_value = happy_case ? INT16_MAX : 10;
+ break;
+ case SET_4BYTES:
+ current_value = INT32_MAX - 2;
+ precision = 1;
+ scale = 0;
+ min_value = -100;
+ max_value = happy_case ? INT32_MAX : 10;
+ break;
+ default:
+ TEST_ABORT();
+ }
+
+ // Transform 32 bit value into chunk of 8 bit values
+ expected_value = explode_value(bytes_count, current_value);
+
+ attribute_store_node_t value_node = create_setpoint_structure(type,
+ current_value,
+ precision,
+ scale,
+ min_value,
+ max_value);
+
+ TEST_ASSERT_EQUAL(
+ happy_case ? SL_STATUS_OK : SL_STATUS_NOT_SUPPORTED,
+ setpoint_set(value_node, received_frame, &received_frame_size));
+
+ if (happy_case) {
+ std::vector expected_frame {
+ COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT,
+ HUMIDITY_CONTROL_SETPOINT_SET,
+ type,
+ helper_get_attribute_field(precision, scale, bytes_count)};
+
+ for (uint8_t value: expected_value) {
+ expected_frame.emplace_back(value);
+ }
+
+ TEST_ASSERT_EQUAL(expected_frame.size(), received_frame_size);
+ TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_frame.data(),
+ received_frame,
+ received_frame_size);
+ }
+}
+
+void helper_report_setpoint(enum set_bytes bytes_count, bool happy_case)
+{
+ humidity_control_setpoint_type_t expected_type
+ = HUMIDITY_CONTROL_SETPOINT_REPORT_SETPOINT_TYPE_HUMIDIFIER;
+
+ zwave_controller_connection_info_t info = {};
+ info.remote.node_id = node_id;
+ info.remote.endpoint_id = endpoint_id;
+ info.local.is_multicast = false;
+
+ attribute_store_node_t value_node;
+
+ humidity_control_setpoint_precision_t precision;
+ humidity_control_setpoint_scale_t scale;
+ humidity_control_setpoint_value_t value;
+
+ humidity_control_setpoint_size_t size = bytes_count;
+
+ switch (size) {
+ case SET_1BYTES:
+ precision = 2;
+ scale = 1;
+ value = -40;
+ value_node = create_setpoint_structure(expected_type,
+ 0,
+ precision,
+ 0,
+ happy_case ? -420 : 20,
+ 500);
+ break;
+ case SET_2BYTES:
+ precision = 5;
+ scale = 1;
+ value = INT16_MIN + 5;
+ value_node = create_setpoint_structure(expected_type,
+ 0,
+ precision,
+ 0,
+ happy_case ? INT16_MIN : 0,
+ 50);
+ break;
+ break;
+ case SET_4BYTES:
+ precision = 1;
+ scale = 0;
+ value = INT16_MAX + 3256;
+ value_node
+ = create_setpoint_structure(expected_type,
+ 0,
+ precision,
+ 0,
+ happy_case ? INT16_MAX : INT32_MAX - 1,
+ INT32_MAX);
+ break;
+ }
+
+ std::vector expected_frame {
+ COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT,
+ HUMIDITY_CONTROL_SETPOINT_REPORT,
+ expected_type,
+ helper_get_attribute_field(precision, scale, size)};
+
+ for (uint8_t field: explode_value(size, value)) {
+ expected_frame.emplace_back(field);
+ }
+
+ // Should be ok
+ TEST_ASSERT_EQUAL_MESSAGE(happy_case ? SL_STATUS_OK : SL_STATUS_NOT_SUPPORTED,
+ handler.control_handler(&info,
+ expected_frame.data(),
+ expected_frame.size()),
+ "Report handler returned incorrect value");
+
+ if (happy_case) {
+ humidity_control_setpoint_value_t reported_value;
+ attribute_store_get_reported(value_node,
+ &reported_value,
+ sizeof(reported_value));
+ TEST_ASSERT_EQUAL_MESSAGE(
+ get_signed_value_from_frame_and_size(explode_value(size, value).data(),
+ size),
+ reported_value,
+ "Setpoint value is not correct");
+
+ humidity_control_setpoint_precision_t reported_precision;
+ attribute_store_get_child_reported(value_node,
+ ATTRIBUTE(VALUE_PRECISION),
+ &reported_precision,
+ sizeof(reported_precision));
+ TEST_ASSERT_EQUAL_MESSAGE(precision,
+ reported_precision,
+ "Precision is not correct");
+
+ humidity_control_setpoint_scale_t reported_scale;
+ attribute_store_get_child_reported(value_node,
+ ATTRIBUTE(VALUE_SCALE),
+ &reported_scale,
+ sizeof(reported_scale));
+ TEST_ASSERT_EQUAL_MESSAGE(scale, reported_scale, "Scale is not correct");
+ }
+}
+
+/////////////////////////////////////////////////////
+// Test case
+/////////////////////////////////////////////////////
+// Stub functions
+static sl_status_t
+ attribute_resolver_register_rule_stub(attribute_store_type_t node_type,
+ attribute_resolver_function_t set_func,
+ attribute_resolver_function_t get_func,
+ int cmock_num_calls)
+{
+ if (node_type == ATTRIBUTE(SUPPORTED_TYPES)) {
+ TEST_ASSERT_NULL(set_func);
+ TEST_ASSERT_NOT_NULL(get_func);
+ supported_types_get = get_func;
+ } else if (node_type == ATTRIBUTE(MIN_VALUE)) {
+ TEST_ASSERT_NULL(set_func);
+ TEST_ASSERT_NOT_NULL(get_func);
+ capabilities_get = get_func;
+ } else if (node_type == ATTRIBUTE(VALUE)) {
+ TEST_ASSERT_NOT_NULL(get_func);
+ TEST_ASSERT_NOT_NULL(set_func);
+ setpoint_get = get_func;
+ setpoint_set = set_func;
+ }
+
+ return SL_STATUS_OK;
+}
+
+static sl_status_t zwave_command_handler_register_handler_stub(
+ zwave_command_handler_t new_command_class_handler, int cmock_num_calls)
+{
+ handler = new_command_class_handler;
+
+ TEST_ASSERT_EQUAL(ZWAVE_CONTROLLER_ENCAPSULATION_NONE,
+ handler.minimal_scheme);
+ TEST_ASSERT_EQUAL(COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT,
+ handler.command_class);
+ TEST_ASSERT_EQUAL(2, handler.version);
+ TEST_ASSERT_NOT_NULL(handler.control_handler);
+ TEST_ASSERT_NULL(handler.support_handler);
+ TEST_ASSERT_FALSE(handler.manual_security_validation);
+
+ return SL_STATUS_OK;
+}
+
+/// Setup the test suite (called once before all test_xxx functions are called)
+void suiteSetUp()
+{
+ datastore_init(":memory:");
+ attribute_store_init();
+ zpc_attribute_store_register_known_attribute_types();
+}
+
+/// Teardown the test suite (called once after all test_xxx functions are called)
+int suiteTearDown(int num_failures)
+{
+ attribute_store_teardown();
+ datastore_teardown();
+ return num_failures;
+}
+
+/// Called before each and every test
+void setUp()
+{
+ zpc_attribute_store_test_helper_create_network();
+
+ // Unset previous definition get/set functions
+ supported_types_get = NULL;
+ setpoint_get = NULL;
+ setpoint_set = NULL;
+ capabilities_get = NULL;
+ memset(received_frame, 0, sizeof(received_frame));
+ received_frame_size = 0;
+ // Unset previous definition of handler
+ memset(&handler, 0, sizeof(zwave_command_handler_t));
+
+ // Resolution functions
+ attribute_resolver_register_rule_Stub(&attribute_resolver_register_rule_stub);
+ // Handler registration
+ zwave_command_handler_register_handler_Stub(
+ &zwave_command_handler_register_handler_stub);
+ // Call init
+ TEST_ASSERT_EQUAL(SL_STATUS_OK,
+ zwave_command_class_humidity_control_setpoint_init());
+}
+
+/// Called after each and every test
+void tearDown() {}
+
+////////////////////////////////////////////////////////////////////////////
+// Setpoint Set/Get/Report
+////////////////////////////////////////////////////////////////////////////
+void test_humidity_control_setpoint_get_happy_case()
+{
+ // Ask for a Get Command, should always be the same
+ TEST_ASSERT_NOT_NULL(setpoint_get);
+ // Not supported with invalid node
+ TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED,
+ setpoint_get(0, received_frame, &received_frame_size));
+
+ humidity_control_setpoint_type_t expected_type
+ = HUMIDITY_CONTROL_SETPOINT_GET_SETPOINT_TYPE_HUMIDIFIER;
+ attribute_store_node_t type_node = create_type_node(expected_type);
+
+ // This is the attribute that trigger the setpoint_get
+ attribute_store_node_t value_node
+ = attribute_store_add_node(ATTRIBUTE(VALUE), type_node);
+
+ TEST_ASSERT_EQUAL(
+ SL_STATUS_OK,
+ setpoint_get(value_node, received_frame, &received_frame_size));
+
+ const uint8_t expected_frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT,
+ HUMIDITY_CONTROL_SETPOINT_GET,
+ expected_type};
+ TEST_ASSERT_EQUAL(sizeof(expected_frame), received_frame_size);
+ TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_frame,
+ received_frame,
+ received_frame_size);
+}
+
+void test_humidity_control_setpoint_set_1bytes_happy_case()
+{
+ helper_set_setpoint(SET_1BYTES, true);
+}
+
+void test_humidity_control_setpoint_set_2bytes_happy_case()
+{
+ helper_set_setpoint(SET_2BYTES, true);
+}
+
+void test_humidity_control_setpoint_set_4bytes_happy_case()
+{
+ helper_set_setpoint(SET_4BYTES, true);
+}
+
+void test_humidity_control_setpoint_set_1bytes_out_of_bounds()
+{
+ helper_set_setpoint(SET_1BYTES, false);
+}
+
+void test_humidity_control_setpoint_set_2bytes_out_of_bounds()
+{
+ helper_set_setpoint(SET_2BYTES, false);
+}
+
+void test_humidity_control_setpoint_set_4bytes_out_of_bounds()
+{
+ helper_set_setpoint(SET_4BYTES, false);
+}
+
+void test_humidity_control_setpoint_report_1bytes_happy_case()
+{
+ helper_report_setpoint(SET_1BYTES, true);
+}
+
+void test_humidity_control_setpoint_report_2bytes_happy_case()
+{
+ helper_report_setpoint(SET_2BYTES, true);
+}
+
+void test_humidity_control_setpoint_report_4bytes_happy_case()
+{
+ helper_report_setpoint(SET_4BYTES, true);
+}
+
+void test_humidity_control_setpoint_report_1bytes_out_of_bounds()
+{
+ helper_report_setpoint(SET_1BYTES, false);
+}
+void test_humidity_control_setpoint_report_2bytes_out_of_bounds()
+{
+ helper_report_setpoint(SET_2BYTES, false);
+}
+void test_humidity_control_setpoint_report_4bytes_out_of_bounds()
+{
+ helper_report_setpoint(SET_4BYTES, false);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Capabilities types Get/Report
+////////////////////////////////////////////////////////////////////////////
+void test_humidity_control_setpoint_capabilities_get_happy_case()
+{
+ // Ask for a Get Command, should always be the same
+ TEST_ASSERT_NOT_NULL(capabilities_get);
+ // Not supported with invalid node
+ TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED,
+ capabilities_get(0, received_frame, &received_frame_size));
+
+ humidity_control_setpoint_type_t expected_type
+ = HUMIDITY_CONTROL_SETPOINT_GET_SETPOINT_TYPE_HUMIDIFIER;
+ attribute_store_node_t type_node
+ = attribute_store_add_node(ATTRIBUTE(TYPE), endpoint_id_node);
+
+ attribute_store_set_reported(type_node,
+ &expected_type,
+ sizeof(expected_type));
+
+ // This is the attribute that trigger the capabilities_get
+ attribute_store_node_t min_node
+ = attribute_store_add_node(ATTRIBUTE(MIN_VALUE), type_node);
+
+ TEST_ASSERT_EQUAL(
+ SL_STATUS_OK,
+ capabilities_get(min_node, received_frame, &received_frame_size));
+
+ const uint8_t expected_frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT,
+ HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_GET,
+ expected_type};
+ TEST_ASSERT_EQUAL(sizeof(expected_frame), received_frame_size);
+ TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_frame,
+ received_frame,
+ received_frame_size);
+}
+
+void test_humidity_control_setpoint_capabilities_report_happy_case()
+{
+ humidity_control_setpoint_type_t expected_type
+ = HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT_SETPOINT_TYPE_DEHUMIDIFIER_V2;
+
+ zwave_controller_connection_info_t info = {};
+ info.remote.node_id = node_id;
+ info.remote.endpoint_id = endpoint_id;
+ info.local.is_multicast = false;
+
+ humidity_control_setpoint_precision_t precision_min = 2;
+ humidity_control_setpoint_scale_t scale_min = 0;
+ humidity_control_setpoint_size_t size_min = 2;
+ uint8_t value_min[] = {12, 13};
+
+ humidity_control_setpoint_precision_t precision_max = 4;
+ humidity_control_setpoint_scale_t scale_max = 1;
+ humidity_control_setpoint_size_t size_max = 4;
+ uint8_t value_max[] = {14, 15, 16, 17};
+
+ const uint8_t frame[] = {
+ COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT,
+ HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT,
+ (uint8_t)(0b11110000
+ | expected_type), // This test if we properly ignore the first 4 bits
+ helper_get_attribute_field(precision_min, scale_min, size_min),
+ value_min[0],
+ value_min[1],
+ helper_get_attribute_field(precision_max, scale_max, size_max),
+ value_max[0],
+ value_max[1],
+ value_max[2],
+ value_max[3]};
+
+ // Type not found
+ TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED,
+ handler.control_handler(&info, frame, sizeof(frame)));
+
+ // Create type
+ attribute_store_node_t type_node = create_type_node(expected_type);
+
+ TEST_ASSERT_EQUAL(SL_STATUS_OK,
+ handler.control_handler(&info, frame, sizeof(frame)));
+
+ attribute_store_node_t min_node
+ = attribute_store_get_node_child_by_type(type_node,
+ ATTRIBUTE(MIN_VALUE),
+ 0);
+
+ attribute_store_node_t max_node
+ = attribute_store_get_node_child_by_type(type_node,
+ ATTRIBUTE(MAX_VALUE),
+ 0);
+
+ TEST_ASSERT_NOT_EQUAL_MESSAGE(ATTRIBUTE_STORE_INVALID_NODE,
+ min_node,
+ "Min value node should be defined");
+ TEST_ASSERT_NOT_EQUAL_MESSAGE(ATTRIBUTE_STORE_INVALID_NODE,
+ max_node,
+ "Max value node should be defined");
+
+ helper_test_type_values(SETPOINT_MIN_VALUE,
+ min_node,
+ precision_min,
+ scale_min,
+ size_min,
+ value_min);
+
+ helper_test_type_values(SETPOINT_MAX_VALUE,
+ max_node,
+ precision_max,
+ scale_max,
+ size_max,
+ value_max);
+}
+
+void test_humidity_control_setpoint_capabilities_report_fail_only_min()
+{
+ humidity_control_setpoint_type_t expected_type
+ = HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT_SETPOINT_TYPE_DEHUMIDIFIER_V2;
+
+ zwave_controller_connection_info_t info = {};
+ info.remote.node_id = node_id;
+ info.remote.endpoint_id = endpoint_id;
+ info.local.is_multicast = false;
+
+ uint8_t precision_min = 2;
+ uint8_t scale_min = 0;
+ uint8_t size_min = 2;
+ uint8_t value_min[] = {12, 13};
+
+ const uint8_t frame[]
+ = {COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT,
+ HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT,
+ expected_type,
+ helper_get_attribute_field(precision_min, scale_min, size_min),
+ value_min[0],
+ value_min[1]};
+
+ // Type not found
+ TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED,
+ handler.control_handler(&info, frame, sizeof(frame)));
+}
+
+void test_humidity_control_setpoint_capabilities_report_fail_incorrect_size_field()
+{
+ humidity_control_setpoint_type_t expected_type
+ = HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT_SETPOINT_TYPE_DEHUMIDIFIER_V2;
+
+ zwave_controller_connection_info_t info = {};
+ info.remote.node_id = node_id;
+ info.remote.endpoint_id = endpoint_id;
+ info.local.is_multicast = false;
+
+ uint8_t precision_min = 2;
+ uint8_t scale_min = 0;
+ uint8_t size_min = 12; // incorrect size
+ uint8_t value_min[] = {12, 13};
+
+ uint8_t precision_max = 4;
+ uint8_t scale_max = 1;
+ uint8_t size_max = 4;
+ uint8_t value_max[] = {14, 15, 16, 17};
+
+ const uint8_t frame[] = {
+ COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT,
+ HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT,
+ (uint8_t)(0b11110000
+ | expected_type), // This test if we properly ignore the first 4 bits
+ helper_get_attribute_field(precision_min, scale_min, size_min),
+ value_min[0],
+ value_min[1],
+ helper_get_attribute_field(precision_max, scale_max, size_max),
+ value_max[0],
+ value_max[1],
+ value_max[2],
+ value_max[3]};
+
+ // Type not found
+ TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED,
+ handler.control_handler(&info, frame, sizeof(frame)));
+}
+
+void test_humidity_control_setpoint_capabilities_report_fail_incorrect_frame_size()
+{
+ zwave_controller_connection_info_t info = {};
+ info.remote.node_id = node_id;
+ info.remote.endpoint_id = endpoint_id;
+ info.local.is_multicast = false;
+
+ const uint8_t frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT,
+ HUMIDITY_CONTROL_SETPOINT_CAPABILITIES_REPORT,
+ 12,
+ 13};
+ // Type not found
+ TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED,
+ handler.control_handler(&info, frame, sizeof(frame)));
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Supported types Get/Report
+////////////////////////////////////////////////////////////////////////////
+void test_humidity_control_setpoint_supported_types_get_happy_case()
+{
+ // Ask for a Get Command, should always be the same
+ TEST_ASSERT_NOT_NULL(supported_types_get);
+ TEST_ASSERT_EQUAL(
+ SL_STATUS_OK,
+ supported_types_get(0, received_frame, &received_frame_size));
+
+ const uint8_t expected_frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT,
+ HUMIDITY_CONTROL_SETPOINT_SUPPORTED_GET};
+ TEST_ASSERT_EQUAL(sizeof(expected_frame), received_frame_size);
+ TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_frame,
+ received_frame,
+ received_frame_size);
+}
+
+void test_humidity_control_setpoint_supported_types_report_happy_case()
+{
+ size_t expected_type_count = 3;
+ humidity_control_setpoint_supported_types_t expected_supported_types
+ = 0b00001110;
+
+ const uint8_t frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT,
+ HUMIDITY_CONTROL_SETPOINT_SUPPORTED_REPORT,
+ expected_supported_types};
+
+ zwave_controller_connection_info_t info = {};
+ info.remote.node_id = node_id;
+ info.remote.endpoint_id = endpoint_id;
+ info.local.is_multicast = false;
+
+ // Simulate previous node
+ create_type_node(0x0F);
+
+ TEST_ASSERT_EQUAL(SL_STATUS_OK,
+ handler.control_handler(&info, frame, sizeof(frame)));
+
+ humidity_control_setpoint_supported_types_t reported_supported_types;
+
+ sl_status_t status
+ = attribute_store_get_child_reported(endpoint_id_node,
+ ATTRIBUTE(SUPPORTED_TYPES),
+ &reported_supported_types,
+ sizeof(reported_supported_types));
+
+ TEST_ASSERT_EQUAL_MESSAGE(SL_STATUS_OK,
+ status,
+ "Should be able to get SUPPORTED_TYPES value");
+
+ TEST_ASSERT_EQUAL_MESSAGE(
+ expected_supported_types,
+ reported_supported_types,
+ "Supported type should be the same as in the report frame");
+
+ size_t type_count
+ = attribute_store_get_node_child_count_by_type(endpoint_id_node,
+ ATTRIBUTE(TYPE));
+
+ TEST_ASSERT_EQUAL_MESSAGE(expected_type_count,
+ type_count,
+ "TYPE node count is incorrect");
+
+ for (size_t i = 0; i < expected_type_count; i++) {
+ attribute_store_node_t node
+ = attribute_store_get_node_child_by_type(endpoint_id_node,
+ ATTRIBUTE(TYPE),
+ i);
+
+ humidity_control_setpoint_type_t reported_value;
+ sl_status_t status = attribute_store_get_reported(node,
+ &reported_value,
+ sizeof(reported_value));
+ TEST_ASSERT_EQUAL_MESSAGE(SL_STATUS_OK,
+ status,
+ "Should be able to get TYPE reported value");
+
+ TEST_ASSERT_EQUAL_MESSAGE(i + 1,
+ reported_value,
+ "Incorrect TYPE value set");
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Misc
+////////////////////////////////////////////////////////////////////////////
+void test_attribute_creation_happy_case()
+{
+ attribute_store_node_t supported_types_node
+ = attribute_store_get_first_child_by_type(endpoint_id_node,
+ ATTRIBUTE(SUPPORTED_TYPES));
+
+ TEST_ASSERT_EQUAL_MESSAGE(
+ ATTRIBUTE_STORE_INVALID_NODE,
+ supported_types_node,
+ "Supported type node shouldn't exist at this stage");
+
+ zwave_cc_version_t version = 1;
+ attribute_store_set_child_reported(endpoint_id_node,
+ ATTRIBUTE(VERSION),
+ &version,
+ sizeof(version));
+
+ supported_types_node
+ = attribute_store_get_first_child_by_type(endpoint_id_node,
+ ATTRIBUTE(SUPPORTED_TYPES));
+
+ TEST_ASSERT_NOT_EQUAL_MESSAGE(
+ ATTRIBUTE_STORE_INVALID_NODE,
+ supported_types_node,
+ "Supported type node should exist at this stage");
+}
+
+void test_scale_bounds()
+{
+ attribute_store_node_t type_node = create_type_node(2);
+
+ std::map
+ correspondence_table {{ATTRIBUTE(VALUE), ATTRIBUTE(VALUE_SCALE)},
+ {ATTRIBUTE(MIN_VALUE), ATTRIBUTE(MIN_VALUE_SCALE)},
+ {ATTRIBUTE(MAX_VALUE), ATTRIBUTE(MAX_VALUE_SCALE)}};
+
+ std::map scale_table;
+ // Create correspondence between parent node ID and scale attribute
+ for (auto &table_entry: correspondence_table) {
+ attribute_store_node_t parent_node
+ = attribute_store_add_node(table_entry.first, type_node);
+
+ scale_table[parent_node] = table_entry.second;
+ }
+
+ for (auto &scale: scale_table) {
+ humidity_control_setpoint_scale_t scale_value = 12;
+ printf("Testing scale attribute #%d\n", scale.second);
+ // Test at attribute creation
+ attribute_store_node_t scale_node
+ = attribute_store_emplace(scale.first,
+ scale.second,
+ &scale_value,
+ sizeof(scale_value));
+
+ attribute_store_get_reported(scale_node, &scale_value, sizeof(scale_value));
+
+ TEST_ASSERT_EQUAL_MESSAGE(
+ 0,
+ scale_value,
+ "Scale value should be equal to 0 if overflows (>1)");
+
+ // Test at attribute update
+ scale_value = 4;
+ attribute_store_set_reported(scale_node, &scale_value, sizeof(scale_value));
+
+ attribute_store_get_reported(scale_node, &scale_value, sizeof(scale_value));
+ TEST_ASSERT_EQUAL_MESSAGE(
+ 0,
+ scale_value,
+ "Scale value should be equal to 0 if overflows (>1)");
+ }
+}
+
+} // extern "C"
\ No newline at end of file
diff --git a/components/uic_dotdot/dotdot-xml/Unify_HumidityControl.xml b/components/uic_dotdot/dotdot-xml/Unify_HumidityControl.xml
new file mode 100644
index 0000000000..0ce25ad5ed
--- /dev/null
+++ b/components/uic_dotdot/dotdot-xml/Unify_HumidityControl.xml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/uic_dotdot/dotdot-xml/library.xml b/components/uic_dotdot/dotdot-xml/library.xml
index 78c9d8140a..78a9ea21ac 100644
--- a/components/uic_dotdot/dotdot-xml/library.xml
+++ b/components/uic_dotdot/dotdot-xml/library.xml
@@ -491,4 +491,5 @@ applicable to this document can be found in the LICENSE.md file.
+
diff --git a/components/uic_dotdot/zap-generated/include/dotdot_attribute_id_definitions.h b/components/uic_dotdot/zap-generated/include/dotdot_attribute_id_definitions.h
index 70c0a280c2..fc488c7fa5 100644
--- a/components/uic_dotdot/zap-generated/include/dotdot_attribute_id_definitions.h
+++ b/components/uic_dotdot/zap-generated/include/dotdot_attribute_id_definitions.h
@@ -856,6 +856,26 @@ typedef enum {
#define DOTDOT_PROTOCOL_CONTROLLER_NETWORK_MANAGEMENT_NETWORK_MANAGEMENT_STATE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x1)
// Definitions for cluster: Descriptor
#define DOTDOT_DESCRIPTOR_DEVICE_TYPE_LIST_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x0)
+// Definitions for cluster: UnifyHumidityControl
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_REPORTING_MODE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x1)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x2)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_CURRENT_STATE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x3)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_SUPPORTED_SET_POINTS_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x4)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_MIN_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x5)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_MAX_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x6)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x7)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_SCALE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x8)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_PRECISION_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x9)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_MIN_ATTRIBUTE_ID ((dotdot_attribute_id_t)0xA)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_MAX_ATTRIBUTE_ID ((dotdot_attribute_id_t)0xB)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_ATTRIBUTE_ID ((dotdot_attribute_id_t)0xC)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_SCALE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0xD)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_PRECISION_ATTRIBUTE_ID ((dotdot_attribute_id_t)0xE)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_MIN_ATTRIBUTE_ID ((dotdot_attribute_id_t)0xF)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_MAX_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x10)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x11)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_SCALE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x12)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_PRECISION_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x13)
// clang-format on
diff --git a/components/uic_dotdot/zap-generated/include/dotdot_cluster_command_id_definitions.h b/components/uic_dotdot/zap-generated/include/dotdot_cluster_command_id_definitions.h
index 2833fd9544..cae4604f6c 100644
--- a/components/uic_dotdot/zap-generated/include/dotdot_cluster_command_id_definitions.h
+++ b/components/uic_dotdot/zap-generated/include/dotdot_cluster_command_id_definitions.h
@@ -364,6 +364,10 @@
// Commands for cluster: Descriptor
+// Commands for cluster: UnifyHumidityControl
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_MODE_SET_COMMAND_ID (0x1)
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_SETPOINT_SET_COMMAND_ID (0x1)
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/components/uic_dotdot/zap-generated/include/dotdot_cluster_id_definitions.h b/components/uic_dotdot/zap-generated/include/dotdot_cluster_id_definitions.h
index 1878448a59..4884c8bacb 100644
--- a/components/uic_dotdot/zap-generated/include/dotdot_cluster_id_definitions.h
+++ b/components/uic_dotdot/zap-generated/include/dotdot_cluster_id_definitions.h
@@ -254,6 +254,10 @@
#define DOTDOT_DESCRIPTOR_CLUSTER_ID ((dotdot_cluster_id_t)0xFD13)
+// Definitions for cluster: UnifyHumidityControl
+#define DOTDOT_UNIFY_HUMIDITY_CONTROL_CLUSTER_ID ((dotdot_cluster_id_t)0xFDA0)
+
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/components/uic_dotdot/zap-generated/include/zap-types.h b/components/uic_dotdot/zap-generated/include/zap-types.h
index fb82f117ca..1c1286c4b3 100644
--- a/components/uic_dotdot/zap-generated/include/zap-types.h
+++ b/components/uic_dotdot/zap-generated/include/zap-types.h
@@ -918,6 +918,14 @@ typedef enum {
ZCL_METERING_UNITOF_MEASURE_MEGA_JOULE_MEGA_JOULE_PER_SECOND = 12,
} MeteringUnitofMeasure;
+// Enum for ModeType
+typedef enum {
+ ZCL_MODE_TYPE_OFF = 0,
+ ZCL_MODE_TYPE_HUMIDIFY = 1,
+ ZCL_MODE_TYPE_DEHUMIDIFY = 2,
+ ZCL_MODE_TYPE_AUTO = 3,
+} ModeType;
+
// Enum for MoveStepMode
typedef enum {
ZCL_MOVE_STEP_MODE_UP = 0,
@@ -1092,6 +1100,12 @@ typedef enum {
ZCL_SHDCFG_DIRECTION_OPENING = 1,
} SHDCFGDirection;
+// Enum for ScaleType
+typedef enum {
+ ZCL_SCALE_TYPE_PERCENTAGE = 0,
+ ZCL_SCALE_TYPE_ABSOLUTE = 1,
+} ScaleType;
+
// Enum for SetpointRaiseOrLowerMode
typedef enum {
ZCL_SETPOINT_RAISE_OR_LOWER_MODE_HEAT = 0,
@@ -1099,6 +1113,13 @@ typedef enum {
ZCL_SETPOINT_RAISE_OR_LOWER_MODE_BOTH = 2,
} SetpointRaiseOrLowerMode;
+// Enum for SetpointType
+typedef enum {
+ ZCL_SETPOINT_TYPE_HUMIDIFIER = 1,
+ ZCL_SETPOINT_TYPE_DEHUMIDIFIER = 2,
+ ZCL_SETPOINT_TYPE_AUTO = 3,
+} SetpointType;
+
// Enum for ShadeConfigurationMode
typedef enum {
ZCL_SHADE_CONFIGURATION_MODE_NORMAL = 0,
@@ -1271,6 +1292,13 @@ typedef enum {
ZCL_TX_REPORT_TRANSMISSION_SPEED_UNKNOWN = 255,
} TxReportTransmissionSpeed;
+// Enum for UnifyHumidityControlCurrentState
+typedef enum {
+ ZCL_UNIFY_HUMIDITY_CONTROL_CURRENT_STATE_IDLE = 0,
+ ZCL_UNIFY_HUMIDITY_CONTROL_CURRENT_STATE_HUMIDIFYING = 1,
+ ZCL_UNIFY_HUMIDITY_CONTROL_CURRENT_STATE_DEHUMIDIFYING = 2,
+} UnifyHumidityControlCurrentState;
+
// Enum for WindowCoveringWindowCoveringType
typedef enum {
ZCL_WINDOW_COVERING_WINDOW_COVERING_TYPE_ROLLERSHADE = 0,
@@ -1954,6 +1982,18 @@ typedef enum {
#define TSTAT_SCHEDULE_MODE_HEAT_OFFSET (0)
#define TSTAT_SCHEDULE_MODE_COOL (2)
#define TSTAT_SCHEDULE_MODE_COOL_OFFSET (1)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE_HUMIDIFY (1)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE_HUMIDIFY_OFFSET (0)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE_DEHUMIDIFY (2)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE_DEHUMIDIFY_OFFSET (1)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE_AUTO (4)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE_AUTO_OFFSET (2)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_SET_POINTS_HUMIDIFIER (1)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_SET_POINTS_HUMIDIFIER_OFFSET (0)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_SET_POINTS_DEHUMIDIFIER (2)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_SET_POINTS_DEHUMIDIFIER_OFFSET (1)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_SET_POINTS_AUTO (4)
+#define UNIFY_HUMIDITY_CONTROL_SUPPORTED_SET_POINTS_AUTO_OFFSET (2)
#define WINDOW_COVERING_CONFIG_OR_STATUS_OPERATIONAL (1)
#define WINDOW_COVERING_CONFIG_OR_STATUS_OPERATIONAL_OFFSET (0)
#define WINDOW_COVERING_CONFIG_OR_STATUS_ONLINE (2)
diff --git a/components/uic_dotdot/zap-generated/readme_ucl_mqtt_reference.md b/components/uic_dotdot/zap-generated/readme_ucl_mqtt_reference.md
index dbdfa36ecb..e99e128003 100644
--- a/components/uic_dotdot/zap-generated/readme_ucl_mqtt_reference.md
+++ b/components/uic_dotdot/zap-generated/readme_ucl_mqtt_reference.md
@@ -53949,6 +53949,1182 @@ mosquitto_pub -t 'ucl/by-unid///Descriptor/Commands/ForceReadAttribute
+
+
+
+
+
+
+
+
+\page unify_humidity_control UnifyHumidityControl Cluster
+The following commands and attributes are accepted as JSON payloads for the
+UnifyHumidityControl cluster.
+
+
+
+
+
+
+\section unify_humidity_control_attrs UnifyHumidityControl Attributes
+The following attribute topics are used to retrieve the UnifyHumidityControl cluster state.
+
+
+
+\subsection unify_humidity_control_attr_reporting_mode UnifyHumidityControl/ReportingMode Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/ReportingMode/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/ReportingMode/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster ReportingMode Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "ModeType"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for ReportingMode attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/ReportingMode/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/ReportingMode/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/ReportingMode/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_supported_reporting_mode UnifyHumidityControl/SupportedReportingMode Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/SupportedReportingMode/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/SupportedReportingMode/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster SupportedReportingMode Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "UnifyHumidityControlSupportedReportingMode"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for SupportedReportingMode attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/SupportedReportingMode/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/SupportedReportingMode/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/SupportedReportingMode/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_current_state UnifyHumidityControl/CurrentState Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/CurrentState/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/CurrentState/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster CurrentState Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "UnifyHumidityControlCurrentState"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for CurrentState attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/CurrentState/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/CurrentState/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/CurrentState/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_supported_set_points UnifyHumidityControl/SupportedSetPoints Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/SupportedSetPoints/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/SupportedSetPoints/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster SupportedSetPoints Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "UnifyHumidityControlSupportedSetPoints"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for SupportedSetPoints attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/SupportedSetPoints/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/SupportedSetPoints/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/SupportedSetPoints/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_humidifier_setpoint_min UnifyHumidityControl/HumidifierSetpointMin Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/HumidifierSetpointMin/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/HumidifierSetpointMin/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster HumidifierSetpointMin Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for HumidifierSetpointMin attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/HumidifierSetpointMin/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/HumidifierSetpointMin/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/HumidifierSetpointMin/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_humidifier_setpoint_max UnifyHumidityControl/HumidifierSetpointMax Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/HumidifierSetpointMax/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/HumidifierSetpointMax/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster HumidifierSetpointMax Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for HumidifierSetpointMax attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/HumidifierSetpointMax/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/HumidifierSetpointMax/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/HumidifierSetpointMax/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_humidifier_setpoint UnifyHumidityControl/HumidifierSetpoint Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/HumidifierSetpoint/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/HumidifierSetpoint/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster HumidifierSetpoint Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for HumidifierSetpoint attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/HumidifierSetpoint/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/HumidifierSetpoint/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/HumidifierSetpoint/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_humidifier_setpoint_scale UnifyHumidityControl/HumidifierSetpointScale Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/HumidifierSetpointScale/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/HumidifierSetpointScale/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster HumidifierSetpointScale Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "ScaleType"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for HumidifierSetpointScale attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/HumidifierSetpointScale/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/HumidifierSetpointScale/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/HumidifierSetpointScale/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_humidifier_setpoint_precision UnifyHumidityControl/HumidifierSetpointPrecision Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/HumidifierSetpointPrecision/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/HumidifierSetpointPrecision/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster HumidifierSetpointPrecision Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for HumidifierSetpointPrecision attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/HumidifierSetpointPrecision/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/HumidifierSetpointPrecision/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/HumidifierSetpointPrecision/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_dehumidifier_setpoint_min UnifyHumidityControl/DehumidifierSetpointMin Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/DehumidifierSetpointMin/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/DehumidifierSetpointMin/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster DehumidifierSetpointMin Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for DehumidifierSetpointMin attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/DehumidifierSetpointMin/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/DehumidifierSetpointMin/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/DehumidifierSetpointMin/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_dehumidifier_setpoint_max UnifyHumidityControl/DehumidifierSetpointMax Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/DehumidifierSetpointMax/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/DehumidifierSetpointMax/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster DehumidifierSetpointMax Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for DehumidifierSetpointMax attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/DehumidifierSetpointMax/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/DehumidifierSetpointMax/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/DehumidifierSetpointMax/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_dehumidifier_setpoint UnifyHumidityControl/DehumidifierSetpoint Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/DehumidifierSetpoint/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/DehumidifierSetpoint/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster DehumidifierSetpoint Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for DehumidifierSetpoint attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/DehumidifierSetpoint/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/DehumidifierSetpoint/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/DehumidifierSetpoint/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_dehumidifier_setpoint_scale UnifyHumidityControl/DehumidifierSetpointScale Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/DehumidifierSetpointScale/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/DehumidifierSetpointScale/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster DehumidifierSetpointScale Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "ScaleType"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for DehumidifierSetpointScale attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/DehumidifierSetpointScale/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/DehumidifierSetpointScale/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/DehumidifierSetpointScale/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_dehumidifier_setpoint_precision UnifyHumidityControl/DehumidifierSetpointPrecision Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/DehumidifierSetpointPrecision/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/DehumidifierSetpointPrecision/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster DehumidifierSetpointPrecision Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for DehumidifierSetpointPrecision attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/DehumidifierSetpointPrecision/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/DehumidifierSetpointPrecision/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/DehumidifierSetpointPrecision/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_auto_setpoint_min UnifyHumidityControl/AutoSetpointMin Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/AutoSetpointMin/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/AutoSetpointMin/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster AutoSetpointMin Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for AutoSetpointMin attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/AutoSetpointMin/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/AutoSetpointMin/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/AutoSetpointMin/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_auto_setpoint_max UnifyHumidityControl/AutoSetpointMax Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/AutoSetpointMax/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/AutoSetpointMax/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster AutoSetpointMax Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for AutoSetpointMax attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/AutoSetpointMax/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/AutoSetpointMax/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/AutoSetpointMax/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_auto_setpoint UnifyHumidityControl/AutoSetpoint Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/AutoSetpoint/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/AutoSetpoint/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster AutoSetpoint Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for AutoSetpoint attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/AutoSetpoint/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/AutoSetpoint/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/AutoSetpoint/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_auto_setpoint_scale UnifyHumidityControl/AutoSetpointScale Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/AutoSetpointScale/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/AutoSetpointScale/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster AutoSetpointScale Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "ScaleType"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for AutoSetpointScale attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/AutoSetpointScale/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/AutoSetpointScale/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/AutoSetpointScale/Reported { "value": }
+
+```
+
+
+
+\subsection unify_humidity_control_attr_auto_setpoint_precision UnifyHumidityControl/AutoSetpointPrecision Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/AutoSetpointPrecision/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/AutoSetpointPrecision/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster AutoSetpointPrecision Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for AutoSetpointPrecision attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid/+/+/UnifyHumidityControl/Attributes/AutoSetpointPrecision/+'
+
+# Example output
+
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/AutoSetpointPrecision/Desired { "value": }
+ucl/by-unid//ep0/UnifyHumidityControl/Attributes/AutoSetpointPrecision/Reported { "value": }
+
+```
+
+
+
+
+\subsection unify_humidity_control_attr_cluster_revision UnifyHumidityControl/ClusterRevision Attribute
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Attributes/ClusterRevision/Reported
+[PREFIX]/UnifyHumidityControl/Attributes/ClusterRevision/Desired
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster ClusterRevision Attribute Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+**Example Mosquitto CLI Tool Usage**
+
+To see desired/reported value for ClusterRevision attribute under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid///UnifyHumidityControl/Attributes/ClusterRevision/+'
+# Example output
+ucl/by-unid///UnifyHumidityControl/Attributes/ClusterRevision/Desired { "value": }
+ucl/by-unid///UnifyHumidityControl/Attributes/ClusterRevision/Reported { "value": }
+```
+
+
+
+
+
+
+
+
+
+
+\section unify_humidity_control_recv_cmd_support UnifyHumidityControl Command Support
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/SupportedCommands
+[PREFIX]/UnifyHumidityControl/SupportedGeneratedCommands
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Command Support Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "array",
+ "items" : {
+ "type": "string",
+ "enum": [
+ "ModeSet",
+ "SetpointSet",
+ "WriteAttributes",
+ "ForceReadAttributes"
+ ]
+ }
+ }
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+**Example Mosquitto CLI Tool Usage**
+
+To see supported commands for UnifyHumidityControl cluster under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid///UnifyHumidityControl/SupportedCommands'
+# Example output
+ucl/by-unid///UnifyHumidityControl/SupportedCommands { "value": ["ModeSet","SetpointSet","WriteAttributes", "ForceReadAttributes"] }
+```
+
+To see supported generated commands for UnifyHumidityControl cluster under the by-unid topic space:
+
+```console
+mosquitto_sub -t 'ucl/by-unid///UnifyHumidityControl/SupportedGeneratedCommands'
+# Example output
+ucl/by-unid///UnifyHumidityControl/SupportedGeneratedCommands { "value": [] }
+```
+
+
+
+
+
+
+
+
+
+
+\section unify_humidity_control_cmds UnifyHumidityControl Commands
+
+
+
+\subsection unify_humidity_control_mode_set_cmd UnifyHumidityControl/ModeSet Command
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Commands/ModeSet
+[PREFIX]/UnifyHumidityControl/GeneratedCommands/ModeSet
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster ModeSet Command Properties",
+ "type": "object",
+ "properties": {
+ "Mode": {
+ "type": "ModeType"
+ }
+ },
+ "required": [
+ "Mode"
+ ]
+}
+```
+
+**Example Mosquitto CLI Tool Usage**
+
+To send a UnifyHumidityControl/ModeSet command under the by-unid topic space:
+
+```console
+mosquitto_pub -t 'ucl/by-unid///UnifyHumidityControl/Commands/ModeSet' -m '{ "Mode": }'
+```
+
+To receive a UnifyHumidityControl/ModeSet generated command from a UNID/endpoint:
+
+```console
+mosquitto_sub -t 'ucl/by-unid///UnifyHumidityControl/GeneratedCommands/ModeSet'
+```
+
+
+
+\subsection unify_humidity_control_setpoint_set_cmd UnifyHumidityControl/SetpointSet Command
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Commands/SetpointSet
+[PREFIX]/UnifyHumidityControl/GeneratedCommands/SetpointSet
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster SetpointSet Command Properties",
+ "type": "object",
+ "properties": {
+ "Type": {
+ "type": "SetpointType"
+ },
+ "Precision": {
+ "type": "integer"
+ },
+ "Scale": {
+ "type": "integer"
+ },
+ "Value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "Type",
+ "Precision",
+ "Scale",
+ "Value"
+ ]
+}
+```
+
+**Example Mosquitto CLI Tool Usage**
+
+To send a UnifyHumidityControl/SetpointSet command under the by-unid topic space:
+
+```console
+mosquitto_pub -t 'ucl/by-unid///UnifyHumidityControl/Commands/SetpointSet' -m '{ "Type": ,"Precision": ,"Scale": ,"Value": }'
+```
+
+To receive a UnifyHumidityControl/SetpointSet generated command from a UNID/endpoint:
+
+```console
+mosquitto_sub -t 'ucl/by-unid///UnifyHumidityControl/GeneratedCommands/SetpointSet'
+```
+
+
+
+\subsection unify_humidity_control_write_attr_cmd UnifyHumidityControl/WriteAttributes Command
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Commands/WriteAttributes
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster WriteAttributes Command Properties",
+ "type": "object",
+ "properties": {
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+**Example Mosquitto CLI Tool Usage**
+
+To update all UnifyHumidityControl attributes under the by-unid topic space:
+
+```console
+mosquitto_pub -t 'ucl/by-unid///UnifyHumidityControl/Commands/WriteAttributes' -m '{ }'
+```
+
+> NOTE: Specify only the list of attributes to write in this command.
+> Unspecified attributes will not be updated.
+
+
+
+\subsection unify_humidity_control_force_read_attr_cmd UnifyHumidityControl/ForceReadAttributes Command
+
+**MQTT Topic Pattern:**
+
+```
+[PREFIX]/UnifyHumidityControl/Commands/ForceReadAttributes
+```
+
+**MQTT Payload JSON Schema:**
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControl Cluster ForceReadAttributes Command Properties",
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "array"
+ "items": {
+ "type": "string",
+ "enum": [
+ "ReportingMode",
+ "SupportedReportingMode",
+ "CurrentState",
+ "SupportedSetPoints",
+ "HumidifierSetpointMin",
+ "HumidifierSetpointMax",
+ "HumidifierSetpoint",
+ "HumidifierSetpointScale",
+ "HumidifierSetpointPrecision",
+ "DehumidifierSetpointMin",
+ "DehumidifierSetpointMax",
+ "DehumidifierSetpoint",
+ "DehumidifierSetpointScale",
+ "DehumidifierSetpointPrecision",
+ "AutoSetpointMin",
+ "AutoSetpointMax",
+ "AutoSetpoint",
+ "AutoSetpointScale",
+ "AutoSetpointPrecision"
+ ]
+ }
+ }
+ },
+ "required": [
+ "value"
+ ]
+}
+```
+
+**Example Mosquitto CLI Tool Usage**
+
+To force read all UnifyHumidityControl attributes under the by-unid topic space (by sending an empty array):
+
+```console
+mosquitto_pub -t 'ucl/by-unid///UnifyHumidityControl/Commands/ForceReadAttributes' -m '{ "value": [] }'
+```
+
+To force read one of the UnifyHumidityControl attributes under the by-unid topic space:
+
+```console
+mosquitto_pub -t 'ucl/by-unid///UnifyHumidityControl/Commands/ForceReadAttributes' -m '{ "value": ["ReportingMode"] }'
+```
+
+
+
+
+
@@ -56478,6 +57654,31 @@ mosquitto_pub -t 'ucl/by-unid///Descriptor/Commands/ForceReadAttribute
+
+
+
+\section enum_mode_type ModeType Enum
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "ModeType Enum Properties",
+ "type": "string",
+ "enum": [
+ "Off",
+ "Humidify",
+ "Dehumidify",
+ "Auto"
+ ]
+}
+```
+
+
+
+
+
+
+
@@ -56975,6 +58176,29 @@ mosquitto_pub -t 'ucl/by-unid///Descriptor/Commands/ForceReadAttribute
+
+
+
+\section enum_scale_type ScaleType Enum
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "ScaleType Enum Properties",
+ "type": "string",
+ "enum": [
+ "Percentage",
+ "Absolute"
+ ]
+}
+```
+
+
+
+
+
+
+
@@ -56999,6 +58223,30 @@ mosquitto_pub -t 'ucl/by-unid///Descriptor/Commands/ForceReadAttribute
+
+
+
+\section enum_setpoint_type SetpointType Enum
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "SetpointType Enum Properties",
+ "type": "string",
+ "enum": [
+ "Humidifier",
+ "Dehumidifier",
+ "Auto"
+ ]
+}
+```
+
+
+
+
+
+
+
@@ -57545,6 +58793,30 @@ mosquitto_pub -t 'ucl/by-unid///Descriptor/Commands/ForceReadAttribute
+
+
+
+\section enum_unify_humidity_control_current_state UnifyHumidityControlCurrentState Enum
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControlCurrentState Enum Properties",
+ "type": "string",
+ "enum": [
+ "Idle",
+ "Humidifying",
+ "Dehumidifying"
+ ]
+}
+```
+
+
+
+
+
+
+
@@ -59947,6 +61219,66 @@ mosquitto_pub -t 'ucl/by-unid///Descriptor/Commands/ForceReadAttribute
+
+
+
+\section enum_unify_humidity_control_supported_reporting_mode UnifyHumidityControlSupportedReportingMode Bitmap
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControlSupportedReportingMode Enum Properties",
+ "type": "object",
+ "properties": {
+ "Humidify": {
+ "type": "boolean"
+ },
+ "Dehumidify": {
+ "type": "boolean"
+ },
+ "Auto": {
+ "type": "boolean"
+ }
+ }
+}
+```
+
+
+
+
+
+
+
+
+
+
+\section enum_unify_humidity_control_supported_set_points UnifyHumidityControlSupportedSetPoints Bitmap
+
+```json
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "UnifyHumidityControlSupportedSetPoints Enum Properties",
+ "type": "object",
+ "properties": {
+ "Humidifier": {
+ "type": "boolean"
+ },
+ "Dehumidifier": {
+ "type": "boolean"
+ },
+ "Auto": {
+ "type": "boolean"
+ }
+ }
+}
+```
+
+
+
+
+
+
+
diff --git a/components/uic_dotdot/zap-generated/src/dotdot_attribute_id_definitions.c b/components/uic_dotdot/zap-generated/src/dotdot_attribute_id_definitions.c
index cd3e175e69..33b0e2b6eb 100644
--- a/components/uic_dotdot/zap-generated/src/dotdot_attribute_id_definitions.c
+++ b/components/uic_dotdot/zap-generated/src/dotdot_attribute_id_definitions.c
@@ -2025,6 +2025,53 @@ const char *uic_dotdot_get_attribute_name(dotdot_cluster_id_t cluster_id,
return "Unknown";
}
// clang-format off
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_CLUSTER_ID:
+ // clang-format on
+ switch (attribute_id) {
+ // clang-format off
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_REPORTING_MODE_ATTRIBUTE_ID:
+ return "ReportingMode";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE_ATTRIBUTE_ID:
+ return "SupportedReportingMode";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_CURRENT_STATE_ATTRIBUTE_ID:
+ return "CurrentState";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_SUPPORTED_SET_POINTS_ATTRIBUTE_ID:
+ return "SupportedSetPoints";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_MIN_ATTRIBUTE_ID:
+ return "HumidifierSetpointMin";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_MAX_ATTRIBUTE_ID:
+ return "HumidifierSetpointMax";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_ATTRIBUTE_ID:
+ return "HumidifierSetpoint";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_SCALE_ATTRIBUTE_ID:
+ return "HumidifierSetpointScale";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_PRECISION_ATTRIBUTE_ID:
+ return "HumidifierSetpointPrecision";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_MIN_ATTRIBUTE_ID:
+ return "DehumidifierSetpointMin";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_MAX_ATTRIBUTE_ID:
+ return "DehumidifierSetpointMax";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_ATTRIBUTE_ID:
+ return "DehumidifierSetpoint";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_SCALE_ATTRIBUTE_ID:
+ return "DehumidifierSetpointScale";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_PRECISION_ATTRIBUTE_ID:
+ return "DehumidifierSetpointPrecision";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_MIN_ATTRIBUTE_ID:
+ return "AutoSetpointMin";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_MAX_ATTRIBUTE_ID:
+ return "AutoSetpointMax";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_ATTRIBUTE_ID:
+ return "AutoSetpoint";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_SCALE_ATTRIBUTE_ID:
+ return "AutoSetpointScale";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_PRECISION_ATTRIBUTE_ID:
+ return "AutoSetpointPrecision";
+ // clang-format on
+ default:
+ return "Unknown";
+ }
+ // clang-format off
// clang-format on
default:
return "Unknown";
@@ -4409,6 +4456,65 @@ dotdot_attribute_id_t
return DOTDOT_DESCRIPTOR_DEVICE_TYPE_LIST_ATTRIBUTE_ID;
}
break;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_CLUSTER_ID:
+ if (strcmp ("ReportingMode", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_REPORTING_MODE_ATTRIBUTE_ID;
+ }
+ if (strcmp ("SupportedReportingMode", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE_ATTRIBUTE_ID;
+ }
+ if (strcmp ("CurrentState", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_CURRENT_STATE_ATTRIBUTE_ID;
+ }
+ if (strcmp ("SupportedSetPoints", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_SUPPORTED_SET_POINTS_ATTRIBUTE_ID;
+ }
+ if (strcmp ("HumidifierSetpointMin", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_MIN_ATTRIBUTE_ID;
+ }
+ if (strcmp ("HumidifierSetpointMax", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_MAX_ATTRIBUTE_ID;
+ }
+ if (strcmp ("HumidifierSetpoint", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_ATTRIBUTE_ID;
+ }
+ if (strcmp ("HumidifierSetpointScale", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_SCALE_ATTRIBUTE_ID;
+ }
+ if (strcmp ("HumidifierSetpointPrecision", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_PRECISION_ATTRIBUTE_ID;
+ }
+ if (strcmp ("DehumidifierSetpointMin", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_MIN_ATTRIBUTE_ID;
+ }
+ if (strcmp ("DehumidifierSetpointMax", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_MAX_ATTRIBUTE_ID;
+ }
+ if (strcmp ("DehumidifierSetpoint", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_ATTRIBUTE_ID;
+ }
+ if (strcmp ("DehumidifierSetpointScale", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_SCALE_ATTRIBUTE_ID;
+ }
+ if (strcmp ("DehumidifierSetpointPrecision", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_PRECISION_ATTRIBUTE_ID;
+ }
+ if (strcmp ("AutoSetpointMin", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_MIN_ATTRIBUTE_ID;
+ }
+ if (strcmp ("AutoSetpointMax", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_MAX_ATTRIBUTE_ID;
+ }
+ if (strcmp ("AutoSetpoint", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_ATTRIBUTE_ID;
+ }
+ if (strcmp ("AutoSetpointScale", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_SCALE_ATTRIBUTE_ID;
+ }
+ if (strcmp ("AutoSetpointPrecision", attribute_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_PRECISION_ATTRIBUTE_ID;
+ }
+ break;
default:
return DOTDOT_INVALID_ATTRIBUTE_ID;
}
@@ -6426,6 +6532,53 @@ dotdot_attribute_json_type_t
return JSON_TYPE_UNKNOWN;
}
// clang-format off
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_CLUSTER_ID:
+ // clang-format on
+ switch (attribute_id) {
+ // clang-format off
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_REPORTING_MODE_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_CURRENT_STATE_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_SUPPORTED_SET_POINTS_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_MIN_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_MAX_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_SCALE_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_PRECISION_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_MIN_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_MAX_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_SCALE_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_PRECISION_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_MIN_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_MAX_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_SCALE_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_PRECISION_ATTRIBUTE_ID:
+ return JSON_TYPE_NUMBER;
+ // clang-format on
+ default:
+ return JSON_TYPE_UNKNOWN;
+ }
+ // clang-format off
// clang-format on
default:
return JSON_TYPE_UNKNOWN;
@@ -6774,5 +6927,23 @@ bool uic_dotdot_attribute_is_enum(dotdot_cluster_id_t cluster_id,
if (64787 == cluster_id) {
}
+ if (64928 == cluster_id) {
+ if (1 == attribute_id) {
+ return true;
+ }
+ if (3 == attribute_id) {
+ return true;
+ }
+ if (8 == attribute_id) {
+ return true;
+ }
+ if (13 == attribute_id) {
+ return true;
+ }
+ if (18 == attribute_id) {
+ return true;
+ }
+ }
+
return false;
}
diff --git a/components/uic_dotdot/zap-generated/src/dotdot_cluster_id_definitions.c b/components/uic_dotdot/zap-generated/src/dotdot_cluster_id_definitions.c
index 18b5402fa7..b4ed6aad64 100644
--- a/components/uic_dotdot/zap-generated/src/dotdot_cluster_id_definitions.c
+++ b/components/uic_dotdot/zap-generated/src/dotdot_cluster_id_definitions.c
@@ -128,6 +128,8 @@ const char* uic_dotdot_get_cluster_name(dotdot_cluster_id_t cluster_id) {
return "ProtocolController-NetworkManagement";
case DOTDOT_DESCRIPTOR_CLUSTER_ID:
return "Descriptor";
+ case DOTDOT_UNIFY_HUMIDITY_CONTROL_CLUSTER_ID:
+ return "UnifyHumidityControl";
default:
return "Unknown";
}
@@ -299,6 +301,9 @@ dotdot_cluster_id_t uic_dotdot_get_cluster_id(const char* cluster_name) {
if (strcmp ("Descriptor", cluster_name) == 0) {
return DOTDOT_DESCRIPTOR_CLUSTER_ID;
}
+ if (strcmp ("UnifyHumidityControl", cluster_name) == 0) {
+ return DOTDOT_UNIFY_HUMIDITY_CONTROL_CLUSTER_ID;
+ }
// Return an invalid ID if we did not get any match.
return DOTDOT_INVALID_CLUSTER_ID;
diff --git a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h
index f0dc62b095..c228ec95ac 100644
--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h
+++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h
@@ -40444,6 +40444,853 @@ void uic_mqtt_dotdot_descriptor_publish_supported_commands(
void uic_mqtt_dotdot_descriptor_publish_empty_supported_commands(
const dotdot_unid_t unid
,dotdot_endpoint_id_t endpoint);
+// Callback types used by the unify_humidity_control cluster
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ uic_mqtt_dotdot_callback_call_type_t call_type,
+ ModeType mode
+
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ uic_mqtt_dotdot_callback_call_type_t call_type,
+ SetpointType type,
+
+ uint8_t precision,
+
+ uint8_t scale,
+
+ int32_t value
+
+);
+
+typedef struct {
+ uint8_t reporting_mode;
+ uint8_t supported_reporting_mode;
+ uint8_t current_state;
+ uint8_t supported_set_points;
+ int32_t humidifier_setpoint_min;
+ int32_t humidifier_setpoint_max;
+ int32_t humidifier_setpoint;
+ uint8_t humidifier_setpoint_scale;
+ uint8_t humidifier_setpoint_precision;
+ int32_t dehumidifier_setpoint_min;
+ int32_t dehumidifier_setpoint_max;
+ int32_t dehumidifier_setpoint;
+ uint8_t dehumidifier_setpoint_scale;
+ uint8_t dehumidifier_setpoint_precision;
+ int32_t auto_setpoint_min;
+ int32_t auto_setpoint_max;
+ int32_t auto_setpoint;
+ uint8_t auto_setpoint_scale;
+ uint8_t auto_setpoint_precision;
+} uic_mqtt_dotdot_unify_humidity_control_state_t;
+
+typedef struct {
+ bool reporting_mode;
+ bool supported_reporting_mode;
+ bool current_state;
+ bool supported_set_points;
+ bool humidifier_setpoint_min;
+ bool humidifier_setpoint_max;
+ bool humidifier_setpoint;
+ bool humidifier_setpoint_scale;
+ bool humidifier_setpoint_precision;
+ bool dehumidifier_setpoint_min;
+ bool dehumidifier_setpoint_max;
+ bool dehumidifier_setpoint;
+ bool dehumidifier_setpoint_scale;
+ bool dehumidifier_setpoint_precision;
+ bool auto_setpoint_min;
+ bool auto_setpoint_max;
+ bool auto_setpoint;
+ bool auto_setpoint_scale;
+ bool auto_setpoint_precision;
+} uic_mqtt_dotdot_unify_humidity_control_updated_state_t;
+
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback_t)(
+ const dotdot_unid_t unid,
+ const dotdot_endpoint_id_t endpoint,
+ uic_mqtt_dotdot_callback_call_type_t call_type,
+ uic_mqtt_dotdot_unify_humidity_control_state_t,
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t
+);
+
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_t)(
+ const dotdot_unid_t unid,
+ const dotdot_endpoint_id_t endpoint,
+ uic_mqtt_dotdot_callback_call_type_t call_type,
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t
+);
+
+
+/**
+ * @brief Command fields for UnifyHumidityControl/ModeSet
+ */
+typedef struct {
+ ModeType mode;
+} uic_mqtt_dotdot_unify_humidity_control_command_mode_set_fields_t;
+
+/**
+ * @brief Command fields for UnifyHumidityControl/SetpointSet
+ */
+typedef struct {
+ SetpointType type;
+
+ uint8_t precision;
+
+ uint8_t scale;
+
+ int32_t value;
+} uic_mqtt_dotdot_unify_humidity_control_command_setpoint_set_fields_t;
+
+
+/**
+ * @brief Setup callback to be called when a
+ * UnifyHumidityControl/Commands/mode_set is received.
+ *
+ * Setting this callback will not overwrite the previous set callback
+ * @param callback Function to be called on command reception
+ */
+void uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_set(const uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_t callback);
+/**
+ * @brief Unsets callback to be called when a
+ * UnifyHumidityControl/Commands/mode_set is received.
+ *
+ * @param callback Function to be no longer called on command reception
+ */
+void uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_unset(const uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_t callback);
+/**
+ * @brief Clears all callbacks registered for when
+ * UnifyHumidityControl/Commands/mode_set is received.
+ */
+void uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_clear();
+
+/**
+ * @brief Setup callback to be called when a
+ * +/UnifyHumidityControl/GeneratedCommands/mode_set is received.
+ *
+ * Setting this callback will not overwrite the previous set callback
+ * @param callback Function to be called on command reception
+ */
+void uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback_set(const uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_t callback);
+/**
+ * @brief Unsets callback to be called when a
+ * +/UnifyHumidityControl/GeneratedCommands/mode_set is received.
+ * @param callback Function to be no longer called on command reception
+ */
+void uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback_unset(const uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_t callback);
+/**
+ * @brief Clears all callbacks registered for when
+ * +/UnifyHumidityControl/GeneratedCommands/mode_set is received.
+ */
+void uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback_clear();
+/**
+ * @brief Setup callback to be called when a
+ * UnifyHumidityControl/Commands/setpoint_set is received.
+ *
+ * Setting this callback will not overwrite the previous set callback
+ * @param callback Function to be called on command reception
+ */
+void uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_set(const uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_t callback);
+/**
+ * @brief Unsets callback to be called when a
+ * UnifyHumidityControl/Commands/setpoint_set is received.
+ *
+ * @param callback Function to be no longer called on command reception
+ */
+void uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_unset(const uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_t callback);
+/**
+ * @brief Clears all callbacks registered for when
+ * UnifyHumidityControl/Commands/setpoint_set is received.
+ */
+void uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_clear();
+
+/**
+ * @brief Setup callback to be called when a
+ * +/UnifyHumidityControl/GeneratedCommands/setpoint_set is received.
+ *
+ * Setting this callback will not overwrite the previous set callback
+ * @param callback Function to be called on command reception
+ */
+void uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback_set(const uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_t callback);
+/**
+ * @brief Unsets callback to be called when a
+ * +/UnifyHumidityControl/GeneratedCommands/setpoint_set is received.
+ * @param callback Function to be no longer called on command reception
+ */
+void uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback_unset(const uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_t callback);
+/**
+ * @brief Clears all callbacks registered for when
+ * +/UnifyHumidityControl/GeneratedCommands/setpoint_set is received.
+ */
+void uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback_clear();
+
+/**
+ * @brief Setup a callback for WriteAttribute to be called when a
+ * +/unify_humidity_control/Commands/WriteAttributes is received.
+ *
+ * Setting this callback will not overwrite the previous set callback
+ * @param callback Function to be called on command reception
+ */
+void uic_mqtt_dotdot_set_unify_humidity_control_write_attributes_callback(
+ const uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback_t callback
+);
+/**
+ * @brief Unsets a callback for WriteAttribute to be called when a
+ * +/unify_humidity_control/Commands/WriteAttributes is received.
+ * @param callback Function to be no longer called on command reception
+ */
+void uic_mqtt_dotdot_unset_unify_humidity_control_write_attributes_callback(
+ const uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback_t callback
+);
+/**
+ * @brief Clears all callbacks registered for when
+ * +/unify_humidity_control/Commands/WriteAttributes is received.
+ */
+void uic_mqtt_dotdot_clear_unify_humidity_control_write_attributes_callbacks();
+
+/**
+ * @brief Setup a callback for ForceReadAttributes to be called when a
+ * +/unify_humidity_control/Commands/ForceReadAttributes is received.
+ *
+ * Setting this callback will not overwrite the previous set callback
+ * @param callback Function to be called on command reception
+ */
+void uic_mqtt_dotdot_set_unify_humidity_control_force_read_attributes_callback(
+ const uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_t callback
+);
+/**
+ * @brief Unsets a callback for ForceReadAttributes to be called when a
+ * +/unify_humidity_control/Commands/ForceReadAttributes is received.
+ *
+ * @param callback Function to be no longer called on command reception
+ */
+void uic_mqtt_dotdot_unset_unify_humidity_control_force_read_attributes_callback(
+ const uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_t callback
+);
+/**
+ * @brief Clears all callbacks registered for when
+ * +/unify_humidity_control/Commands/ForceReadAttributes is received.
+ */
+void uic_mqtt_dotdot_clear_unify_humidity_control_force_read_attributes_callbacks();
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/ReportingMode
+ *
+ * @param base_topic topic prefix to publish, /reporting_mode
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_reporting_mode_publish(
+ const char *base_topic,
+ ModeType value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/ReportingMode
+ *
+ * @param base_topic topic prefix to publish, /reporting_mode
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_reporting_mode_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/SupportedReportingMode
+ *
+ * @param base_topic topic prefix to publish, /supported_reporting_mode
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_supported_reporting_mode_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/SupportedReportingMode
+ *
+ * @param base_topic topic prefix to publish, /supported_reporting_mode
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_supported_reporting_mode_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/CurrentState
+ *
+ * @param base_topic topic prefix to publish, /current_state
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_current_state_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/CurrentState
+ *
+ * @param base_topic topic prefix to publish, /current_state
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_current_state_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/SupportedSetPoints
+ *
+ * @param base_topic topic prefix to publish, /supported_set_points
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_supported_set_points_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/SupportedSetPoints
+ *
+ * @param base_topic topic prefix to publish, /supported_set_points
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_supported_set_points_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/HumidifierSetpointMin
+ *
+ * @param base_topic topic prefix to publish, /humidifier_setpoint_min
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_min_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/HumidifierSetpointMin
+ *
+ * @param base_topic topic prefix to publish, /humidifier_setpoint_min
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_min_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/HumidifierSetpointMax
+ *
+ * @param base_topic topic prefix to publish, /humidifier_setpoint_max
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_max_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/HumidifierSetpointMax
+ *
+ * @param base_topic topic prefix to publish, /humidifier_setpoint_max
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_max_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/HumidifierSetpoint
+ *
+ * @param base_topic topic prefix to publish, /humidifier_setpoint
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/HumidifierSetpoint
+ *
+ * @param base_topic topic prefix to publish, /humidifier_setpoint
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/HumidifierSetpointScale
+ *
+ * @param base_topic topic prefix to publish, /humidifier_setpoint_scale
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_scale_publish(
+ const char *base_topic,
+ ScaleType value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/HumidifierSetpointScale
+ *
+ * @param base_topic topic prefix to publish, /humidifier_setpoint_scale
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_scale_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/HumidifierSetpointPrecision
+ *
+ * @param base_topic topic prefix to publish, /humidifier_setpoint_precision
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_precision_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/HumidifierSetpointPrecision
+ *
+ * @param base_topic topic prefix to publish, /humidifier_setpoint_precision
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_precision_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/DehumidifierSetpointMin
+ *
+ * @param base_topic topic prefix to publish, /dehumidifier_setpoint_min
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_min_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/DehumidifierSetpointMin
+ *
+ * @param base_topic topic prefix to publish, /dehumidifier_setpoint_min
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_min_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/DehumidifierSetpointMax
+ *
+ * @param base_topic topic prefix to publish, /dehumidifier_setpoint_max
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_max_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/DehumidifierSetpointMax
+ *
+ * @param base_topic topic prefix to publish, /dehumidifier_setpoint_max
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_max_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/DehumidifierSetpoint
+ *
+ * @param base_topic topic prefix to publish, /dehumidifier_setpoint
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/DehumidifierSetpoint
+ *
+ * @param base_topic topic prefix to publish, /dehumidifier_setpoint
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/DehumidifierSetpointScale
+ *
+ * @param base_topic topic prefix to publish, /dehumidifier_setpoint_scale
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_scale_publish(
+ const char *base_topic,
+ ScaleType value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/DehumidifierSetpointScale
+ *
+ * @param base_topic topic prefix to publish, /dehumidifier_setpoint_scale
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_scale_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/DehumidifierSetpointPrecision
+ *
+ * @param base_topic topic prefix to publish, /dehumidifier_setpoint_precision
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_precision_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/DehumidifierSetpointPrecision
+ *
+ * @param base_topic topic prefix to publish, /dehumidifier_setpoint_precision
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_precision_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/AutoSetpointMin
+ *
+ * @param base_topic topic prefix to publish, /auto_setpoint_min
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_min_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/AutoSetpointMin
+ *
+ * @param base_topic topic prefix to publish, /auto_setpoint_min
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_min_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/AutoSetpointMax
+ *
+ * @param base_topic topic prefix to publish, /auto_setpoint_max
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_max_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/AutoSetpointMax
+ *
+ * @param base_topic topic prefix to publish, /auto_setpoint_max
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_max_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/AutoSetpoint
+ *
+ * @param base_topic topic prefix to publish, /auto_setpoint
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/AutoSetpoint
+ *
+ * @param base_topic topic prefix to publish, /auto_setpoint
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/AutoSetpointScale
+ *
+ * @param base_topic topic prefix to publish, /auto_setpoint_scale
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_scale_publish(
+ const char *base_topic,
+ ScaleType value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/AutoSetpointScale
+ *
+ * @param base_topic topic prefix to publish, /auto_setpoint_scale
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_scale_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Publish the attribute; UnifyHumidityControl/Attributes/AutoSetpointPrecision
+ *
+ * @param base_topic topic prefix to publish, /auto_setpoint_precision
+ * will be appended
+ * @param value Value to publish
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_precision_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+/**
+ * @brief Unretains a published attribute; UnifyHumidityControl/Attributes/AutoSetpointPrecision
+ *
+ * @param base_topic topic prefix to publish, /auto_setpoint_precision
+ * will be appended
+ * @param publish_type Whether to publish as Desired, Reported, or Both.
+ *
+ * @returns SL_STATUS_OK on success
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_precision_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+);
+
+
+/**
+ * @brief Publish the UnifyHumidityControl/ClusterRevision attribute
+ *
+ * @param base_topic topic prefix to publish, /UnifyHumidityControl/Attributes/ClusterRevision
+ * will be appended.
+ * @param value Value to publish.
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_cluster_revision(const char* base_topic, uint16_t value);
+
+/**
+ * @brief Unretain a publication to UnifyHumidityControl/ClusterRevision attribute
+ *
+ * @param base_topic topic prefix to publish, /UnifyHumidityControl/Attributes/ClusterRevision
+ * will be appended.
+ */
+void uic_mqtt_dotdot_unify_humidity_control_unretain_cluster_revision(const char* base_topic);
+
+/**
+ * @brief Publish the SupportedCommands for UNID/EndPoint for the UnifyHumidityControl Cluster
+ *
+ * This function will iterate over all Commands in the UnifyHumidityControl Cluster and
+ * call all registered callback functions with UNID/endpoint, and
+ * callback_type = UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK.
+ * All Cluster Command callback functions that return SL_STATUS_OK
+ * will be added to the list of supported commands and published.
+ *
+ * @param unid
+ * @param endpoint
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_supported_commands(
+ const dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint);
+
+/**
+ * @brief Publish an empty array of SupportedCommands for UNID/EndPoint for
+ * the UnifyHumidityControl Cluster
+ *
+ * @param unid
+ * @param endpoint )
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_empty_supported_commands(
+ const dotdot_unid_t unid
+ ,dotdot_endpoint_id_t endpoint);
/**
* @brief Publish the SupportedCommands for UNID/EndPoint
diff --git a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_attributes.h b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_attributes.h
index 92daf48a23..33a8a8f4d3 100644
--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_attributes.h
+++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_attributes.h
@@ -5134,6 +5134,140 @@ typedef sl_status_t (*uic_mqtt_dotdot_descriptor_attribute_device_type_list_call
size_t device_type_list_count,
const DeviceTypeStruct* device_type_list
);
+// Callback types used by the unify_humidity_control cluster
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_reporting_mode_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ uint8_t reporting_mode
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_supported_reporting_mode_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ uint8_t supported_reporting_mode
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_current_state_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ uint8_t current_state
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_supported_set_points_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ uint8_t supported_set_points
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_min_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ int32_t humidifier_setpoint_min
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_max_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ int32_t humidifier_setpoint_max
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ int32_t humidifier_setpoint
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_scale_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ uint8_t humidifier_setpoint_scale
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_precision_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ uint8_t humidifier_setpoint_precision
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_min_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ int32_t dehumidifier_setpoint_min
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_max_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ int32_t dehumidifier_setpoint_max
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ int32_t dehumidifier_setpoint
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_scale_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ uint8_t dehumidifier_setpoint_scale
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_precision_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ uint8_t dehumidifier_setpoint_precision
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_min_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ int32_t auto_setpoint_min
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_max_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ int32_t auto_setpoint_max
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ int32_t auto_setpoint
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_scale_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ uint8_t auto_setpoint_scale
+);
+typedef sl_status_t (*uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_precision_callback_t)(
+ dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint,
+ bool unretained,
+ uic_mqtt_dotdot_attribute_update_type_t update_type,
+ uint8_t auto_setpoint_precision
+);
#ifdef __cplusplus
extern "C" {
@@ -9858,6 +9992,128 @@ sl_status_t uic_mqtt_dotdot_descriptor_attributes_init();
void uic_mqtt_dotdot_descriptor_attribute_device_type_list_callback_set(const uic_mqtt_dotdot_descriptor_attribute_device_type_list_callback_t callback);
+/**
+ * Initializes the attributes features for the UnifyHumidityControl cluster,
+ * allowing to receive attribute updates from other UNIDs.
+ */
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_attributes_init();
+
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/reporting_mode/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_reporting_mode_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_reporting_mode_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/supported_reporting_mode/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_supported_reporting_mode_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_supported_reporting_mode_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/current_state/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_current_state_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_current_state_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/supported_set_points/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_supported_set_points_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_supported_set_points_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/humidifier_setpoint_min/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_min_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_min_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/humidifier_setpoint_max/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_max_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_max_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/humidifier_setpoint/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/humidifier_setpoint_scale/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_scale_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_scale_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/humidifier_setpoint_precision/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_precision_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_precision_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/dehumidifier_setpoint_min/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_min_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_min_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/dehumidifier_setpoint_max/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_max_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_max_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/dehumidifier_setpoint/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/dehumidifier_setpoint_scale/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_scale_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_scale_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/dehumidifier_setpoint_precision/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_precision_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_precision_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/auto_setpoint_min/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_min_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_min_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/auto_setpoint_max/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_max_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_max_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/auto_setpoint/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/auto_setpoint_scale/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_scale_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_scale_callback_t callback);
+/**
+ * Setup callback to be called when a
+ * UnifyHumidityControl/Attributes/auto_setpoint_precision/# is received. Setting
+ * this callback will overwrite the previous set callback
+ */
+void uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_precision_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_precision_callback_t callback);
+
+
#ifdef __cplusplus
}
#endif // __cplusplus
diff --git a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_generated_commands.h b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_generated_commands.h
index 16d97617d4..7fb6c674c8 100644
--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_generated_commands.h
+++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_generated_commands.h
@@ -4986,6 +4986,70 @@ void uic_mqtt_dotdot_descriptor_publish_generated_write_attributes_command(
uic_mqtt_dotdot_descriptor_updated_state_t attribute_list
);
+/**
+ * @brief Publishes an incoming/generated ModeSet command for
+ * the UnifyHumidityControl cluster.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-unid/UNID/epID/UnifyHumidityControl/GeneratedCommands/ModeSet
+ *
+ * @param unid The UNID of the node that sent us the command.
+ *
+ * @param endpoint The Endpoint ID of the node that sent us the command.
+ *
+ *
+ * @param fields Struct pointer with the fields value of the command
+ *
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_generated_mode_set_command(
+ const dotdot_unid_t unid,
+ const dotdot_endpoint_id_t endpoint,
+ const uic_mqtt_dotdot_unify_humidity_control_command_mode_set_fields_t *fields
+
+);
+/**
+ * @brief Publishes an incoming/generated SetpointSet command for
+ * the UnifyHumidityControl cluster.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-unid/UNID/epID/UnifyHumidityControl/GeneratedCommands/SetpointSet
+ *
+ * @param unid The UNID of the node that sent us the command.
+ *
+ * @param endpoint The Endpoint ID of the node that sent us the command.
+ *
+ *
+ * @param fields Struct pointer with the fields value of the command
+ *
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_generated_setpoint_set_command(
+ const dotdot_unid_t unid,
+ const dotdot_endpoint_id_t endpoint,
+ const uic_mqtt_dotdot_unify_humidity_control_command_setpoint_set_fields_t *fields
+
+);
+
+/**
+ * @brief Publishes an incoming/generated WriteAttributes command for
+ * the UnifyHumidityControl cluster.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-unid/UNID/epID/UnifyHumidityControl/GeneratedCommands/WriteAttributes
+ *
+ * @param unid The UNID of the node that sent us the command.
+ *
+ * @param endpoint The Endpoint ID of the node that sent us the command.
+ *
+ * @param attribute_values Values to assign to the attributes
+ * @param attribute_list List of attributes that are written
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_generated_write_attributes_command(
+ const dotdot_unid_t unid,
+ const dotdot_endpoint_id_t endpoint,
+ uic_mqtt_dotdot_unify_humidity_control_state_t attribute_values,
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t attribute_list
+);
+
#ifdef __cplusplus
}
diff --git a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_group_commands.h b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_group_commands.h
index a5c1d17ef9..1d7931b466 100644
--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_group_commands.h
+++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_group_commands.h
@@ -3709,6 +3709,55 @@ void uic_mqtt_dotdot_by_group_descriptor_write_attributes_callback_set(
+/**
+ * @brief Callback signature for by-group UnifyHumidityControl::ModeSet command.
+ */
+typedef void (*uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback_t)(
+ const dotdot_group_id_t group_id,
+ const uic_mqtt_dotdot_unify_humidity_control_command_mode_set_fields_t *fields
+);
+
+/**
+ * Setup handler to be called when a
+ * ucl/by-group/+/UnifyHumidityControl/mode_set is received.
+ * Setting this callback will overwrite the previous set callback.
+ *
+ */
+void uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback_set(const uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback_t callback);
+
+/**
+ * @brief Callback signature for by-group UnifyHumidityControl::SetpointSet command.
+ */
+typedef void (*uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback_t)(
+ const dotdot_group_id_t group_id,
+ const uic_mqtt_dotdot_unify_humidity_control_command_setpoint_set_fields_t *fields
+);
+
+/**
+ * Setup handler to be called when a
+ * ucl/by-group/+/UnifyHumidityControl/setpoint_set is received.
+ * Setting this callback will overwrite the previous set callback.
+ *
+ */
+void uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback_set(const uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback_t callback);
+
+typedef void (*uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback_t)(
+ const dotdot_group_id_t group_id,
+ uic_mqtt_dotdot_unify_humidity_control_state_t,
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t
+);
+
+/**
+ * Setup a callback for WriteAttribute to be called when a
+ * ucl/by-group/+/unify_humidity_control/Commands/WriteAttributes is received.
+ * Setting this callback will overwrite any previously set callback.
+ */
+void uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback_set(
+ const uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback_t callback
+);
+
+
+
#ifdef __cplusplus
}
#endif // __cplusplus
diff --git a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_helpers.h b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_helpers.h
index dcc29ad5f1..79335ba6df 100644
--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_helpers.h
+++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_helpers.h
@@ -517,6 +517,13 @@ char *metering_unitof_measure_get_enum_value_name_c(
uint32_t value, char *result, size_t max_result_size);
/** Get metering_unitof_measure enum representation from string. */
uint32_t metering_unitof_measure_get_enum_value_number_c(const char *str);
+#define MODE_TYPE_ENUM_NAME_AVAILABLE 1
+
+/** Get mode_type string representation from enum. */
+char *mode_type_get_enum_value_name_c(
+ uint32_t value, char *result, size_t max_result_size);
+/** Get mode_type enum representation from string. */
+uint32_t mode_type_get_enum_value_number_c(const char *str);
#define MOVE_STEP_MODE_ENUM_NAME_AVAILABLE 1
/** Get move_step_mode string representation from enum. */
@@ -650,6 +657,13 @@ char *shdcfg_direction_get_enum_value_name_c(
uint32_t value, char *result, size_t max_result_size);
/** Get shdcfg_direction enum representation from string. */
uint32_t shdcfg_direction_get_enum_value_number_c(const char *str);
+#define SCALE_TYPE_ENUM_NAME_AVAILABLE 1
+
+/** Get scale_type string representation from enum. */
+char *scale_type_get_enum_value_name_c(
+ uint32_t value, char *result, size_t max_result_size);
+/** Get scale_type enum representation from string. */
+uint32_t scale_type_get_enum_value_number_c(const char *str);
#define SETPOINT_RAISE_OR_LOWER_MODE_ENUM_NAME_AVAILABLE 1
/** Get setpoint_raise_or_lower_mode string representation from enum. */
@@ -657,6 +671,13 @@ char *setpoint_raise_or_lower_mode_get_enum_value_name_c(
uint32_t value, char *result, size_t max_result_size);
/** Get setpoint_raise_or_lower_mode enum representation from string. */
uint32_t setpoint_raise_or_lower_mode_get_enum_value_number_c(const char *str);
+#define SETPOINT_TYPE_ENUM_NAME_AVAILABLE 1
+
+/** Get setpoint_type string representation from enum. */
+char *setpoint_type_get_enum_value_name_c(
+ uint32_t value, char *result, size_t max_result_size);
+/** Get setpoint_type enum representation from string. */
+uint32_t setpoint_type_get_enum_value_number_c(const char *str);
#define SHADE_CONFIGURATION_MODE_ENUM_NAME_AVAILABLE 1
/** Get shade_configuration_mode string representation from enum. */
@@ -811,6 +832,13 @@ char *tx_report_transmission_speed_get_enum_value_name_c(
uint32_t value, char *result, size_t max_result_size);
/** Get tx_report_transmission_speed enum representation from string. */
uint32_t tx_report_transmission_speed_get_enum_value_number_c(const char *str);
+#define UNIFY_HUMIDITY_CONTROL_CURRENT_STATE_ENUM_NAME_AVAILABLE 1
+
+/** Get unify_humidity_control_current_state string representation from enum. */
+char *unify_humidity_control_current_state_get_enum_value_name_c(
+ uint32_t value, char *result, size_t max_result_size);
+/** Get unify_humidity_control_current_state enum representation from string. */
+uint32_t unify_humidity_control_current_state_get_enum_value_number_c(const char *str);
#define WINDOW_COVERING_WINDOW_COVERING_TYPE_ENUM_NAME_AVAILABLE 1
/** Get window_covering_window_covering_type string representation from enum. */
diff --git a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_helpers.hpp b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_helpers.hpp
index 8db91a511c..b129eb8761 100644
--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_helpers.hpp
+++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_helpers.hpp
@@ -1220,6 +1220,23 @@ std::string metering_unitof_measure_get_enum_value_name(
*/
uint32_t metering_unitof_measure_get_enum_value_number(const std::string &str);
+#define MODE_TYPE_ENUM_NAME_AVAILABLE 1
+
+/**
+ * @brief Finds the name of a field for the ModeType enum
+ *
+ * @returns A string representation of the value.
+ */
+std::string mode_type_get_enum_value_name(
+ uint32_t value);
+
+/**
+ * @brief Finds the enum number of a string representation for the ModeType enum
+ *
+ * @returns A number enum value.
+ */
+uint32_t mode_type_get_enum_value_number(const std::string &str);
+
#define MOVE_STEP_MODE_ENUM_NAME_AVAILABLE 1
/**
@@ -1543,6 +1560,23 @@ std::string shdcfg_direction_get_enum_value_name(
*/
uint32_t shdcfg_direction_get_enum_value_number(const std::string &str);
+#define SCALE_TYPE_ENUM_NAME_AVAILABLE 1
+
+/**
+ * @brief Finds the name of a field for the ScaleType enum
+ *
+ * @returns A string representation of the value.
+ */
+std::string scale_type_get_enum_value_name(
+ uint32_t value);
+
+/**
+ * @brief Finds the enum number of a string representation for the ScaleType enum
+ *
+ * @returns A number enum value.
+ */
+uint32_t scale_type_get_enum_value_number(const std::string &str);
+
#define SETPOINT_RAISE_OR_LOWER_MODE_ENUM_NAME_AVAILABLE 1
/**
@@ -1560,6 +1594,23 @@ std::string setpoint_raise_or_lower_mode_get_enum_value_name(
*/
uint32_t setpoint_raise_or_lower_mode_get_enum_value_number(const std::string &str);
+#define SETPOINT_TYPE_ENUM_NAME_AVAILABLE 1
+
+/**
+ * @brief Finds the name of a field for the SetpointType enum
+ *
+ * @returns A string representation of the value.
+ */
+std::string setpoint_type_get_enum_value_name(
+ uint32_t value);
+
+/**
+ * @brief Finds the enum number of a string representation for the SetpointType enum
+ *
+ * @returns A number enum value.
+ */
+uint32_t setpoint_type_get_enum_value_number(const std::string &str);
+
#define SHADE_CONFIGURATION_MODE_ENUM_NAME_AVAILABLE 1
/**
@@ -1934,6 +1985,23 @@ std::string tx_report_transmission_speed_get_enum_value_name(
*/
uint32_t tx_report_transmission_speed_get_enum_value_number(const std::string &str);
+#define UNIFY_HUMIDITY_CONTROL_CURRENT_STATE_ENUM_NAME_AVAILABLE 1
+
+/**
+ * @brief Finds the name of a field for the UnifyHumidityControlCurrentState enum
+ *
+ * @returns A string representation of the value.
+ */
+std::string unify_humidity_control_current_state_get_enum_value_name(
+ uint32_t value);
+
+/**
+ * @brief Finds the enum number of a string representation for the UnifyHumidityControlCurrentState enum
+ *
+ * @returns A number enum value.
+ */
+uint32_t unify_humidity_control_current_state_get_enum_value_number(const std::string &str);
+
#define WINDOW_COVERING_WINDOW_COVERING_TYPE_ENUM_NAME_AVAILABLE 1
/**
diff --git a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_send_commands.h b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_send_commands.h
index 64af1ec66c..5df9b1c7ab 100644
--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_send_commands.h
+++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_send_commands.h
@@ -7127,6 +7127,84 @@ void uic_mqtt_dotdot_protocol_controller_network_management_publish_write_comman
void uic_mqtt_dotdot_protocol_controller_network_management_publish_write_command_to_group(
uint16_t destination_group_id
);
+/**
+ * @brief Sends/Publishes a ModeSet command for
+ * the UnifyHumidityControl cluster to a destination.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-unid/UNID/epID/UnifyHumidityControl/Commands/ModeSet
+ *
+ * @param destination_unid The UNID of the node that should receive the command.
+ *
+ * @param destination_endpoint The Endpoint ID of the node that should receive the command.
+ *
+ *
+ * @param fields Struct pointer with the fields value of the command
+ *
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_mode_set_command(
+ const dotdot_unid_t destination_unid,
+ const dotdot_endpoint_id_t destination_endpoint,
+ const uic_mqtt_dotdot_unify_humidity_control_command_mode_set_fields_t *fields
+
+);
+
+/**
+ * @brief Sends/Publishes a ModeSet command for
+ * the UnifyHumidityControl cluster to a group.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-group/GroupID/UnifyHumidityControl/Commands/ModeSet
+ *
+ * @param destination_group_id The GroupID that should receive the command.
+ *
+ * @param fields Struct pointer with the fields value of the command
+ *
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_mode_set_command_to_group(
+ uint16_t destination_group_id,
+ const uic_mqtt_dotdot_unify_humidity_control_command_mode_set_fields_t *fields
+
+);
+/**
+ * @brief Sends/Publishes a SetpointSet command for
+ * the UnifyHumidityControl cluster to a destination.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-unid/UNID/epID/UnifyHumidityControl/Commands/SetpointSet
+ *
+ * @param destination_unid The UNID of the node that should receive the command.
+ *
+ * @param destination_endpoint The Endpoint ID of the node that should receive the command.
+ *
+ *
+ * @param fields Struct pointer with the fields value of the command
+ *
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_setpoint_set_command(
+ const dotdot_unid_t destination_unid,
+ const dotdot_endpoint_id_t destination_endpoint,
+ const uic_mqtt_dotdot_unify_humidity_control_command_setpoint_set_fields_t *fields
+
+);
+
+/**
+ * @brief Sends/Publishes a SetpointSet command for
+ * the UnifyHumidityControl cluster to a group.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-group/GroupID/UnifyHumidityControl/Commands/SetpointSet
+ *
+ * @param destination_group_id The GroupID that should receive the command.
+ *
+ * @param fields Struct pointer with the fields value of the command
+ *
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_setpoint_set_command_to_group(
+ uint16_t destination_group_id,
+ const uic_mqtt_dotdot_unify_humidity_control_command_setpoint_set_fields_t *fields
+
+);
#ifdef __cplusplus
diff --git a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_supported_generated_commands.h b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_supported_generated_commands.h
index 3180bd0498..24665f391b 100644
--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_supported_generated_commands.h
+++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_supported_generated_commands.h
@@ -1664,6 +1664,36 @@ void uic_mqtt_dotdot_descriptor_publish_supported_generated_commands(
);
+/**
+ * @brief Struct containing the list of commands for UnifyHumidityControl
+ */
+typedef struct _uic_mqtt_dotdot_unify_humidity_control_supported_commands_ {
+ bool mode_set;
+ bool setpoint_set;
+ bool write_attributes;
+} uic_mqtt_dotdot_unify_humidity_control_supported_commands_t;
+
+/**
+ * @brief Sends/Publishes a the SupportedGenerated commands for
+ * the UnifyHumidityControl cluster for a UNID/Endpoint
+ *
+ * Publication will be made at the following topic
+ * ucl/by-unid/UNID/epID/UnifyHumidityControl/SupportedGeneratedCommands
+ *
+ * @param unid The UNID of the node on behalf of which the advertisment is made
+ *
+ * @param endpoint The Endpoint ID of the node on behalf of which the advertisment is made
+ *
+ * @param command_list Struct pointer with the fields value indicating if
+ * individual commands can be generated.
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_supported_generated_commands(
+ const dotdot_unid_t unid,
+ const dotdot_endpoint_id_t endpoint,
+ const uic_mqtt_dotdot_unify_humidity_control_supported_commands_t *command_list
+);
+
+
#ifdef __cplusplus
}
diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp
index 5dbf0c607a..bd19353ab5 100644
--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp
+++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp
@@ -94739,6 +94739,1929 @@ sl_status_t uic_mqtt_dotdot_descriptor_init()
return SL_STATUS_OK;
}
+// Callbacks pointers
+static std::set uic_mqtt_dotdot_unify_humidity_control_mode_set_callback;
+static std::set uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback;
+static std::set uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback;
+static std::set uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback;
+static std::set uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback;
+static std::set uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback;
+
+// Callbacks setters
+void uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_set(const uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_t callback)
+{
+ if (callback != nullptr) {
+ uic_mqtt_dotdot_unify_humidity_control_mode_set_callback.insert(callback);
+ }
+}
+void uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_unset(const uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_mode_set_callback.erase(callback);
+}
+void uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_clear()
+{
+ uic_mqtt_dotdot_unify_humidity_control_mode_set_callback.clear();
+}
+std::set& get_uic_mqtt_dotdot_unify_humidity_control_mode_set_callback()
+{
+ return uic_mqtt_dotdot_unify_humidity_control_mode_set_callback;
+}
+
+void uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback_set(const uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_t callback)
+{
+ if (callback != nullptr) {
+ uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback.insert(callback);
+ }
+}
+void uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback_unset(const uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback.erase(callback);
+}
+void uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback_clear()
+{
+ uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback.clear();
+}
+void uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_set(const uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_t callback)
+{
+ if (callback != nullptr) {
+ uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback.insert(callback);
+ }
+}
+void uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_unset(const uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback.erase(callback);
+}
+void uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_clear()
+{
+ uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback.clear();
+}
+std::set& get_uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback()
+{
+ return uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback;
+}
+
+void uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback_set(const uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_t callback)
+{
+ if (callback != nullptr) {
+ uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback.insert(callback);
+ }
+}
+void uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback_unset(const uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback.erase(callback);
+}
+void uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback_clear()
+{
+ uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback.clear();
+}
+
+void uic_mqtt_dotdot_set_unify_humidity_control_write_attributes_callback(
+ const uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback_t callback)
+{
+ if (callback != nullptr) {
+ uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback.insert(callback);
+ }
+}
+void uic_mqtt_dotdot_unset_unify_humidity_control_write_attributes_callback(
+ const uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback.erase(callback);
+}
+void uic_mqtt_dotdot_clear_unify_humidity_control_write_attributes_callbacks()
+{
+ uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback.clear();
+}
+std::set& get_uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback()
+{
+ return uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback;
+}
+
+void uic_mqtt_dotdot_set_unify_humidity_control_force_read_attributes_callback(
+ const uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_t callback)
+{
+ if (callback != nullptr) {
+ uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback.insert(callback);
+ }
+}
+void uic_mqtt_dotdot_unset_unify_humidity_control_force_read_attributes_callback(
+ const uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback.erase(callback);
+}
+void uic_mqtt_dotdot_clear_unify_humidity_control_force_read_attributes_callbacks()
+{
+ uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback.clear();
+}
+
+
+// Callback function for incoming publications on ucl/by-unid/+/+/UnifyHumidityControl/Commands/ModeSet
+void uic_mqtt_dotdot_on_unify_humidity_control_mode_set(
+ const char *topic,
+ const char *message,
+ const size_t message_length)
+{
+ if (message_length == 0 || (uic_mqtt_dotdot_unify_humidity_control_mode_set_callback.empty())) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ ModeType mode = {};
+
+
+ nlohmann::json jsn;
+ try {
+ jsn = nlohmann::json::parse(std::string(message));
+
+
+ uic_mqtt_dotdot_parse_unify_humidity_control_mode_set(
+ jsn,
+ mode
+ );
+
+ } catch (const nlohmann::json::parse_error& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyHumidityControl", "ModeSet");
+ return;
+ } catch (const nlohmann::json::exception& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "ModeSet", e.what());
+ return;
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "ModeSet", "");
+ return;
+ }
+
+
+
+ for (const auto& callback: uic_mqtt_dotdot_unify_humidity_control_mode_set_callback){
+ callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL,
+ mode
+
+ );
+ }
+
+}
+
+// Callback function for incoming publications on ucl/by-unid/+/+/UnifyHumidityControl/GeneratedCommands/ModeSet
+static void uic_mqtt_dotdot_on_generated_unify_humidity_control_mode_set(
+ const char *topic,
+ const char *message,
+ const size_t message_length)
+{
+ if (message_length == 0 || (uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback.empty())) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ ModeType mode = {};
+
+
+ nlohmann::json jsn;
+ try {
+ jsn = nlohmann::json::parse(std::string(message));
+
+
+ uic_mqtt_dotdot_parse_unify_humidity_control_mode_set(
+ jsn,
+ mode
+ );
+
+ } catch (const nlohmann::json::parse_error& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyHumidityControl", "ModeSet");
+ return;
+ } catch (const nlohmann::json::exception& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "ModeSet", e.what());
+ return;
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "ModeSet", "");
+ return;
+ }
+
+
+
+
+ for (const auto& callback: uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback){
+ callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL,
+ mode
+
+ );
+ }
+}
+
+
+// Callback function for incoming publications on ucl/by-unid/+/+/UnifyHumidityControl/Commands/SetpointSet
+void uic_mqtt_dotdot_on_unify_humidity_control_setpoint_set(
+ const char *topic,
+ const char *message,
+ const size_t message_length)
+{
+ if (message_length == 0 || (uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback.empty())) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ SetpointType type = {};
+ uint8_t precision = {};
+ uint8_t scale = {};
+ int32_t value = {};
+
+
+ nlohmann::json jsn;
+ try {
+ jsn = nlohmann::json::parse(std::string(message));
+
+
+ uic_mqtt_dotdot_parse_unify_humidity_control_setpoint_set(
+ jsn,
+ type,
+
+ precision,
+
+ scale,
+
+ value
+ );
+
+ } catch (const nlohmann::json::parse_error& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyHumidityControl", "SetpointSet");
+ return;
+ } catch (const nlohmann::json::exception& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "SetpointSet", e.what());
+ return;
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "SetpointSet", "");
+ return;
+ }
+
+
+
+ for (const auto& callback: uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback){
+ callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL,
+ type,
+
+ precision,
+
+ scale,
+
+ value
+
+ );
+ }
+
+}
+
+// Callback function for incoming publications on ucl/by-unid/+/+/UnifyHumidityControl/GeneratedCommands/SetpointSet
+static void uic_mqtt_dotdot_on_generated_unify_humidity_control_setpoint_set(
+ const char *topic,
+ const char *message,
+ const size_t message_length)
+{
+ if (message_length == 0 || (uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback.empty())) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ SetpointType type = {};
+ uint8_t precision = {};
+ uint8_t scale = {};
+ int32_t value = {};
+
+
+ nlohmann::json jsn;
+ try {
+ jsn = nlohmann::json::parse(std::string(message));
+
+
+ uic_mqtt_dotdot_parse_unify_humidity_control_setpoint_set(
+ jsn,
+ type,
+
+ precision,
+
+ scale,
+
+ value
+ );
+
+ } catch (const nlohmann::json::parse_error& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyHumidityControl", "SetpointSet");
+ return;
+ } catch (const nlohmann::json::exception& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "SetpointSet", e.what());
+ return;
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "SetpointSet", "");
+ return;
+ }
+
+
+
+
+ for (const auto& callback: uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback){
+ callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL,
+ type,
+
+ precision,
+
+ scale,
+
+ value
+
+ );
+ }
+}
+
+
+// Callback function for incoming publications on ucl/by-unid/+/+/UnifyHumidityControl/Commands/WriteAttributes
+void uic_mqtt_dotdot_on_unify_humidity_control_WriteAttributes(
+ const char *topic,
+ const char *message,
+ const size_t message_length)
+{
+ if (uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback.empty()) {
+ return;
+ }
+
+ if (message_length == 0) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_state_t new_state = {};
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t new_updated_state = {};
+
+
+ nlohmann::json jsn;
+ try {
+ jsn = nlohmann::json::parse(std::string(message));
+
+ uic_mqtt_dotdot_parse_unify_humidity_control_write_attributes(
+ jsn,
+ new_state,
+ new_updated_state
+ );
+ } catch (const nlohmann::json::parse_error& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyHumidityControl", "WriteAttributes");
+ return;
+ } catch (const nlohmann::json::exception& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "WriteAttributes", e.what());
+ return;
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "WriteAttributes", "");
+ return;
+ }
+
+ for (const auto& callback: uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback){
+ callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL,
+ new_state,
+ new_updated_state
+ );
+ }
+
+}
+
+static void uic_mqtt_dotdot_on_unify_humidity_control_force_read_attributes(
+ const char *topic,
+ const char *message,
+ const size_t message_length)
+{
+ uint8_t endpoint = 0;
+ std::string unid;
+
+ if ((message_length == 0) || (uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback.empty())) {
+ return;
+ }
+
+ if(! uic_dotdot_mqtt::parse_topic(topic, unid, endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ try {
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t force_update = {0};
+ bool trigger_handler = false;
+
+ nlohmann::json jsn = nlohmann::json::parse(std::string(message));
+ std::vector attributes = jsn["value"].get>();
+
+ // Assume all attributes to be read on empty array received
+ if (attributes.size() == 0) {
+ force_update.reporting_mode = true;
+ force_update.supported_reporting_mode = true;
+ force_update.current_state = true;
+ force_update.supported_set_points = true;
+ force_update.humidifier_setpoint_min = true;
+ force_update.humidifier_setpoint_max = true;
+ force_update.humidifier_setpoint = true;
+ force_update.humidifier_setpoint_scale = true;
+ force_update.humidifier_setpoint_precision = true;
+ force_update.dehumidifier_setpoint_min = true;
+ force_update.dehumidifier_setpoint_max = true;
+ force_update.dehumidifier_setpoint = true;
+ force_update.dehumidifier_setpoint_scale = true;
+ force_update.dehumidifier_setpoint_precision = true;
+ force_update.auto_setpoint_min = true;
+ force_update.auto_setpoint_max = true;
+ force_update.auto_setpoint = true;
+ force_update.auto_setpoint_scale = true;
+ force_update.auto_setpoint_precision = true;
+ trigger_handler = true;
+ } else {
+ std::unordered_map supported_attrs = {
+ {"ReportingMode", &force_update.reporting_mode },
+ {"SupportedReportingMode", &force_update.supported_reporting_mode },
+ {"CurrentState", &force_update.current_state },
+ {"SupportedSetPoints", &force_update.supported_set_points },
+ {"HumidifierSetpointMin", &force_update.humidifier_setpoint_min },
+ {"HumidifierSetpointMax", &force_update.humidifier_setpoint_max },
+ {"HumidifierSetpoint", &force_update.humidifier_setpoint },
+ {"HumidifierSetpointScale", &force_update.humidifier_setpoint_scale },
+ {"HumidifierSetpointPrecision", &force_update.humidifier_setpoint_precision },
+ {"DehumidifierSetpointMin", &force_update.dehumidifier_setpoint_min },
+ {"DehumidifierSetpointMax", &force_update.dehumidifier_setpoint_max },
+ {"DehumidifierSetpoint", &force_update.dehumidifier_setpoint },
+ {"DehumidifierSetpointScale", &force_update.dehumidifier_setpoint_scale },
+ {"DehumidifierSetpointPrecision", &force_update.dehumidifier_setpoint_precision },
+ {"AutoSetpointMin", &force_update.auto_setpoint_min },
+ {"AutoSetpointMax", &force_update.auto_setpoint_max },
+ {"AutoSetpoint", &force_update.auto_setpoint },
+ {"AutoSetpointScale", &force_update.auto_setpoint_scale },
+ {"AutoSetpointPrecision", &force_update.auto_setpoint_precision },
+ };
+
+ for (auto& attribute : attributes) {
+ auto found_attr = supported_attrs.find(attribute);
+ if (found_attr != supported_attrs.end()) {
+ *(found_attr->second) = true;
+ trigger_handler = true;
+ }
+ }
+ }
+
+ if (trigger_handler == true) {
+ for (const auto& callback: uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback) {
+ callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL,
+ force_update
+ );
+ }
+ }
+ } catch (...) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl/Commands/ForceReadAttributes: Unable to parse JSON payload");
+ return;
+ }
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_reporting_mode_publish(
+ const char *base_topic,
+ ModeType value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ #ifdef UNIFY_HUMIDITY_CONTROL_REPORTING_MODE_ENUM_NAME_AVAILABLE
+ jsn["value"] = unify_humidity_control_reporting_mode_get_enum_value_name((uint32_t)value);
+ #elif defined(MODE_TYPE_ENUM_NAME_AVAILABLE)
+ jsn["value"] = mode_type_get_enum_value_name((uint32_t)value);
+ #else
+ sl_log_warning(LOG_TAG,"Warning: Enum name not available for UNIFY_HUMIDITY_CONTROL_REPORTING_MODE. Using number instead.");
+ jsn["value"] = static_cast(value);
+ #endif
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/ReportingMode", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/ReportingMode";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_reporting_mode_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/ReportingMode";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_supported_reporting_mode_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ nlohmann::json bitmap_values = UnifyHumidityControlSupportedReportingMode.get_bitmap_values_as_json_tree((uint32_t)value);
+ jsn["value"] = bitmap_values;
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/SupportedReportingMode", e.what());
+ return SL_STATUS_OK;
+ }
+
+ boost::replace_all(payload_str, "\"true\"", "true");
+ boost::replace_all(payload_str, "\"false\"", "false");
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/SupportedReportingMode";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_supported_reporting_mode_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/SupportedReportingMode";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_current_state_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ #ifdef UNIFY_HUMIDITY_CONTROL_CURRENT_STATE_ENUM_NAME_AVAILABLE
+ jsn["value"] = unify_humidity_control_current_state_get_enum_value_name((uint32_t)value);
+ #elif defined(ENUM8_ENUM_NAME_AVAILABLE)
+ jsn["value"] = enum8_get_enum_value_name((uint32_t)value);
+ #else
+ sl_log_warning(LOG_TAG,"Warning: Enum name not available for UNIFY_HUMIDITY_CONTROL_CURRENT_STATE. Using number instead.");
+ jsn["value"] = static_cast(value);
+ #endif
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/CurrentState", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/CurrentState";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_current_state_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/CurrentState";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_supported_set_points_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ nlohmann::json bitmap_values = UnifyHumidityControlSupportedSetPoints.get_bitmap_values_as_json_tree((uint32_t)value);
+ jsn["value"] = bitmap_values;
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/SupportedSetPoints", e.what());
+ return SL_STATUS_OK;
+ }
+
+ boost::replace_all(payload_str, "\"true\"", "true");
+ boost::replace_all(payload_str, "\"false\"", "false");
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/SupportedSetPoints";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_supported_set_points_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/SupportedSetPoints";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_min_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,5,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,5,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/HumidifierSetpointMin", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/HumidifierSetpointMin";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_min_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/HumidifierSetpointMin";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_max_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,6,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,6,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/HumidifierSetpointMax", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/HumidifierSetpointMax";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_max_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/HumidifierSetpointMax";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,7,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,7,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/HumidifierSetpoint", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/HumidifierSetpoint";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/HumidifierSetpoint";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_scale_publish(
+ const char *base_topic,
+ ScaleType value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ #ifdef UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_SCALE_ENUM_NAME_AVAILABLE
+ jsn["value"] = unify_humidity_control_humidifier_setpoint_scale_get_enum_value_name((uint32_t)value);
+ #elif defined(SCALE_TYPE_ENUM_NAME_AVAILABLE)
+ jsn["value"] = scale_type_get_enum_value_name((uint32_t)value);
+ #else
+ sl_log_warning(LOG_TAG,"Warning: Enum name not available for UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_SCALE. Using number instead.");
+ jsn["value"] = static_cast(value);
+ #endif
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/HumidifierSetpointScale", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/HumidifierSetpointScale";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_scale_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/HumidifierSetpointScale";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_precision_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,9,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,9,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/HumidifierSetpointPrecision", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/HumidifierSetpointPrecision";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_humidifier_setpoint_precision_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/HumidifierSetpointPrecision";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_min_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,10,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,10,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/DehumidifierSetpointMin", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/DehumidifierSetpointMin";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_min_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/DehumidifierSetpointMin";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_max_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,11,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,11,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/DehumidifierSetpointMax", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/DehumidifierSetpointMax";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_max_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/DehumidifierSetpointMax";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,12,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,12,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/DehumidifierSetpoint", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/DehumidifierSetpoint";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/DehumidifierSetpoint";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_scale_publish(
+ const char *base_topic,
+ ScaleType value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ #ifdef UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_SCALE_ENUM_NAME_AVAILABLE
+ jsn["value"] = unify_humidity_control_dehumidifier_setpoint_scale_get_enum_value_name((uint32_t)value);
+ #elif defined(SCALE_TYPE_ENUM_NAME_AVAILABLE)
+ jsn["value"] = scale_type_get_enum_value_name((uint32_t)value);
+ #else
+ sl_log_warning(LOG_TAG,"Warning: Enum name not available for UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_SCALE. Using number instead.");
+ jsn["value"] = static_cast(value);
+ #endif
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/DehumidifierSetpointScale", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/DehumidifierSetpointScale";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_scale_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/DehumidifierSetpointScale";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_precision_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,14,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,14,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/DehumidifierSetpointPrecision", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/DehumidifierSetpointPrecision";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_dehumidifier_setpoint_precision_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/DehumidifierSetpointPrecision";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_min_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,15,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,15,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/AutoSetpointMin", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/AutoSetpointMin";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_min_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/AutoSetpointMin";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_max_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,16,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,16,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/AutoSetpointMax", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/AutoSetpointMax";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_max_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/AutoSetpointMax";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_publish(
+ const char *base_topic,
+ int32_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,17,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,17,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/AutoSetpoint", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/AutoSetpoint";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/AutoSetpoint";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_scale_publish(
+ const char *base_topic,
+ ScaleType value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ #ifdef UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_SCALE_ENUM_NAME_AVAILABLE
+ jsn["value"] = unify_humidity_control_auto_setpoint_scale_get_enum_value_name((uint32_t)value);
+ #elif defined(SCALE_TYPE_ENUM_NAME_AVAILABLE)
+ jsn["value"] = scale_type_get_enum_value_name((uint32_t)value);
+ #else
+ sl_log_warning(LOG_TAG,"Warning: Enum name not available for UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_SCALE. Using number instead.");
+ jsn["value"] = static_cast(value);
+ #endif
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/AutoSetpointScale", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/AutoSetpointScale";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_scale_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/AutoSetpointScale";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_precision_publish(
+ const char *base_topic,
+ uint8_t value,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type
+)
+{
+ nlohmann::json jsn;
+
+ // This is a single value
+
+ if (true == uic_dotdot_has_attribute_value_a_name(64928,19,value)) {
+ jsn["value"] = uic_dotdot_get_attribute_value_name(64928,19,value);
+ }else{
+ jsn["value"] = value;
+ }
+
+
+ std::string payload_str;
+ try {
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ payload_str = jsn.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+ } catch (const nlohmann::json::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl/Attributes/AutoSetpointPrecision", e.what());
+ return SL_STATUS_OK;
+ }
+
+
+ std::string topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/AutoSetpointPrecision";
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ if (publish_type & UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ }
+ return SL_STATUS_OK;
+}
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_auto_setpoint_precision_unretain(
+ const char *base_topic,
+ uic_mqtt_dotdot_attribute_publish_type_t publish_type)
+{
+ // clang-format on
+ std::string topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/AutoSetpointPrecision";
+
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_DESIRED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_desired = topic + "/Desired";
+ uic_mqtt_publish(topic_desired.c_str(), NULL, 0, true);
+ }
+ if ((publish_type == UCL_MQTT_PUBLISH_TYPE_REPORTED)
+ || (publish_type == UCL_MQTT_PUBLISH_TYPE_ALL)) {
+ std::string topic_reported = topic + "/Reported";
+ uic_mqtt_publish(topic_reported.c_str(), NULL, 0, true);
+ }
+ return SL_STATUS_OK;
+}
+// clang-format off
+
+
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_init()
+{
+ std::string base_topic = "ucl/by-unid/+/+/";
+
+ std::string subscription_topic;
+ if(!uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback.empty()) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Commands/WriteAttributes";
+ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_humidity_control_WriteAttributes);
+ }
+
+ if(!uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback.empty()) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Commands/ForceReadAttributes";
+ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_humidity_control_force_read_attributes);
+ }
+ if (!uic_mqtt_dotdot_unify_humidity_control_mode_set_callback.empty()) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Commands/ModeSet";
+ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_humidity_control_mode_set);
+ }
+ if (!uic_mqtt_dotdot_unify_humidity_control_generated_mode_set_callback.empty()) {
+ subscription_topic = base_topic + "UnifyHumidityControl/GeneratedCommands/ModeSet";
+ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_humidity_control_mode_set);
+ }
+ if (!uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback.empty()) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Commands/SetpointSet";
+ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_humidity_control_setpoint_set);
+ }
+ if (!uic_mqtt_dotdot_unify_humidity_control_generated_setpoint_set_callback.empty()) {
+ subscription_topic = base_topic + "UnifyHumidityControl/GeneratedCommands/SetpointSet";
+ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_humidity_control_setpoint_set);
+ }
+
+ // Init the attributes for that cluster
+ uic_mqtt_dotdot_unify_humidity_control_attributes_init();
+
+ uic_mqtt_dotdot_by_group_unify_humidity_control_init();
+
+ return SL_STATUS_OK;
+}
+
sl_status_t uic_mqtt_dotdot_init() {
@@ -94952,6 +96875,10 @@ sl_status_t uic_mqtt_dotdot_init() {
status_flag = uic_mqtt_dotdot_descriptor_init();
}
+ if (status_flag == SL_STATUS_OK) {
+ status_flag = uic_mqtt_dotdot_unify_humidity_control_init();
+ }
+
return status_flag;
}
@@ -95013,6 +96940,7 @@ void uic_mqtt_dotdot_publish_supported_commands(
uic_mqtt_dotdot_aox_position_estimation_publish_supported_commands(unid, endpoint_id);
uic_mqtt_dotdot_protocol_controller_network_management_publish_supported_commands(unid, 0);
uic_mqtt_dotdot_descriptor_publish_supported_commands(unid, endpoint_id);
+ uic_mqtt_dotdot_unify_humidity_control_publish_supported_commands(unid, endpoint_id);
}
void uic_mqtt_dotdot_publish_empty_supported_commands(
@@ -95071,6 +96999,7 @@ void uic_mqtt_dotdot_publish_empty_supported_commands(
uic_mqtt_dotdot_aox_position_estimation_publish_empty_supported_commands(unid, endpoint_id);
uic_mqtt_dotdot_protocol_controller_network_management_publish_empty_supported_commands(unid);
uic_mqtt_dotdot_descriptor_publish_empty_supported_commands(unid, endpoint_id);
+ uic_mqtt_dotdot_unify_humidity_control_publish_empty_supported_commands(unid, endpoint_id);
}
// Publishing Cluster Revision for Basic Cluster
@@ -108533,6 +110462,216 @@ void uic_mqtt_dotdot_descriptor_publish_empty_supported_commands(
}
}
+// Publishing Cluster Revision for UnifyHumidityControl Cluster
+void uic_mqtt_dotdot_unify_humidity_control_publish_cluster_revision(const char* base_topic, uint16_t value)
+{
+ std::string cluster_topic = std::string(base_topic) + "/UnifyHumidityControl/Attributes/ClusterRevision";
+ // Publish Desired
+ std::string pub_topic_des = cluster_topic + "/Desired";
+ std::string payload = std::string(R"({"value": )")
+ + std::to_string(value) + std::string("}");
+ uic_mqtt_publish(pub_topic_des.c_str(),
+ payload.c_str(),
+ payload.size(),
+ true);
+ // Publish Reported
+ std::string pub_topic_rep = cluster_topic + "/Reported";
+ uic_mqtt_publish(pub_topic_rep.c_str(),
+ payload.c_str(),
+ payload.size(),
+ true);
+}
+
+// Unretain Cluster Revision for UnifyHumidityControl Cluster
+void uic_mqtt_dotdot_unify_humidity_control_unretain_cluster_revision(const char* base_topic)
+{
+ // clang-format on
+ std::string cluster_topic
+ = std::string(base_topic)
+ + "/UnifyHumidityControl/Attributes/ClusterRevision";
+ // Publish Desired
+ std::string desired_topic = cluster_topic + "/Desired";
+ uic_mqtt_publish(desired_topic.c_str(), NULL, 0, true);
+ // Publish Reported
+ std::string reported_topic = cluster_topic + "/Reported";
+ uic_mqtt_publish(reported_topic.c_str(), NULL, 0, true);
+ // clang-format off
+}
+
+static inline bool uic_mqtt_dotdot_unify_humidity_control_mode_set_is_supported(
+ const dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint_id)
+{
+ ModeType mode_value;
+ memset(&mode_value, 0x00, sizeof(mode_value));
+ for (const auto& callback: uic_mqtt_dotdot_unify_humidity_control_mode_set_callback) {
+ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK
+ ,
+ mode_value
+
+ ) == SL_STATUS_OK) {
+ return true;
+ }
+ }
+
+ return false;
+}
+static inline bool uic_mqtt_dotdot_unify_humidity_control_setpoint_set_is_supported(
+ const dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint_id)
+{
+ SetpointType type_value;
+ memset(&type_value, 0x00, sizeof(type_value));
+ uint8_t precision_value;
+ memset(&precision_value, 0x00, sizeof(precision_value));
+ uint8_t scale_value;
+ memset(&scale_value, 0x00, sizeof(scale_value));
+ int32_t value_value;
+ memset(&value_value, 0x00, sizeof(value_value));
+ for (const auto& callback: uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback) {
+ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK
+ ,
+ type_value,
+
+ precision_value,
+
+ scale_value,
+
+ value_value
+
+ ) == SL_STATUS_OK) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static inline bool uic_mqtt_dotdot_unify_humidity_control_write_attributes_is_supported(
+ const dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint_id)
+{
+ for (const auto& callback: uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback) {
+ uic_mqtt_dotdot_unify_humidity_control_state_t unify_humidity_control_new_state = {};
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t unify_humidity_control_new_updated_state = {};
+
+ if (callback(
+ unid,
+ endpoint_id,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK,
+ unify_humidity_control_new_state,
+ unify_humidity_control_new_updated_state
+ ) == SL_STATUS_OK) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static inline bool uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_is_supported(
+ const dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint_id)
+{
+ for (const auto& callback: uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback) {
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t unify_humidity_control_force_update = {0};
+ if (callback(
+ unid,
+ endpoint_id,
+ UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK,
+ unify_humidity_control_force_update
+ ) == SL_STATUS_OK) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Publishing Supported Commands for UnifyHumidityControl Cluster
+void uic_mqtt_dotdot_unify_humidity_control_publish_supported_commands(
+ const dotdot_unid_t unid,
+ dotdot_endpoint_id_t endpoint_id)
+{
+ std::stringstream ss;
+ bool first_command = true;
+ ss.str("");
+
+ // check if there is callback for each command
+ if (uic_mqtt_dotdot_unify_humidity_control_mode_set_is_supported(unid, endpoint_id)) {
+ if (first_command == false) {
+ ss << ", ";
+ }
+ first_command = false;
+ ss << R"("ModeSet")";
+ }
+ if (uic_mqtt_dotdot_unify_humidity_control_setpoint_set_is_supported(unid, endpoint_id)) {
+ if (first_command == false) {
+ ss << ", ";
+ }
+ first_command = false;
+ ss << R"("SetpointSet")";
+ }
+
+ // Check for a WriteAttributes Callback
+ if(uic_mqtt_dotdot_unify_humidity_control_write_attributes_is_supported(unid, endpoint_id)) {
+ if (first_command == false) {
+ ss << ", ";
+ }
+ first_command = false;
+ ss << R"("WriteAttributes")";
+ }
+
+ // Check for a ForceReadAttributes Callback
+ if (uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_is_supported(unid, endpoint_id)) {
+ if (first_command == false) {
+ ss << ", ";
+ }
+ first_command = false;
+ ss << R"("ForceReadAttributes")";
+ }
+
+ // Publish supported commands
+ std::string topic = "ucl/by-unid/" + std::string(unid);
+ topic += "/ep"+ std::to_string(endpoint_id);
+ topic += "/UnifyHumidityControl/SupportedCommands";
+ std::string payload_str("{\"value\": [" + ss.str() + "]" + "}");
+ if (first_command == false) {
+ uic_mqtt_publish(topic.c_str(),
+ payload_str.c_str(),
+ payload_str.length(),
+ true);
+ } else if (uic_mqtt_count_topics(topic.c_str()) == 0) {
+ // There are no supported commands, but make sure we publish some
+ // SupportedCommands = [] if any attribute has been published for a cluster.
+ std::string attributes_topic = "ucl/by-unid/" + std::string(unid);
+ attributes_topic += "/ep"+ std::to_string(endpoint_id);
+ attributes_topic += "/UnifyHumidityControl/Attributes";
+
+ if (uic_mqtt_count_topics(attributes_topic.c_str()) > 0) {
+ uic_mqtt_publish(topic.c_str(),
+ EMPTY_VALUE_ARRAY,
+ strlen(EMPTY_VALUE_ARRAY),
+ true);
+ }
+ }
+}
+
+// Publishing empty/no Supported Commands for UnifyHumidityControl Cluster
+void uic_mqtt_dotdot_unify_humidity_control_publish_empty_supported_commands(
+ const dotdot_unid_t unid
+ , dotdot_endpoint_id_t endpoint_id)
+{
+ std::string topic = "ucl/by-unid/" + std::string(unid);
+ topic += "/ep"+ std::to_string(endpoint_id);
+ topic += "/UnifyHumidityControl/SupportedCommands";
+
+ if (uic_mqtt_count_topics(topic.c_str()) > 0) {
+ uic_mqtt_publish(topic.c_str(),
+ EMPTY_VALUE_ARRAY,
+ strlen(EMPTY_VALUE_ARRAY),
+ true);
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
// Generated Commands publications functions
@@ -115181,3 +117320,75 @@ void uic_mqtt_dotdot_protocol_controller_network_management_publish_generated_wr
payload.size(),
false);
}
+/**
+ * @brief Publishes an incoming/generated ModeSet command for
+ * the UnifyHumidityControl cluster.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-unid/UNID/epID/UnifyHumidityControl/GeneratedCommands/ModeSet
+ *
+ * @param unid The UNID of the node that sent us the command.
+ *
+ * @param endpoint The Endpoint ID of the node that sent us the command.
+ *
+ *
+ * @param fields Struct pointer with the fields value of the command
+ *
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_generated_mode_set_command(
+ const dotdot_unid_t unid,
+ const dotdot_endpoint_id_t endpoint,
+ const uic_mqtt_dotdot_unify_humidity_control_command_mode_set_fields_t *fields
+
+) {
+ // Create the topic
+ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" +
+ std::to_string(endpoint) + "/";
+ topic += "UnifyHumidityControl/GeneratedCommands/ModeSet";
+
+ std::string payload =
+ get_json_payload_for_unify_humidity_control_mode_set_command(
+ fields);
+
+ // Publish our command
+ uic_mqtt_publish(topic.c_str(),
+ payload.c_str(),
+ payload.size(),
+ false);
+}
+/**
+ * @brief Publishes an incoming/generated SetpointSet command for
+ * the UnifyHumidityControl cluster.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-unid/UNID/epID/UnifyHumidityControl/GeneratedCommands/SetpointSet
+ *
+ * @param unid The UNID of the node that sent us the command.
+ *
+ * @param endpoint The Endpoint ID of the node that sent us the command.
+ *
+ *
+ * @param fields Struct pointer with the fields value of the command
+ *
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_generated_setpoint_set_command(
+ const dotdot_unid_t unid,
+ const dotdot_endpoint_id_t endpoint,
+ const uic_mqtt_dotdot_unify_humidity_control_command_setpoint_set_fields_t *fields
+
+) {
+ // Create the topic
+ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" +
+ std::to_string(endpoint) + "/";
+ topic += "UnifyHumidityControl/GeneratedCommands/SetpointSet";
+
+ std::string payload =
+ get_json_payload_for_unify_humidity_control_setpoint_set_command(
+ fields);
+
+ // Publish our command
+ uic_mqtt_publish(topic.c_str(),
+ payload.c_str(),
+ payload.size(),
+ false);
+}
diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.hpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.hpp
index 156e7b356d..1af04197bb 100644
--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.hpp
+++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.hpp
@@ -367,6 +367,13 @@ sl_status_t uic_mqtt_dotdot_by_group_aox_position_estimation_init();
*/
sl_status_t uic_mqtt_dotdot_by_group_descriptor_init();
+/**
+ * @brief Initialize UnifyHumidityControl dotdot bygroup command handlers
+ *
+ * @returns SL_STATUS_OK on success, error otherwise.
+ */
+sl_status_t uic_mqtt_dotdot_by_group_unify_humidity_control_init();
+
// clang-format on
@@ -5052,6 +5059,65 @@ void uic_mqtt_dotdot_on_descriptor_WriteAttributes(
const size_t message_length);
+// clang-format on
+
+/**
+ * @brief Retrieves the container with callbacks pointer for
+ * by-unid UnifyHumidityControl/Commands/ModeSet messages
+ *
+ * @returns std::set of callbacks.
+ */
+std::set &get_uic_mqtt_dotdot_unify_humidity_control_mode_set_callback();
+
+/**
+ * @brief MQTT Subscribe handler for incoming publications on:
+ * ucl/by-unid/+/+/UnifyHumidityControl/Commands/ModeSet
+ */
+// clang-format off
+void uic_mqtt_dotdot_on_unify_humidity_control_mode_set(
+ const char *topic,
+ const char *message,
+ const size_t message_length);
+// clang-format on
+
+/**
+ * @brief Retrieves the container with callbacks pointer for
+ * by-unid UnifyHumidityControl/Commands/SetpointSet messages
+ *
+ * @returns std::set of callbacks.
+ */
+std::set &get_uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback();
+
+/**
+ * @brief MQTT Subscribe handler for incoming publications on:
+ * ucl/by-unid/+/+/UnifyHumidityControl/Commands/SetpointSet
+ */
+// clang-format off
+void uic_mqtt_dotdot_on_unify_humidity_control_setpoint_set(
+ const char *topic,
+ const char *message,
+ const size_t message_length);
+// clang-format on
+
+/**
+ * @brief Retrieves the container with callback pointers for by-unid
+ * /Commands/WriteAttributes messages
+ *
+ * @returns std::set of callbacks.
+ */
+std::set & get_uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback();
+
+/**
+ * @brief MQTT Subscribe handler for incoming publications on:
+ * ucl/by-unid/+/+/UnifyHumidityControl/Commands/WriteAttributes
+ */
+// clang-format off
+void uic_mqtt_dotdot_on_unify_humidity_control_WriteAttributes(
+ const char *topic,
+ const char *message,
+ const size_t message_length);
+
+
// All bitmaps are defined as the cluster label for the bitmap plus the command/attribute name
@@ -5891,6 +5957,26 @@ const std::vector, std::vector, std::vector>>> UnifyHumidityControlSupportedReportingMode_bitmap_data {
+{ {"Humidify", "bool", "0x1", "0"}, {
+} },
+{ {"Dehumidify", "bool", "0x2", "1"}, {
+} },
+{ {"Auto", "bool", "0x4", "2"}, {
+} }
+};
+const dotdot_bitmap UnifyHumidityControlSupportedReportingMode("UnifyHumidityControlSupportedReportingMode", "Unknown UnifyHumidityControlSupportedReportingMode", UnifyHumidityControlSupportedReportingMode_bitmap_data);
+
+const std::vector, std::vector>>> UnifyHumidityControlSupportedSetPoints_bitmap_data {
+{ {"Humidifier", "bool", "0x1", "0"}, {
+} },
+{ {"Dehumidifier", "bool", "0x2", "1"}, {
+} },
+{ {"Auto", "bool", "0x4", "2"}, {
+} }
+};
+const dotdot_bitmap UnifyHumidityControlSupportedSetPoints("UnifyHumidityControlSupportedSetPoints", "Unknown UnifyHumidityControlSupportedSetPoints", UnifyHumidityControlSupportedSetPoints_bitmap_data);
+
const std::vector, std::vector>>> WindowCoveringConfigOrStatus_bitmap_data {
{ {"Operational", "bool", "0x1", "0"}, {
} },
diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_attributes.cpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_attributes.cpp
index 43090fc989..995736a59b 100644
--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_attributes.cpp
+++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_attributes.cpp
@@ -63117,3 +63117,1685 @@ void uic_mqtt_dotdot_descriptor_attribute_device_type_list_callback_set(const ui
// End of supported cluster.
+///////////////////////////////////////////////////////////////////////////////
+// Callback pointers for UnifyHumidityControl
+///////////////////////////////////////////////////////////////////////////////
+static uic_mqtt_dotdot_unify_humidity_control_attribute_reporting_mode_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_reporting_mode_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_supported_reporting_mode_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_supported_reporting_mode_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_current_state_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_current_state_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_supported_set_points_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_supported_set_points_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_min_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_min_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_max_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_max_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_scale_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_scale_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_precision_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_precision_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_min_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_min_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_max_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_max_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_scale_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_scale_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_precision_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_precision_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_min_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_min_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_max_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_max_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_scale_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_scale_callback = nullptr;
+static uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_precision_callback_t uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_precision_callback = nullptr;
+
+///////////////////////////////////////////////////////////////////////////////
+// Attribute update handlers for UnifyHumidityControl
+///////////////////////////////////////////////////////////////////////////////
+static void uic_mqtt_dotdot_on_unify_humidity_control_reporting_mode_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_reporting_mode_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ ModeType reporting_mode = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::ReportingMode: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ uint32_t tmp = get_enum_decimal_value("value", json_payload);
+ if (tmp == numeric_limits::max()) {
+ #ifdef UNIFY_HUMIDITY_CONTROL_REPORTING_MODE_ENUM_NAME_AVAILABLE
+ tmp = unify_humidity_control_reporting_mode_get_enum_value_number(json_payload.at("value").get());
+ #elif defined(REPORTING_MODE_ENUM_NAME_AVAILABLE)
+ tmp = reporting_mode_get_enum_value_number(json_payload.at("value").get());
+ #endif
+ }
+ reporting_mode = static_cast(tmp);
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_reporting_mode_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ reporting_mode
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_supported_reporting_mode_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_supported_reporting_mode_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ uint8_t supported_reporting_mode = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::SupportedReportingMode: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ supported_reporting_mode = uic_dotdot_mqtt::get_bitmap_decimal_value("value", json_payload, UnifyHumidityControlSupportedReportingMode);
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_supported_reporting_mode_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ supported_reporting_mode
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_current_state_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_current_state_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ uint8_t current_state = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::CurrentState: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ uint32_t tmp = get_enum_decimal_value("value", json_payload);
+ if (tmp == numeric_limits::max()) {
+ #ifdef UNIFY_HUMIDITY_CONTROL_CURRENT_STATE_ENUM_NAME_AVAILABLE
+ tmp = unify_humidity_control_current_state_get_enum_value_number(json_payload.at("value").get());
+ #elif defined(CURRENT_STATE_ENUM_NAME_AVAILABLE)
+ tmp = current_state_get_enum_value_number(json_payload.at("value").get());
+ #endif
+ }
+ current_state = static_cast(tmp);
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_current_state_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ current_state
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_supported_set_points_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_supported_set_points_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ uint8_t supported_set_points = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::SupportedSetPoints: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ supported_set_points = uic_dotdot_mqtt::get_bitmap_decimal_value("value", json_payload, UnifyHumidityControlSupportedSetPoints);
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_supported_set_points_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ supported_set_points
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_humidifier_setpoint_min_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_min_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ int32_t humidifier_setpoint_min = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::HumidifierSetpointMin: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ humidifier_setpoint_min = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_min_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ humidifier_setpoint_min
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_humidifier_setpoint_max_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_max_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ int32_t humidifier_setpoint_max = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::HumidifierSetpointMax: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ humidifier_setpoint_max = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_max_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ humidifier_setpoint_max
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_humidifier_setpoint_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ int32_t humidifier_setpoint = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::HumidifierSetpoint: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ humidifier_setpoint = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ humidifier_setpoint
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_humidifier_setpoint_scale_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_scale_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ ScaleType humidifier_setpoint_scale = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::HumidifierSetpointScale: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ uint32_t tmp = get_enum_decimal_value("value", json_payload);
+ if (tmp == numeric_limits::max()) {
+ #ifdef UNIFY_HUMIDITY_CONTROL_HUMIDIFIER_SETPOINT_SCALE_ENUM_NAME_AVAILABLE
+ tmp = unify_humidity_control_humidifier_setpoint_scale_get_enum_value_number(json_payload.at("value").get());
+ #elif defined(HUMIDIFIER_SETPOINT_SCALE_ENUM_NAME_AVAILABLE)
+ tmp = humidifier_setpoint_scale_get_enum_value_number(json_payload.at("value").get());
+ #endif
+ }
+ humidifier_setpoint_scale = static_cast(tmp);
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_scale_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ humidifier_setpoint_scale
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_humidifier_setpoint_precision_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_precision_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ uint8_t humidifier_setpoint_precision = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::HumidifierSetpointPrecision: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ humidifier_setpoint_precision = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_precision_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ humidifier_setpoint_precision
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_dehumidifier_setpoint_min_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_min_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ int32_t dehumidifier_setpoint_min = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::DehumidifierSetpointMin: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ dehumidifier_setpoint_min = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_min_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ dehumidifier_setpoint_min
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_dehumidifier_setpoint_max_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_max_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ int32_t dehumidifier_setpoint_max = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::DehumidifierSetpointMax: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ dehumidifier_setpoint_max = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_max_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ dehumidifier_setpoint_max
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_dehumidifier_setpoint_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ int32_t dehumidifier_setpoint = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::DehumidifierSetpoint: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ dehumidifier_setpoint = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ dehumidifier_setpoint
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_dehumidifier_setpoint_scale_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_scale_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ ScaleType dehumidifier_setpoint_scale = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::DehumidifierSetpointScale: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ uint32_t tmp = get_enum_decimal_value("value", json_payload);
+ if (tmp == numeric_limits::max()) {
+ #ifdef UNIFY_HUMIDITY_CONTROL_DEHUMIDIFIER_SETPOINT_SCALE_ENUM_NAME_AVAILABLE
+ tmp = unify_humidity_control_dehumidifier_setpoint_scale_get_enum_value_number(json_payload.at("value").get());
+ #elif defined(DEHUMIDIFIER_SETPOINT_SCALE_ENUM_NAME_AVAILABLE)
+ tmp = dehumidifier_setpoint_scale_get_enum_value_number(json_payload.at("value").get());
+ #endif
+ }
+ dehumidifier_setpoint_scale = static_cast(tmp);
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_scale_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ dehumidifier_setpoint_scale
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_dehumidifier_setpoint_precision_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_precision_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ uint8_t dehumidifier_setpoint_precision = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::DehumidifierSetpointPrecision: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ dehumidifier_setpoint_precision = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_precision_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ dehumidifier_setpoint_precision
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_auto_setpoint_min_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_min_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ int32_t auto_setpoint_min = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::AutoSetpointMin: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ auto_setpoint_min = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_min_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ auto_setpoint_min
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_auto_setpoint_max_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_max_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ int32_t auto_setpoint_max = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::AutoSetpointMax: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ auto_setpoint_max = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_max_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ auto_setpoint_max
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_auto_setpoint_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ int32_t auto_setpoint = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::AutoSetpoint: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ auto_setpoint = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ auto_setpoint
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_auto_setpoint_scale_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_scale_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ ScaleType auto_setpoint_scale = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::AutoSetpointScale: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ uint32_t tmp = get_enum_decimal_value("value", json_payload);
+ if (tmp == numeric_limits::max()) {
+ #ifdef UNIFY_HUMIDITY_CONTROL_AUTO_SETPOINT_SCALE_ENUM_NAME_AVAILABLE
+ tmp = unify_humidity_control_auto_setpoint_scale_get_enum_value_number(json_payload.at("value").get());
+ #elif defined(AUTO_SETPOINT_SCALE_ENUM_NAME_AVAILABLE)
+ tmp = auto_setpoint_scale_get_enum_value_number(json_payload.at("value").get());
+ #endif
+ }
+ auto_setpoint_scale = static_cast(tmp);
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_scale_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ auto_setpoint_scale
+ );
+
+}
+static void uic_mqtt_dotdot_on_unify_humidity_control_auto_setpoint_precision_attribute_update(
+ const char *topic,
+ const char *message,
+ const size_t message_length) {
+ if (uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_precision_callback == nullptr) {
+ return;
+ }
+
+ std::string unid;
+ uint8_t endpoint = 0; // Default value for endpoint-less topics.
+ if(! uic_dotdot_mqtt::parse_topic(topic,unid,endpoint)) {
+ sl_log_debug(LOG_TAG,
+ "Error parsing UNID / Endpoint ID from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ std::string last_item;
+ if (SL_STATUS_OK != uic_dotdot_mqtt::get_topic_last_item(topic,last_item)){
+ sl_log_debug(LOG_TAG,
+ "Error parsing last item from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ uic_mqtt_dotdot_attribute_update_type_t update_type;
+ if (last_item == "Reported") {
+ update_type = UCL_REPORTED_UPDATED;
+ } else if (last_item == "Desired") {
+ update_type = UCL_DESIRED_UPDATED;
+ } else {
+ sl_log_debug(LOG_TAG,
+ "Unknown value type (neither Desired/Reported) for topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Empty message means unretained value.
+ bool unretained = false;
+ if (message_length == 0) {
+ unretained = true;
+ }
+
+
+ uint8_t auto_setpoint_precision = {};
+
+ nlohmann::json json_payload;
+ try {
+
+ if (unretained == false) {
+ json_payload = nlohmann::json::parse(std::string(message));
+
+ if (json_payload.find("value") == json_payload.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::AutoSetpointPrecision: Missing attribute element: 'value'\n");
+ return;
+ }
+// Start parsing value
+ auto_setpoint_precision = json_payload.at("value").get();
+
+ // End parsing value
+ }
+
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message);
+ return;
+ }
+
+ uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_precision_callback(
+ static_cast(unid.c_str()),
+ endpoint,
+ unretained,
+ update_type,
+ auto_setpoint_precision
+ );
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Attribute init functions for UnifyHumidityControl
+///////////////////////////////////////////////////////////////////////////////
+sl_status_t uic_mqtt_dotdot_unify_humidity_control_attributes_init()
+{
+ std::string base_topic = "ucl/by-unid/+/+/";
+
+ std::string subscription_topic;
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_reporting_mode_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/ReportingMode/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_reporting_mode_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_supported_reporting_mode_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/SupportedReportingMode/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_supported_reporting_mode_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_current_state_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/CurrentState/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_current_state_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_supported_set_points_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/SupportedSetPoints/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_supported_set_points_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_min_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/HumidifierSetpointMin/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_humidifier_setpoint_min_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_max_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/HumidifierSetpointMax/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_humidifier_setpoint_max_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/HumidifierSetpoint/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_humidifier_setpoint_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_scale_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/HumidifierSetpointScale/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_humidifier_setpoint_scale_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_precision_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/HumidifierSetpointPrecision/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_humidifier_setpoint_precision_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_min_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/DehumidifierSetpointMin/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_dehumidifier_setpoint_min_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_max_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/DehumidifierSetpointMax/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_dehumidifier_setpoint_max_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/DehumidifierSetpoint/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_dehumidifier_setpoint_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_scale_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/DehumidifierSetpointScale/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_dehumidifier_setpoint_scale_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_precision_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/DehumidifierSetpointPrecision/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_dehumidifier_setpoint_precision_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_min_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/AutoSetpointMin/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_auto_setpoint_min_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_max_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/AutoSetpointMax/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_auto_setpoint_max_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/AutoSetpoint/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_auto_setpoint_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_scale_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/AutoSetpointScale/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_auto_setpoint_scale_attribute_update);
+ }
+ if(uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_precision_callback) {
+ subscription_topic = base_topic + "UnifyHumidityControl/Attributes/AutoSetpointPrecision/#";
+ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_humidity_control_auto_setpoint_precision_attribute_update);
+ }
+
+ return SL_STATUS_OK;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Callback setters and getters for UnifyHumidityControl
+///////////////////////////////////////////////////////////////////////////////
+void uic_mqtt_dotdot_unify_humidity_control_attribute_reporting_mode_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_reporting_mode_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_reporting_mode_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_supported_reporting_mode_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_supported_reporting_mode_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_supported_reporting_mode_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_current_state_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_current_state_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_current_state_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_supported_set_points_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_supported_set_points_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_supported_set_points_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_min_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_min_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_min_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_max_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_max_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_max_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_scale_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_scale_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_scale_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_precision_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_precision_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_humidifier_setpoint_precision_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_min_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_min_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_min_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_max_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_max_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_max_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_scale_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_scale_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_scale_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_precision_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_precision_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_dehumidifier_setpoint_precision_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_min_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_min_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_min_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_max_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_max_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_max_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_scale_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_scale_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_scale_callback = callback;
+}
+void uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_precision_callback_set(const uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_precision_callback_t callback)
+{
+ uic_mqtt_dotdot_unify_humidity_control_attribute_auto_setpoint_precision_callback = callback;
+}
+
+// End of supported cluster.
+
diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_command_helpers.cpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_command_helpers.cpp
index 0ee153812b..3d8f12ef68 100644
--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_command_helpers.cpp
+++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_command_helpers.cpp
@@ -14797,5 +14797,165 @@ void uic_mqtt_dotdot_parse_descriptor_write_attributes(
+}
+
+
+std::string get_json_payload_for_unify_humidity_control_mode_set_command(
+
+ const uic_mqtt_dotdot_unify_humidity_control_command_mode_set_fields_t *fields
+
+){
+ bool command_with_no_fields = true;
+
+ // Create a JSON payload from all the parameters
+ nlohmann::json json_payload;
+ command_with_no_fields = false;
+ // Single Value
+ // Enum ModeSet / Mode
+ #ifdef MODE_SET_MODE_ENUM_NAME_AVAILABLE
+ // Pick up the name from the value.
+ json_payload["Mode"] =
+ mode_set_mode_get_enum_value_name(
+ (uint32_t)fields->mode);
+ #elif defined(MODE_TYPE_ENUM_NAME_AVAILABLE)
+ json_payload["Mode"] =
+ mode_type_get_enum_value_name((uint32_t)fields->mode);
+ #else
+ // If there is no name value for the enum, just write it directly.
+ json_payload["Mode"] = fields->mode;
+ #endif
+
+ // Get the string
+ if (command_with_no_fields == true) {
+ return std::string("{}");
+ }
+ // Payload may contain data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ return json_payload.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+}
+
+
+void uic_mqtt_dotdot_parse_unify_humidity_control_mode_set(
+ nlohmann::json &jsn,
+ ModeType &mode
+
+) {
+
+ uint32_t Mode_enum_val = get_enum_decimal_value("Mode", jsn);
+ if (Mode_enum_val == std::numeric_limits::max()) {
+ #ifdef MODE_TYPE_ENUM_NAME_AVAILABLE
+ Mode_enum_val = mode_type_get_enum_value_number(jsn.at("Mode").get());
+ #endif
+ }
+ if (jsn.at("Mode").is_null()) {
+ sl_log_debug(LOG_TAG, "Ignoring JSON Null object");
+ return;
+ }
+ mode = static_cast(Mode_enum_val);
+}
+
+
+std::string get_json_payload_for_unify_humidity_control_setpoint_set_command(
+
+ const uic_mqtt_dotdot_unify_humidity_control_command_setpoint_set_fields_t *fields
+
+){
+ bool command_with_no_fields = true;
+
+ // Create a JSON payload from all the parameters
+ nlohmann::json json_payload;
+ command_with_no_fields = false;
+ // Single Value
+ // Enum SetpointSet / Type
+ #ifdef SETPOINT_SET_TYPE_ENUM_NAME_AVAILABLE
+ // Pick up the name from the value.
+ json_payload["Type"] =
+ setpoint_set_type_get_enum_value_name(
+ (uint32_t)fields->type);
+ #elif defined(SETPOINT_TYPE_ENUM_NAME_AVAILABLE)
+ json_payload["Type"] =
+ setpoint_type_get_enum_value_name((uint32_t)fields->type);
+ #else
+ // If there is no name value for the enum, just write it directly.
+ json_payload["Type"] = fields->type;
+ #endif
+ command_with_no_fields = false;
+ // Single Value
+ // Non-enum and non-bitmask (struct, string or scalar)
+ json_payload["Precision"] = nlohmann::json(fields->precision);
+ command_with_no_fields = false;
+ // Single Value
+ // Non-enum and non-bitmask (struct, string or scalar)
+ json_payload["Scale"] = nlohmann::json(fields->scale);
+ command_with_no_fields = false;
+ // Single Value
+ // Non-enum and non-bitmask (struct, string or scalar)
+ json_payload["Value"] = nlohmann::json(fields->value);
+
+ // Get the string
+ if (command_with_no_fields == true) {
+ return std::string("{}");
+ }
+ // Payload may contain data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ return json_payload.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+}
+
+
+void uic_mqtt_dotdot_parse_unify_humidity_control_setpoint_set(
+ nlohmann::json &jsn,
+ SetpointType &type,
+
+ uint8_t &precision,
+
+ uint8_t &scale,
+
+ int32_t &value
+
+) {
+
+ uint32_t Type_enum_val = get_enum_decimal_value("Type", jsn);
+ if (Type_enum_val == std::numeric_limits::max()) {
+ #ifdef SETPOINT_TYPE_ENUM_NAME_AVAILABLE
+ Type_enum_val = setpoint_type_get_enum_value_number(jsn.at("Type").get());
+ #endif
+ }
+ if (jsn.at("Type").is_null()) {
+ sl_log_debug(LOG_TAG, "Ignoring JSON Null object");
+ return;
+ }
+ type = static_cast(Type_enum_val);
+ if (jsn.at("Precision").is_null()) {
+ sl_log_debug(LOG_TAG, "Ignoring JSON Null object");
+ return;
+ }
+
+ precision = jsn.at("Precision").get< uint8_t >();
+ if (jsn.at("Scale").is_null()) {
+ sl_log_debug(LOG_TAG, "Ignoring JSON Null object");
+ return;
+ }
+
+ scale = jsn.at("Scale").get< uint8_t >();
+ if (jsn.at("Value").is_null()) {
+ sl_log_debug(LOG_TAG, "Ignoring JSON Null object");
+ return;
+ }
+
+ value = jsn.at("Value").get< int32_t >();
+ }
+
+
+/**
+ * @brief JSON parser for ::WriteAttributes command arguments.
+ *
+ * Parse incoming JSON object to populate command arguments passed in by reference.
+ */
+void uic_mqtt_dotdot_parse_unify_humidity_control_write_attributes(
+ nlohmann::json &jsn,
+ uic_mqtt_dotdot_unify_humidity_control_state_t &new_state,
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t &new_updated_state
+) {
+
+
+
}
diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_command_helpers.hpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_command_helpers.hpp
index 21f137181d..43736077e7 100644
--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_command_helpers.hpp
+++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_command_helpers.hpp
@@ -6071,6 +6071,80 @@ void uic_mqtt_dotdot_parse_descriptor_write_attributes(
);
+/**
+ * @brief Private helper function that will create a JSON string based on the
+ * fields of a UnifyHumidityControl ModeSet command
+ *
+ * @param fields Struct pointer with the list of fields for the command
+ *
+ * @returns std::string that contains JSON payload
+ */
+std::string get_json_payload_for_unify_humidity_control_mode_set_command(
+
+ const uic_mqtt_dotdot_unify_humidity_control_command_mode_set_fields_t *fields
+
+);
+
+
+/**
+ * @brief JSON parser for UnifyHumidityControl ModeSet command arguments.
+ *
+ * Parse incoming JSON object to populate command arguments passed in by reference.
+ */
+void uic_mqtt_dotdot_parse_unify_humidity_control_mode_set(
+ nlohmann::json &jsn,
+ ModeType &mode
+
+);
+
+
+
+/**
+ * @brief Private helper function that will create a JSON string based on the
+ * fields of a UnifyHumidityControl SetpointSet command
+ *
+ * @param fields Struct pointer with the list of fields for the command
+ *
+ * @returns std::string that contains JSON payload
+ */
+std::string get_json_payload_for_unify_humidity_control_setpoint_set_command(
+
+ const uic_mqtt_dotdot_unify_humidity_control_command_setpoint_set_fields_t *fields
+
+);
+
+
+/**
+ * @brief JSON parser for UnifyHumidityControl SetpointSet command arguments.
+ *
+ * Parse incoming JSON object to populate command arguments passed in by reference.
+ */
+void uic_mqtt_dotdot_parse_unify_humidity_control_setpoint_set(
+ nlohmann::json &jsn,
+ SetpointType &type,
+
+ uint8_t &precision,
+
+ uint8_t &scale,
+
+ int32_t &value
+
+);
+
+
+
+/**
+ * @brief JSON parser for UnifyHumidityControl WriteAttributes command arguments.
+ *
+ * Parse incoming JSON object to populate command arguments passed in by reference.
+ */
+void uic_mqtt_dotdot_parse_unify_humidity_control_write_attributes(
+ nlohmann::json &jsn,
+ uic_mqtt_dotdot_unify_humidity_control_state_t &new_state,
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t &new_updated_state
+);
+
+
#endif //DOTDOT_MQTT_COMMAND_HELPERS_HPP
/** @} end dotdot_mqtt_command_helpers */
diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_generated_commands.cpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_generated_commands.cpp
index a09f1a69cf..20fae62a03 100644
--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_generated_commands.cpp
+++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_generated_commands.cpp
@@ -11396,3 +11396,115 @@ void uic_mqtt_dotdot_descriptor_publish_generated_write_attributes_command(
false);
}
+/**
+ * @brief Publishes an incoming/generated ModeSet command for
+ * the UnifyHumidityControl cluster.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-unid/UNID/epID/UnifyHumidityControl/GeneratedCommands/ModeSet
+ *
+ * @param unid The UNID of the node that sent us the command.
+ *
+ * @param endpoint The Endpoint ID of the node that sent us the command.
+ *
+ *
+ * @param fields Struct pointer with the fields value of the command
+ *
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_generated_mode_set_command(
+ const dotdot_unid_t unid,
+ const dotdot_endpoint_id_t endpoint,
+ const uic_mqtt_dotdot_unify_humidity_control_command_mode_set_fields_t *fields
+
+) {
+ // Create the topic
+ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" +
+ std::to_string(endpoint) + "/";
+ topic += "UnifyHumidityControl/GeneratedCommands/ModeSet";
+
+ std::string payload =
+ get_json_payload_for_unify_humidity_control_mode_set_command(
+ fields);
+
+ // Publish our command
+ uic_mqtt_publish(topic.c_str(),
+ payload.c_str(),
+ payload.size(),
+ false);
+}
+/**
+ * @brief Publishes an incoming/generated SetpointSet command for
+ * the UnifyHumidityControl cluster.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-unid/UNID/epID/UnifyHumidityControl/GeneratedCommands/SetpointSet
+ *
+ * @param unid The UNID of the node that sent us the command.
+ *
+ * @param endpoint The Endpoint ID of the node that sent us the command.
+ *
+ *
+ * @param fields Struct pointer with the fields value of the command
+ *
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_generated_setpoint_set_command(
+ const dotdot_unid_t unid,
+ const dotdot_endpoint_id_t endpoint,
+ const uic_mqtt_dotdot_unify_humidity_control_command_setpoint_set_fields_t *fields
+
+) {
+ // Create the topic
+ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" +
+ std::to_string(endpoint) + "/";
+ topic += "UnifyHumidityControl/GeneratedCommands/SetpointSet";
+
+ std::string payload =
+ get_json_payload_for_unify_humidity_control_setpoint_set_command(
+ fields);
+
+ // Publish our command
+ uic_mqtt_publish(topic.c_str(),
+ payload.c_str(),
+ payload.size(),
+ false);
+}
+
+
+/**
+ * @brief Publishes an incoming/generated WriteAttributes command for
+ * the UnifyHumidityControl cluster.
+ *
+ * Publication will be made at the following topic
+ * ucl/by-unid/UNID/epID/UnifyHumidityControl/GeneratedCommands/WriteAttributes
+ *
+ * @param unid The UNID of the node that sent us the command.
+ *
+ * @param endpoint The Endpoint ID of the node that sent us the command.
+ *
+ * @param attribute_values Values to assign to the attributes
+ * @param attribute_list List of attributes that are written
+ */
+void uic_mqtt_dotdot_unify_humidity_control_publish_generated_write_attributes_command(
+ const dotdot_unid_t unid,
+ const dotdot_endpoint_id_t endpoint,
+ uic_mqtt_dotdot_unify_humidity_control_state_t attribute_values,
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t attribute_list
+){
+ // Create the topic
+ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" +
+ std::to_string(endpoint) + "/";
+ topic += "UnifyHumidityControl/GeneratedCommands/WriteAttributes";
+
+ nlohmann::json json_object = nlohmann::json::object();
+
+
+ // Payload contains data from end nodes, which we cannot control, thus we handle if there are non-utf8 characters
+ std::string payload = json_object.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
+
+ // Publish our command
+ uic_mqtt_publish(topic.c_str(),
+ payload.c_str(),
+ payload.size(),
+ false);
+}
+
diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_group_commands.cpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_group_commands.cpp
index 5d85d166d8..040a7a29b7 100644
--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_group_commands.cpp
+++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_group_commands.cpp
@@ -366,6 +366,11 @@ static uic_mqtt_dotdot_by_group_aox_position_estimation_write_attributes_callbac
static uic_mqtt_dotdot_by_group_descriptor_write_attributes_callback_t uic_mqtt_dotdot_by_group_descriptor_write_attributes_callback = nullptr;
+static uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback_t uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback = nullptr;
+static uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback_t uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback = nullptr;
+static uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback_t uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback = nullptr;
+
+
// Callbacks setters
@@ -1876,6 +1881,27 @@ void uic_mqtt_dotdot_by_group_descriptor_write_attributes_callback_set(
+// Callbacks setters
+
+void uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback_set(const uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback_t callback)
+{
+ uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback = callback;
+}
+
+
+void uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback_set(const uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback_t callback)
+{
+ uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback = callback;
+}
+
+void uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback_set(
+ const uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback_t callback)
+{
+ uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback = callback;
+}
+
+
+
// Callback function for incoming publications on ucl/by-group/+/Basic/Commands/ResetToFactoryDefaults
static void uic_mqtt_dotdot_on_by_group_basic_reset_to_factory_defaults(
@@ -23492,6 +23518,287 @@ sl_status_t uic_mqtt_dotdot_by_group_descriptor_init()
+
+// Callback function for incoming publications on ucl/by-group/+/UnifyHumidityControl/Commands/ModeSet
+static void uic_mqtt_dotdot_on_by_group_unify_humidity_control_mode_set(
+ const char *topic,
+ const char *message,
+ const size_t message_length)
+{
+ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback == nullptr)) {
+ return;
+ }
+ if (message_length == 0) {
+ return;
+ }
+
+ dotdot_group_id_t group_id = 0U;
+ if(!uic_dotdot_mqtt::parse_topic_group_id(topic,group_id)) {
+ sl_log_debug(LOG_TAG,
+ "Failed to parse GroupId from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Pass to command-specific callback if set. Otherwise, pass to
+ // group-dispatch callback
+ if (uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback != nullptr) {
+
+
+ uic_mqtt_dotdot_unify_humidity_control_command_mode_set_fields_t fields;
+
+
+ nlohmann::json jsn;
+ try {
+ jsn = nlohmann::json::parse(std::string(message));
+
+
+ uic_mqtt_dotdot_parse_unify_humidity_control_mode_set(
+ jsn,
+ fields.mode
+ );
+
+ // Populate list fields from vector or string types
+
+
+ } catch (const nlohmann::json::parse_error& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyHumidityControl", "ModeSet");
+ return;
+ } catch (const nlohmann::json::exception& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "ModeSet", e.what());
+ return;
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "ModeSet", "");
+ return;
+ }
+
+ uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback(
+ group_id,
+ &fields
+ );
+ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_humidity_control_mode_set_callback().empty())) {
+ // group-dispatch callback only called if the command-specific by-unid
+ // callback is set
+ try {
+ nlohmann::json jsn = nlohmann::json::parse(std::string(message));
+ if (jsn.find("Mode") == jsn.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::ModeSet: Missing command-argument: Mode\n");
+ return;
+ }
+
+ group_dispatch_callback(
+ group_id,
+ "UnifyHumidityControl",
+ "ModeSet",
+ message,
+ message_length,
+ uic_mqtt_dotdot_on_unify_humidity_control_mode_set);
+
+ } catch (...) {
+ sl_log_debug(LOG_TAG, "ModeSet: Unable to parse JSON payload.\n");
+ return;
+ }
+ }
+
+}
+
+// Callback function for incoming publications on ucl/by-group/+/UnifyHumidityControl/Commands/SetpointSet
+static void uic_mqtt_dotdot_on_by_group_unify_humidity_control_setpoint_set(
+ const char *topic,
+ const char *message,
+ const size_t message_length)
+{
+ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback == nullptr)) {
+ return;
+ }
+ if (message_length == 0) {
+ return;
+ }
+
+ dotdot_group_id_t group_id = 0U;
+ if(!uic_dotdot_mqtt::parse_topic_group_id(topic,group_id)) {
+ sl_log_debug(LOG_TAG,
+ "Failed to parse GroupId from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ // Pass to command-specific callback if set. Otherwise, pass to
+ // group-dispatch callback
+ if (uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback != nullptr) {
+
+
+ uic_mqtt_dotdot_unify_humidity_control_command_setpoint_set_fields_t fields;
+
+
+ nlohmann::json jsn;
+ try {
+ jsn = nlohmann::json::parse(std::string(message));
+
+
+ uic_mqtt_dotdot_parse_unify_humidity_control_setpoint_set(
+ jsn,
+ fields.type,
+
+ fields.precision,
+
+ fields.scale,
+
+ fields.value
+ );
+
+ // Populate list fields from vector or string types
+
+
+ } catch (const nlohmann::json::parse_error& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyHumidityControl", "SetpointSet");
+ return;
+ } catch (const nlohmann::json::exception& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "SetpointSet", e.what());
+ return;
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "SetpointSet", "");
+ return;
+ }
+
+ uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback(
+ group_id,
+ &fields
+ );
+ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback().empty())) {
+ // group-dispatch callback only called if the command-specific by-unid
+ // callback is set
+ try {
+ nlohmann::json jsn = nlohmann::json::parse(std::string(message));
+ if (jsn.find("Type") == jsn.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::SetpointSet: Missing command-argument: Type\n");
+ return;
+ }
+ if (jsn.find("Precision") == jsn.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::SetpointSet: Missing command-argument: Precision\n");
+ return;
+ }
+ if (jsn.find("Scale") == jsn.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::SetpointSet: Missing command-argument: Scale\n");
+ return;
+ }
+ if (jsn.find("Value") == jsn.end()) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl::SetpointSet: Missing command-argument: Value\n");
+ return;
+ }
+
+ group_dispatch_callback(
+ group_id,
+ "UnifyHumidityControl",
+ "SetpointSet",
+ message,
+ message_length,
+ uic_mqtt_dotdot_on_unify_humidity_control_setpoint_set);
+
+ } catch (...) {
+ sl_log_debug(LOG_TAG, "SetpointSet: Unable to parse JSON payload.\n");
+ return;
+ }
+ }
+
+}
+
+static void uic_mqtt_dotdot_on_by_group_unify_humidity_control_WriteAttributes(
+ const char *topic,
+ const char *message,
+ const size_t message_length)
+{
+
+ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback == nullptr)) {
+ return;
+ }
+ if (message_length == 0) {
+ return;
+ }
+
+ dotdot_group_id_t group_id = 0U;
+ if(!uic_dotdot_mqtt::parse_topic_group_id(topic,group_id)) {
+ sl_log_debug(LOG_TAG,
+ "Failed to parse GroupId from topic %s. Ignoring",
+ topic);
+ return;
+ }
+
+ if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback().empty())) {
+ try {
+ group_dispatch_callback(group_id,
+ "UnifyHumidityControl",
+ "WriteAttributes",
+ message,
+ message_length,
+ uic_mqtt_dotdot_on_unify_humidity_control_WriteAttributes);
+
+ } catch (...) {
+ sl_log_debug(LOG_TAG, "UnifyHumidityControl: Unable to parse JSON payload.\n");
+ return;
+ }
+ } else if (uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback != nullptr) {
+
+ uic_mqtt_dotdot_unify_humidity_control_state_t new_state = {};
+ uic_mqtt_dotdot_unify_humidity_control_updated_state_t new_updated_state = {};
+
+
+ nlohmann::json jsn;
+ try {
+ jsn = nlohmann::json::parse(std::string(message));
+
+ uic_mqtt_dotdot_parse_unify_humidity_control_write_attributes(
+ jsn,
+ new_state,
+ new_updated_state
+ );
+ } catch (const nlohmann::json::parse_error& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyHumidityControl", "WriteAttributes");
+ return;
+ } catch (const nlohmann::json::exception& e) {
+ // Catch JSON object field parsing errors
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "WriteAttributes", e.what());
+ return;
+ } catch (const std::exception& e) {
+ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyHumidityControl", "WriteAttributes", "");
+ return;
+ }
+
+ uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback(
+ group_id,
+ new_state,
+ new_updated_state
+ );
+ }
+}
+
+sl_status_t uic_mqtt_dotdot_by_group_unify_humidity_control_init()
+{
+ std::string subscription_topic;
+ const std::string topic_bygroup = TOPIC_BY_GROUP_PREFIX;
+ if(uic_mqtt_dotdot_by_group_unify_humidity_control_write_attributes_callback) {
+ subscription_topic = topic_bygroup + "UnifyHumidityControl/Commands/WriteAttributes";
+ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_humidity_control_WriteAttributes);
+ }
+ if (uic_mqtt_dotdot_by_group_unify_humidity_control_mode_set_callback) {
+ subscription_topic = topic_bygroup + "UnifyHumidityControl/Commands/ModeSet";
+ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_humidity_control_mode_set);
+ }
+ if (uic_mqtt_dotdot_by_group_unify_humidity_control_setpoint_set_callback) {
+ subscription_topic = topic_bygroup + "UnifyHumidityControl/Commands/SetpointSet";
+ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_humidity_control_setpoint_set);
+ }
+
+ return SL_STATUS_OK;
+}
+
+
+
void uic_mqtt_dotdot_set_group_dispatch_callback(group_dispatch_t callback)
{
// Check for uninitialized value in order to subscribe with on_group handlers
@@ -23773,6 +24080,10 @@ void uic_mqtt_dotdot_set_group_dispatch_callback(group_dispatch_t callback)
uic_mqtt_subscribe("ucl/by-group/+/Descriptor/Commands/WriteAttributes", uic_mqtt_dotdot_on_by_group_descriptor_WriteAttributes);
+ uic_mqtt_subscribe("ucl/by-group/+/UnifyHumidityControl/Commands/WriteAttributes", uic_mqtt_dotdot_on_by_group_unify_humidity_control_WriteAttributes);
+ uic_mqtt_subscribe("ucl/by-group/+/UnifyHumidityControl/Commands/ModeSet", uic_mqtt_dotdot_on_by_group_unify_humidity_control_mode_set);
+ uic_mqtt_subscribe("ucl/by-group/+/UnifyHumidityControl/Commands/SetpointSet", uic_mqtt_dotdot_on_by_group_unify_humidity_control_setpoint_set);
+
}
group_dispatch_callback = callback;
diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_helpers.cpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_helpers.cpp
index e777d585ab..02814ecf9f 100644
--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_helpers.cpp
+++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_helpers.cpp
@@ -3308,6 +3308,47 @@ uint32_t metering_unitof_measure_get_enum_value_number(const std::string &str)
return std::numeric_limits::max();
}
+// Enum to string map for ModeType
+const std::map mode_type_enum_id_to_string_map {
+ { 0, "Off" },
+ { 1, "Humidify" },
+ { 2, "Dehumidify" },
+ { 3, "Auto" },
+};
+
+// String to enum map for ModeType
+const std::map mode_type_enum_string_to_id_map {
+ { "Off", 0 },
+ { "Humidify", 1 },
+ { "Dehumidify", 2 },
+ { "Auto", 3 },
+};
+
+std::string mode_type_get_enum_value_name(
+ uint32_t value)
+{
+ auto it = mode_type_enum_id_to_string_map.find(value);
+ if (it != mode_type_enum_id_to_string_map.end()){
+ return it->second;
+ }
+
+ // No known name value is set for this field.
+ // Set it to a string version of the value.
+ return std::to_string(value);
+}
+
+uint32_t mode_type_get_enum_value_number(const std::string &str)
+{
+ auto it = mode_type_enum_string_to_id_map.find(str);
+ if (it != mode_type_enum_string_to_id_map.end()){
+ return it->second;
+ }
+
+ // No known numeric value is set for this string.
+ // Return UINT32_MAX to indicate an error.
+ return std::numeric_limits::max();
+}
+
// Enum to string map for MoveStepMode
const std::map move_step_mode_enum_id_to_string_map {
{ 0, "Up" },
@@ -4131,6 +4172,43 @@ uint32_t shdcfg_direction_get_enum_value_number(const std::string &str)
return std::numeric_limits::max();
}
+// Enum to string map for ScaleType
+const std::map scale_type_enum_id_to_string_map {
+ { 0, "Percentage" },
+ { 1, "Absolute" },
+};
+
+// String to enum map for ScaleType
+const std::map scale_type_enum_string_to_id_map {
+ { "Percentage", 0 },
+ { "Absolute", 1 },
+};
+
+std::string scale_type_get_enum_value_name(
+ uint32_t value)
+{
+ auto it = scale_type_enum_id_to_string_map.find(value);
+ if (it != scale_type_enum_id_to_string_map.end()){
+ return it->second;
+ }
+
+ // No known name value is set for this field.
+ // Set it to a string version of the value.
+ return std::to_string(value);
+}
+
+uint32_t scale_type_get_enum_value_number(const std::string &str)
+{
+ auto it = scale_type_enum_string_to_id_map.find(str);
+ if (it != scale_type_enum_string_to_id_map.end()){
+ return it->second;
+ }
+
+ // No known numeric value is set for this string.
+ // Return UINT32_MAX to indicate an error.
+ return std::numeric_limits::max();
+}
+
// Enum to string map for SetpointRaiseOrLowerMode
const std::map setpoint_raise_or_lower_mode_enum_id_to_string_map {
{ 0, "Heat" },
@@ -4170,6 +4248,45 @@ uint32_t setpoint_raise_or_lower_mode_get_enum_value_number(const std::string &s
return std::numeric_limits::max();
}
+// Enum to string map for SetpointType
+const std::map setpoint_type_enum_id_to_string_map {
+ { 1, "Humidifier" },
+ { 2, "Dehumidifier" },
+ { 3, "Auto" },
+};
+
+// String to enum map for SetpointType
+const std::map setpoint_type_enum_string_to_id_map {
+ { "Humidifier", 1 },
+ { "Dehumidifier", 2 },
+ { "Auto", 3 },
+};
+
+std::string setpoint_type_get_enum_value_name(
+ uint32_t value)
+{
+ auto it = setpoint_type_enum_id_to_string_map.find(value);
+ if (it != setpoint_type_enum_id_to_string_map.end()){
+ return it->second;
+ }
+
+ // No known name value is set for this field.
+ // Set it to a string version of the value.
+ return std::to_string(value);
+}
+
+uint32_t setpoint_type_get_enum_value_number(const std::string &str)
+{
+ auto it = setpoint_type_enum_string_to_id_map.find(str);
+ if (it != setpoint_type_enum_string_to_id_map.end()){
+ return it->second;
+ }
+
+ // No known numeric value is set for this string.
+ // Return UINT32_MAX to indicate an error.
+ return std::numeric_limits::max();
+}
+
// Enum to string map for ShadeConfigurationMode
const std::map shade_configuration_mode_enum_id_to_string_map {
{ 0, "Normal" },
@@ -5064,6 +5181,45 @@ uint32_t tx_report_transmission_speed_get_enum_value_number(const std::string &s
return std::numeric_limits::max();
}
+// Enum to string map for UnifyHumidityControlCurrentState
+const std::map unify_humidity_control_current_state_enum_id_to_string_map {
+ { 0, "Idle" },
+ { 1, "Humidifying" },
+ { 2, "Dehumidifying" },
+};
+
+// String to enum map for UnifyHumidityControlCurrentState
+const std::map