From 6917f5a760a9bd3d1f7d1dea543850e52783d5f4 Mon Sep 17 00:00:00 2001 From: Philippe Coval Date: Fri, 12 Sep 2025 17:28:38 +0200 Subject: [PATCH 01/12] p/UnifySDK: Import UnifySDK patches for multilevel sensor command class update [Philippe Coval] Add exported changes Forwarded: https://github.com/SiliconLabsSoftware/z-wave-protocol-controller/pull/143 Signed-off-by: Philippe Coval --- ...-Allow-to-regenerate-files-using-zap.patch | 37 + ...ustom-Unify_MultilevelSensor-cluster.patch | 538 +++ ...ed-files-for-Unify_MultilevelSensor-.patch | 3672 +++++++++++++++++ ...ed-files-for-Unify_MultilevelSensor-.patch | 101 + 4 files changed, 4348 insertions(+) create mode 100644 patches/UnifySDK/0007-fix-build-Allow-to-regenerate-files-using-zap.patch create mode 100644 patches/UnifySDK/0008-UIC-3273-Custom-Unify_MultilevelSensor-cluster.patch create mode 100644 patches/UnifySDK/0009-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch create mode 100644 patches/UnifySDK/0010-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch diff --git a/patches/UnifySDK/0007-fix-build-Allow-to-regenerate-files-using-zap.patch b/patches/UnifySDK/0007-fix-build-Allow-to-regenerate-files-using-zap.patch new file mode 100644 index 000000000..49e2f7541 --- /dev/null +++ b/patches/UnifySDK/0007-fix-build-Allow-to-regenerate-files-using-zap.patch @@ -0,0 +1,37 @@ +From f1b677b4127c8776244b272bcf20c9afeebe5522 Mon Sep 17 00:00:00 2001 +From: Philippe Coval +Date: Mon, 15 Sep 2025 10:43:26 +0200 +Subject: [PATCH] fix(build): Allow to regenerate files using zap + +For the record, files can be regenerated from developer using: + + rm -rf build ; cmake_options=-DZAP_GENERATE=ON ./helper.mk + +For some reasons developer will have to commit also generated files, +which is a bad practice, but I believe it was intentional to avoid +propagation to zap as build dependency, this may be revised to avoid +serialization of development. + +Relate-to: https://github.com/project-chip/zap/releases/download/v2025.07.24/zap-linux-x64.deb +Bug-SiliconLabs: UIC-3222 +Signed-off-by: Philippe Coval +--- + helper.mk | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/helper.mk b/helper.mk +index be052d5af6..75d1051981 100755 +--- a/helper.mk ++++ b/helper.mk +@@ -16,7 +16,7 @@ project?=unifysdk + BUILD_DEV_GUI?=OFF + BUILD_IMAGE_PROVIDER?=ON + +-cmake_options?=-B ${build_dir} ++cmake_options+=-B ${build_dir} + + CMAKE_GENERATOR?=Ninja + export CMAKE_GENERATOR +-- +2.39.5 + diff --git a/patches/UnifySDK/0008-UIC-3273-Custom-Unify_MultilevelSensor-cluster.patch b/patches/UnifySDK/0008-UIC-3273-Custom-Unify_MultilevelSensor-cluster.patch new file mode 100644 index 000000000..06f6ef334 --- /dev/null +++ b/patches/UnifySDK/0008-UIC-3273-Custom-Unify_MultilevelSensor-cluster.patch @@ -0,0 +1,538 @@ +From 049707c76ce7f322abe1ef54a1c5b568dc4599ba Mon Sep 17 00:00:00 2001 +From: ptphan +Date: Wed, 2 Oct 2024 10:40:35 +0700 +Subject: [PATCH] UIC-3273: Custom Unify_MultilevelSensor cluster + +[Philippe Coval] + +This patch was split in two, this version is the change that apply to +Unify, please refer to previous commit to undestand the flow, I after +the failed cherry-pick, I just used patch -p1 < patch and commited +only the changes that applies to Unify, the same operation should be +done for z-p-c project (in the opposite way). + +Origin: ver_1.7.0-unstable-23-g38f24ffb48 +Bug-SiliconLabs: UIC-3273 +Origin: s.s.com/projects/UIC/repos/uic/pull-requests/2855 +Relate-to: https://github.com/SiliconLabsSoftware/z-wave-protocol-controller/issues/44 +Forwarded: https://github.com/rzr/UnifySDK/tree/z-wave/core/zpc/main +Forwarded: https://github.com/SiliconLabsSoftware/z-wave-protocol-controller/pull/143 +Signed-off-by: Philippe Coval +--- + .../multilevel_sensor_cluster_server.cpp | 181 ++++++++++++++++++ + .../multilevel_sensor_cluster_server.h | 44 +++++ + .../zcl_cluster_servers/CMakeLists.txt | 46 +++++ + .../src/zcl_cluster_servers.cpp | 55 ++++++ + .../dotdot-xml/Unify_MultilevelSensor.xml | 121 ++++++++++++ + components/uic_dotdot/dotdot-xml/library.xml | 1 + + components/uic_dotdot/zap/addon-helper.js | 1 + + 7 files changed, 449 insertions(+) + create mode 100644 applications/examples/applications/emulated_end_device/components/eed_attribute_store/include/multilevel_sensor_cluster_server.cpp + create mode 100644 applications/examples/applications/emulated_end_device/components/eed_attribute_store/include/multilevel_sensor_cluster_server.h + create mode 100644 applications/zpc/components/zcl_cluster_servers/CMakeLists.txt + create mode 100644 applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp + create mode 100644 components/uic_dotdot/dotdot-xml/Unify_MultilevelSensor.xml + +diff --git a/applications/examples/applications/emulated_end_device/components/eed_attribute_store/include/multilevel_sensor_cluster_server.cpp b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/include/multilevel_sensor_cluster_server.cpp +new file mode 100644 +index 0000000000..0645623b87 +--- /dev/null ++++ b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/include/multilevel_sensor_cluster_server.cpp +@@ -0,0 +1,181 @@ ++/****************************************************************************** ++ * # License ++ * Copyright 2022 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 "multilevel_sensor_cluster_server.h" ++#include "zcl_cluster_servers_helpers.hpp" ++ ++// Interfaces ++#include "zwave_command_class_version_types.h" ++#include "zwave_command_class_configuration_types.h" ++ ++// ZPC includes ++#include "zpc_attribute_store.h" ++#include "zpc_attribute_store_network_helper.h" ++#include "zwave_command_class_generic_types.h" ++#include "attribute_store_defined_attribute_types.h" ++ ++// Includes from Unify shared components ++#include "attribute.hpp" ++#include "attribute_store_helper.h" ++#include "sl_log.h" ++ ++// Includes from auto-generated files ++#include "dotdot_mqtt.h" ++#include "zap-types.h" ++#include "dotdot_mqtt_helpers.hpp" ++ ++// Generic includes ++#include ++#include ++#include ++ ++using namespace attribute_store; ++ ++// Setup Log ID ++constexpr char LOG_TAG[] = "multilevel_sensor_cluster_server"; ++ ++// Attribute macro, shortening those long defines for attribute types: ++#define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_SENSOR_MULTILEVEL_##type ++ ++// List of attributes of SensorValues ++namespace ++{ ++const std::vector sensor_values_attributes ++ = {ATTRIBUTE(SENSOR_VALUE), ATTRIBUTE(SCALE)}; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Attribute publication functions ++////////////////////////////////////////////////////////////////////////////// ++ ++/** ++ * @brief Publishes the Multilevel Sensor Cluster Server attributes ++ * ++ * @param unid unid for which we want to publish the ++ * SensorValues attributes. ++ * @param endpoint_id Endpoint ID for which we want to publish the ++ * SensorValues attributes. ++ * @param sensor_type Sensor Type node ID for which we want to publish the ++ * SensorValues attributes. ++ */ ++static sl_status_t publish_multilevel_sensor_cluster_attributes( ++ const std::string &unid, ++ attribute_store::attribute sensor_type_node, ++ zwave_endpoint_id_t endpoint_id) ++{ ++ // Do not publish any state supported commands for ourselves. ++ if (is_zpc_unid(unid.c_str())) { ++ return SL_STATUS_FAIL; ++ } ++ ++ // Build the base topic and pass it on to DotDot MQTT. ++ try { ++ // Get reported sensor type ID ++ uint8_t sensor_type = sensor_type_node.reported(); ++ ++ // Get SensorType name ++ const std::string sensor_type_str ++ = multilevel_sensor_sensor_type_get_enum_value_name(sensor_type); ++ ++ // Added sensor type name to base topic ++ const std::string base_topic = "ucl/by-unid/" + std::string(unid) + "/ep" ++ + std::to_string(endpoint_id) + "/" ++ + std::string(sensor_type_str); ++ ++ SensorValue value = {0, 0}; ++ // Get report sensor value ++ attribute_store::attribute sensor_value_node ++ = sensor_type_node.child_by_type(ATTRIBUTE(SENSOR_VALUE)); ++ if (sensor_value_node.reported_exists()) { ++ value.Value = sensor_value_node.reported(); ++ } ++ // Get report sensor scale ++ attribute_store::attribute sensor_scale_node ++ = sensor_type_node.child_by_type(ATTRIBUTE(SCALE)); ++ if (sensor_scale_node.reported_exists()) { ++ value.Scale = static_cast(sensor_scale_node.reported()); ++ } ++ ++ // Pulish the sensor value attribute ++ if (SL_STATUS_OK ++ != uic_mqtt_dotdot_multilevel_sensor_sensor_values_publish( ++ base_topic.c_str(), ++ value, ++ UCL_MQTT_PUBLISH_TYPE_REPORTED)) { ++ return SL_STATUS_FAIL; ++ } ++ } catch (const std::exception &e) { ++ sl_log_error(LOG_TAG, ++ "Error while get base topic and sensor data : %s", ++ e.what()); ++ ++ return SL_STATUS_FAIL; ++ } ++ return SL_STATUS_OK; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Attribute store callback functions ++////////////////////////////////////////////////////////////////////////////// ++/** ++ * @brief Listens to updates to the SensorValues then publishes the attributes. ++ * ++ * @param updated_node Attribute Store node that was modified. ++ * @param change Type of change applied to the node. ++ */ ++void on_sensor_values_update(attribute_store_node_t updated_node, ++ attribute_store_change_t change) ++{ ++ if (change == ATTRIBUTE_CREATED || change == ATTRIBUTE_DELETED) { ++ return; ++ } ++ ++ // Go up and find the UNID/Endpoint and its network status. ++ unid_t unid; ++ zwave_endpoint_id_t endpoint_id = 0; ++ if (SL_STATUS_OK ++ != attribute_store_network_helper_get_unid_endpoint_from_node( ++ updated_node, ++ unid, ++ &endpoint_id)) { ++ return; ++ } ++ ++ attribute_store::attribute sensor_type_node ++ = attribute_store_get_first_parent_with_type(updated_node, ++ ATTRIBUTE(SENSOR_TYPE)); ++ ++ // Publish the multilevel sensor values: ++ if (SL_STATUS_OK ++ != publish_multilevel_sensor_cluster_attributes(std::string(unid), ++ sensor_type_node, ++ endpoint_id)) { ++ return; ++ } ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Init and teardown functions. ++////////////////////////////////////////////////////////////////////////////// ++sl_status_t multilevel_sensor_cluster_server_init(void) ++{ ++ sl_log_debug(LOG_TAG, "Multilevel sensor server initialization"); ++ ++ // Register attribute updates ++ ++ attribute_store_register_callback_by_type_to_array( ++ &on_sensor_values_update, ++ sensor_values_attributes.data(), ++ static_cast(sensor_values_attributes.size())); ++ ++ return SL_STATUS_OK; ++} +diff --git a/applications/examples/applications/emulated_end_device/components/eed_attribute_store/include/multilevel_sensor_cluster_server.h b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/include/multilevel_sensor_cluster_server.h +new file mode 100644 +index 0000000000..7abce74752 +--- /dev/null ++++ b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/include/multilevel_sensor_cluster_server.h +@@ -0,0 +1,44 @@ ++/****************************************************************************** ++ * # License ++ * Copyright 2022 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 multilevel_sensor_cluster_server ZCL Multilevel Sensor cluster ++ * @ingroup zcl_cluster_servers ++ * @brief The module handlers the Multilevel Sensor Cluster attribute and ++ * publish directly the attribute via MQTT. ++ * ++ * @{ ++ */ ++ ++#ifndef MULTILEVEL_SENSOR_CLUSTER_SERVER_H ++#define MULTILEVEL_SENSOR_CLUSTER_SERVER_H ++ ++#include "sl_status.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/** ++ * @brief Initialize the Multilevel Sensor Cluster Commands handler. ++ * ++ * @returns SL_STATUS_OK on success, any other code on failure ++ */ ++sl_status_t multilevel_sensor_cluster_server_init(void); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif //MULTILEVEL_SENSOR_CLUSTER_SERVER_H ++/** @} end configuration_cluster_mapper */ +diff --git a/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt b/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt +new file mode 100644 +index 0000000000..41a947535f +--- /dev/null ++++ b/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt +@@ -0,0 +1,46 @@ ++find_package(Boost REQUIRED) ++ ++# Find nlohmann_json, unfortunately the find_package doesn't work for this when ++# cross compiling, thus we use the simplified method find_path instead ++find_path(nlohmann_json_include nlohmann/json.hpp REQUIRED) ++ ++# ZCL Cluster server library ++add_library( ++ zcl_cluster_servers ++ src/configuration_parameter_cluster_server.cpp ++ src/humidity_control_cluster_server.c ++ src/user_code_cluster_server.cpp ++ src/fan_control_cluster_server.c ++ src/zcl_binding_cluster_server.cpp ++ src/zcl_cluster_servers.cpp ++ 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/multilevel_sensor_cluster_server.cpp ++ ) ++ ++target_include_directories( ++ zcl_cluster_servers ++ PUBLIC include ++ PRIVATE src ${nlohmann_json_include} ${Boost_INCLUDE_DIRS}) ++ ++target_link_libraries( ++ zcl_cluster_servers ++ PUBLIC zwave_handlers zwave_definitions ++ PRIVATE unify ++ zpc_attribute_store ++ zpc_utils ++ ucl_mqtt ++ zwave_command_classes ++ zwave_api_transport ++ dotdot_mapper ++ zwave_network_management) ++ ++if(BUILD_TESTING) ++ # Unit tests ++ add_subdirectory(test) ++ ++ # Mocks ++ target_add_mock(zcl_cluster_servers) ++endif() +diff --git a/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp b/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp +new file mode 100644 +index 0000000000..736b3d7f39 +--- /dev/null ++++ b/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp +@@ -0,0 +1,55 @@ ++/****************************************************************************** ++ * # License ++ * Copyright 2021 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 from this component ++#include "zcl_cluster_servers.h" ++#include "zcl_rf_telemetry_cluster_server.h" ++#include "configuration_parameter_cluster_server.h" ++#include "zcl_binding_cluster_server.h" ++#include "zcl_scenes_cluster_server.h" ++#include "zcl_OTA_cluster_server.hpp" ++#include "user_code_cluster_server.h" ++#include "fan_control_cluster_server.h" ++#include "multilevel_sensor_cluster_server.h" ++ ++//Includes from other components ++#include "attribute_store.h" ++#include "attribute_store_helper.h" ++#include "zpc_attribute_store_network_helper.h" ++#include "attribute_store_defined_attribute_types.h" ++ ++// Interfaces ++#include "zwave_controller_types.h" ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Init and teardown functions. ++////////////////////////////////////////////////////////////////////////////// ++sl_status_t zcl_cluster_servers_init() ++{ ++ sl_status_t init_status = SL_STATUS_OK; ++ init_status |= zcl_OTA_cluster_server_init(); ++ init_status |= zcl_rf_telemetry_cluster_server_init(); ++ init_status |= configuration_parameter_cluster_server_init(); ++ init_status |= binding_cluster_server_init(); ++ init_status |= zcl_scenes_cluster_server_init(); ++ init_status |= user_code_cluster_server_init(); ++ init_status |= fan_control_cluster_server_init(); ++ init_status |= multilevel_sensor_cluster_server_init(); ++ ++ return init_status; ++} ++ ++int zcl_cluster_servers_teardown() ++{ ++ zcl_scenes_cluster_server_teardown(); ++ return 0; ++} +diff --git a/components/uic_dotdot/dotdot-xml/Unify_MultilevelSensor.xml b/components/uic_dotdot/dotdot-xml/Unify_MultilevelSensor.xml +new file mode 100644 +index 0000000000..126be4bd8e +--- /dev/null ++++ b/components/uic_dotdot/dotdot-xml/Unify_MultilevelSensor.xml +@@ -0,0 +1,121 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/components/uic_dotdot/dotdot-xml/library.xml b/components/uic_dotdot/dotdot-xml/library.xml +index 4210b67fa4..deec70c822 100644 +--- a/components/uic_dotdot/dotdot-xml/library.xml ++++ b/components/uic_dotdot/dotdot-xml/library.xml +@@ -501,4 +501,5 @@ applicable to this document can be found in the LICENSE.md file. + + + ++ + +\ No newline at end of file +diff --git a/components/uic_dotdot/zap/addon-helper.js b/components/uic_dotdot/zap/addon-helper.js +index 3686fb8395..9d57f82c8b 100644 +--- a/components/uic_dotdot/zap/addon-helper.js ++++ b/components/uic_dotdot/zap/addon-helper.js +@@ -127,6 +127,7 @@ function isStruct(type) { + case 'SSceneTable': return true + case 'DeviceTypeStruct': return true + case 'CredentialStruct': return true ++ case 'SensorValue': return true + default: return false + } + } +-- +2.39.5 + diff --git a/patches/UnifySDK/0009-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch b/patches/UnifySDK/0009-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch new file mode 100644 index 000000000..a55cbdaad --- /dev/null +++ b/patches/UnifySDK/0009-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch @@ -0,0 +1,3672 @@ +From 15eb74a0f1c4a8fdd9fa20b17d6e3129af53dac0 Mon Sep 17 00:00:00 2001 +From: ptphan +Date: Wed, 2 Oct 2024 10:38:02 +0700 +Subject: [PATCH] UIC-3273: Generated files for Unify_MultilevelSensor Cluster + +[Philippe Coval] + +This change has been applied without any change and will be forwarded to: + +This change was made from uic repo by exporting patch using: + +git format-patch -1 943ae4c683f819ae8b6407ee29aa4f7c9bd69ddf + +And then applied on top of z-wave/core/zpc/main (dangling branch of +Unify, currently in rzr fork, that may be pushed to public Unify repo) + +git apply -i 0001-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch + +Then a patch is generated for z-p-c project using: + + git format-patch --no-numbered \ + -o ~/mnt/z-wave-protocol-controller/patches/UnifySDK/ \ + ver_1.7.0 + +Bug-SiliconLabs: UIC-3273 +Origin: ver_1.7.0-unstable-22-g943ae4c683 +Origin: s.s.com/projects/UIC/repos/uic/pull-requests/2855 +Relate-to: https://github.com/SiliconLabsSoftware/z-wave-protocol-controller/issues/44 +Forwarded: https://github.com/rzr/UnifySDK/tree/z-wave/core/zpc/main +Forwarded: https://github.com/SiliconLabsSoftware/z-wave-protocol-controller/pull/143 +Signed-off-by: Philippe Coval +--- + .../cluster-types/cluster-type-attributes.ts | 2 +- + .../include/dotdot_attribute_id_definitions.h | 3 + + .../dotdot_cluster_command_id_definitions.h | 2 + + .../include/dotdot_cluster_id_definitions.h | 4 + + .../zap-generated/include/zap-types.h | 96 ++++ + .../readme_ucl_mqtt_reference.md | 443 ++++++++++++++++ + .../src/dotdot_attribute_id_definitions.c | 40 ++ + .../src/dotdot_cluster_id_definitions.c | 5 + + .../zap-generated/include/dotdot_mqtt.h | 183 +++++++ + .../include/dotdot_mqtt_attributes.h | 35 ++ + .../include/dotdot_mqtt_generated_commands.h | 22 + + .../include/dotdot_mqtt_group_commands.h | 17 + + .../include/dotdot_mqtt_helpers.h | 7 + + .../include/dotdot_mqtt_helpers.hpp | 17 + + ...dotdot_mqtt_supported_generated_commands.h | 28 + + .../include/dotdot_mqtt_translators.h | 26 + + .../zap-generated/src/dotdot_mqtt.cpp | 488 ++++++++++++++++++ + .../zap-generated/src/dotdot_mqtt.hpp | 28 + + .../src/dotdot_mqtt_attributes.cpp | 206 ++++++++ + .../src/dotdot_mqtt_command_helpers.cpp | 16 + + .../src/dotdot_mqtt_command_helpers.hpp | 12 + + .../src/dotdot_mqtt_generated_commands.cpp | 40 ++ + .../src/dotdot_mqtt_group_commands.cpp | 99 ++++ + .../zap-generated/src/dotdot_mqtt_helpers.cpp | 246 +++++++++ + ...tdot_mqtt_supported_generated_commands.cpp | 43 ++ + .../test/dotdot_mqtt_test.include | 1 + + .../include/dotdot_attributes.uam | 4 + + .../include/dotdot_attributes_camel_case.uam | 4 + + .../unify_dotdot_attribute_store_helpers.h | 240 +++++++++ + .../unify_dotdot_defined_attribute_types.h | 3 + + ...ot_attribute_store_attribute_publisher.cpp | 257 +++++++++ + ..._force_read_attributes_command_callbacks.c | 37 ++ + .../unify_dotdot_attribute_store_helpers.cpp | 249 +++++++++ + ...fy_dotdot_attribute_store_registration.cpp | 48 ++ + ...store_write_attributes_command_callbacks.c | 33 ++ + .../test/unify_dotdot_attribute_store_test.c | 28 + + .../test/unify_dotdot_attribute_store_test.h | 4 + + 37 files changed, 3015 insertions(+), 1 deletion(-) + +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 a46049dbe7..2fa7a4c728 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 +@@ -1,7 +1,7 @@ + //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 = { +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 a988971041..52a9683a3b 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 +@@ -831,6 +831,9 @@ typedef enum { + #define DOTDOT_NAME_AND_LOCATION_LOCATION_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x1) + // Definitions for cluster: ConfigurationParameters + #define DOTDOT_CONFIGURATION_PARAMETERS_CONFIGURATION_PARAMETERS_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x0) ++// Definitions for cluster: MultilevelSensor ++#define DOTDOT_MULTILEVEL_SENSOR_SENSOR_VALUES_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x0) ++#define DOTDOT_MULTILEVEL_SENSOR_SENSOR_TYPE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x1) + // Definitions for cluster: AoXLocator + #define DOTDOT_AOX_LOCATOR_REPORTING_MODE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x1) + #define DOTDOT_AOX_LOCATOR_POSITION_AND_ORIENTATION_VALID_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x2) +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 7e33175d4a..c63d48c45f 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 +@@ -353,6 +353,8 @@ + #define DOTDOT_CONFIGURATION_PARAMETERS_SET_PARAMETER_COMMAND_ID (0x3) + #define DOTDOT_CONFIGURATION_PARAMETERS_DISCOVER_PARAMETER_RANGE_COMMAND_ID (0x4) + ++// Commands for cluster: MultilevelSensor ++ + // Commands for cluster: AoXLocator + #define DOTDOT_AOX_LOCATOR_IQ_REPORT_COMMAND_ID (0x1) + #define DOTDOT_AOX_LOCATOR_ANGLE_REPORT_COMMAND_ID (0x2) +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 34db7d7b79..7432fce84e 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 +@@ -238,6 +238,10 @@ + #define DOTDOT_CONFIGURATION_PARAMETERS_CLUSTER_ID ((dotdot_cluster_id_t)0xFD07) + + ++// Definitions for cluster: MultilevelSensor ++#define DOTDOT_MULTILEVEL_SENSOR_CLUSTER_ID ((dotdot_cluster_id_t)0xFD09) ++ ++ + // Definitions for cluster: AoXLocator + #define DOTDOT_AOX_LOCATOR_CLUSTER_ID ((dotdot_cluster_id_t)0xFD10) + +diff --git a/components/uic_dotdot/zap-generated/include/zap-types.h b/components/uic_dotdot/zap-generated/include/zap-types.h +index daf85dbdac..504969219c 100644 +--- a/components/uic_dotdot/zap-generated/include/zap-types.h ++++ b/components/uic_dotdot/zap-generated/include/zap-types.h +@@ -946,6 +946,96 @@ typedef enum { + ZCL_MOVE_STEP_MODE_DOWN = 1, + } MoveStepMode; + ++// Enum for MultilevelSensorSensorType ++typedef enum { ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_AIR_TEMPERATURE = 1, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_ILLUMINANCE = 3, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_POWER = 4, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_HUMIDITY = 5, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_VELOCITY = 6, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_DIRECTION = 7, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_ATMOSPHERIC_PRESSURE = 8, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_BAROMETRIC_PRESSURE = 9, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_SOLAR_RADIATION = 10, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_DEW_POINT = 11, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_RAIN_RATE = 12, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_TIDE_LEVEL = 13, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_WEIGHT = 14, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_VOLTAGE = 15, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_CURRENT = 16, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_CARBON_DIOXIDE_CO2_LEVEL = 17, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_AIR_FLOW = 18, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_TANK_CAPACITY = 19, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_DISTANCE = 20, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_ROTATION = 22, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_WATER_TEMPURATURE = 23, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_SOIL_TEMPURATURE = 24, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_SEISMIC_INTENSITY = 25, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_SEISMIC_MAGNITUDE = 26, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_ULTRAVIOLET = 27, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_ELECTRICAL_RESISTIVITY = 28, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_ELECTRICAL_CONDUCTIVITY = 29, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_LOUDNESS = 30, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_MOISTURE = 31, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_FREQUENCY = 32, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_TIME = 33, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_TARGET_TEMPERATURE = 34, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_PARTICULATE_MATTER2__5 = 35, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_FORMALDEHYDE_LEVEL = 36, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_RADON_CONCENTRATION = 37, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_METHANE_DENSITY = 38, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_VOLATILE_ORGANIC_COMPOUND_LEVEL = 39, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_CARBON_MONOXIDE_LEVEL = 40, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_SOIL_HUMIDITY = 41, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_SOIL_REACTIVITY = 42, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_SOIL_SALINITY = 43, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_HEART_RATE = 44, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_BLOOD_PRESSURE = 45, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_MUSCLE_MASS = 46, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_FAT_MASS = 47, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_BONE_MASS = 48, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_TOTAL_BODY_WATER = 49, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_BASIS_METABOLIC_RATE = 50, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_BODY_MASS_INDEX = 51, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_ACCELERATION_X_AXIS = 52, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_ACCELERATION_Y_AXIS = 53, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_ACCELERATION_Z_AXIS = 54, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_SMOKE_DENSITY = 55, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_WATER_FLOW = 56, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_WATER_PRESSURE = 57, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_RF_SIGNAL_STRENGTH = 58, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_PARTICULATE_MATTER10 = 59, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_RESPIRATORY_RATE = 60, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_RELATIVE_MODULATION_LEVEL = 61, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_BOILER_WATER_TEMPERATURE = 62, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_DOMESTIC_HOT_WATER_TEMPERATURE = 63, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_OUTSIDE_TEMPERATURE = 64, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_EXHAUST_TEMPERATURE = 65, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_WATER_CHLORINE_LEVEL = 66, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_WATER_ACIDITY = 67, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_WATER_OXIDATION_REDUCTION_POTENTIAL = 68, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_HEART_RATE_LFHF_RATIO = 69, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_MOTION_DIRECTION = 70, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_APPLIED_FORCE_ON_THE_SENSOR = 71, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_RETURN_AIR_TEMPERATURE = 72, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_SUPPLY_AIR_TEMPERATURE = 73, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_CONDENSER_COIL_TEMPERATURE = 74, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_EVAPRORATOR_COIL_TEMPERATURE = 75, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_LIQUID_LINE_TEMPERATURE = 76, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_DISCHARGE_LINE_TEMPERATURE = 77, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_SUCTION_PRESSURE = 78, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_DISCHARGE_PRESSURE = 79, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_DEFROST_TEMPERATURE = 80, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_OZONE = 81, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_SULFUR_DIOXIDE = 82, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_NITROGEN_DIOXIDE = 83, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_AMMONIA = 84, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_LEAD = 85, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_PARTICULATE_MATTER1 = 86, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_PERSON_COUNTER_ENTERING = 87, ++ ZCL_MULTILEVEL_SENSOR_SENSOR_TYPE_PERSON_COUNTER_EXITING = 88, ++} MultilevelSensorSensorType; ++ + // Enum for NM_State + typedef enum { + ZCL_NM_STATE_IDLE = 0, +@@ -2284,6 +2374,12 @@ typedef struct _SSceneTable { + const char* SceneTableExtensions; + } SSceneTable; + ++// Struct for SensorValue ++typedef struct _SensorValue { ++ int32_t Value; ++ uint8_t Scale; ++} SensorValue; ++ + // Struct for SphericalCoordinates + typedef struct _SphericalCoordinates { + double Azimuth; +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 5316b884c2..82dfa2097d 100644 +--- a/components/uic_dotdot/zap-generated/readme_ucl_mqtt_reference.md ++++ b/components/uic_dotdot/zap-generated/readme_ucl_mqtt_reference.md +@@ -51886,6 +51886,315 @@ mosquitto_pub -t 'ucl/by-unid///ConfigurationParameters/Commands/Force +


+ + ++ ++ ++ ++ ++ ++\page multilevel_sensor MultilevelSensor Cluster ++The following commands and attributes are accepted as JSON payloads for the ++MultilevelSensor cluster. ++ ++

++ ++ ++ ++ ++\section multilevel_sensor_attrs MultilevelSensor Attributes ++The following attribute topics are used to retrieve the MultilevelSensor cluster state. ++ ++
++ ++\subsection multilevel_sensor_attr_sensor_values MultilevelSensor/SensorValues Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/MultilevelSensor/Attributes/SensorValues/Reported ++[PREFIX]/MultilevelSensor/Attributes/SensorValues/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "MultilevelSensor Cluster SensorValues Attribute Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "SensorValue" ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see desired/reported value for SensorValues attribute under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid/+/+/MultilevelSensor/Attributes/SensorValues/+' ++ ++# Example output ++ ++ucl/by-unid//ep0/MultilevelSensor/Attributes/SensorValues/Desired { "value": } ++ucl/by-unid//ep0/MultilevelSensor/Attributes/SensorValues/Reported { "value": } ++ ++``` ++ ++

++ ++\subsection multilevel_sensor_attr_sensor_type MultilevelSensor/SensorType Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/MultilevelSensor/Attributes/SensorType/Reported ++[PREFIX]/MultilevelSensor/Attributes/SensorType/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "MultilevelSensor Cluster SensorType Attribute Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "MultilevelSensorSensorType" ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see desired/reported value for SensorType attribute under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid/+/+/MultilevelSensor/Attributes/SensorType/+' ++ ++# Example output ++ ++ucl/by-unid//ep0/MultilevelSensor/Attributes/SensorType/Desired { "value": } ++ucl/by-unid//ep0/MultilevelSensor/Attributes/SensorType/Reported { "value": } ++ ++``` ++ ++

++ ++ ++\subsection multilevel_sensor_attr_cluster_revision MultilevelSensor/ClusterRevision Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/MultilevelSensor/Attributes/ClusterRevision/Reported ++[PREFIX]/MultilevelSensor/Attributes/ClusterRevision/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "MultilevelSensor 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///MultilevelSensor/Attributes/ClusterRevision/+' ++# Example output ++ucl/by-unid///MultilevelSensor/Attributes/ClusterRevision/Desired { "value": } ++ucl/by-unid///MultilevelSensor/Attributes/ClusterRevision/Reported { "value": } ++``` ++ ++ ++ ++ ++ ++

++ ++ ++ ++ ++\section multilevel_sensor_recv_cmd_support MultilevelSensor Command Support ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/MultilevelSensor/SupportedCommands ++[PREFIX]/MultilevelSensor/SupportedGeneratedCommands ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "MultilevelSensor Command Support Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "array", ++ "items" : { ++ "type": "string", ++ "enum": [ ++ ] ++ } ++ } ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see supported commands for MultilevelSensor cluster under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///MultilevelSensor/SupportedCommands' ++# Example output ++ucl/by-unid///MultilevelSensor/SupportedCommands { "value": [] } ++``` ++ ++To see supported generated commands for MultilevelSensor cluster under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///MultilevelSensor/SupportedGeneratedCommands' ++# Example output ++ucl/by-unid///MultilevelSensor/SupportedGeneratedCommands { "value": [] } ++``` ++ ++ ++ ++ ++ ++

++ ++ ++ ++ ++\section multilevel_sensor_cmds MultilevelSensor Commands ++ ++

++ ++\subsection multilevel_sensor_write_attr_cmd MultilevelSensor/WriteAttributes Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/MultilevelSensor/Commands/WriteAttributes ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "MultilevelSensor Cluster WriteAttributes Command Properties", ++ "type": "object", ++ "properties": { ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To update all MultilevelSensor attributes under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///MultilevelSensor/Commands/WriteAttributes' -m '{ }' ++``` ++ ++> NOTE: Specify only the list of attributes to write in this command. ++> Unspecified attributes will not be updated. ++ ++

++ ++\subsection multilevel_sensor_force_read_attr_cmd MultilevelSensor/ForceReadAttributes Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/MultilevelSensor/Commands/ForceReadAttributes ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "MultilevelSensor Cluster ForceReadAttributes Command Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "array" ++ "items": { ++ "type": "string", ++ "enum": [ ++ "SensorValues", ++ "SensorType" ++ ] ++ } ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To force read all MultilevelSensor attributes under the by-unid topic space (by sending an empty array): ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///MultilevelSensor/Commands/ForceReadAttributes' -m '{ "value": [] }' ++``` ++ ++To force read one of the MultilevelSensor attributes under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///MultilevelSensor/Commands/ForceReadAttributes' -m '{ "value": ["SensorValues"] }' ++``` ++ ++ ++ ++ ++ ++


++ ++ + + + +@@ -54908,6 +55217,33 @@ mosquitto_pub -t 'ucl/by-unid///UnifyHumidityControl/Commands/ForceRea + +

+ ++ ++ ++ ++\section struct_sensor_value SensorValue Struct ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "SensorValue Struct Properties", ++ "type": "object", ++ "properties": { ++ "Value": { ++ "type": "integer" ++ } ++ "Scale": { ++ "type": "integer" ++ } ++ } ++} ++``` ++ ++ ++ ++ ++ ++

++ + + + +@@ -57032,6 +57368,113 @@ mosquitto_pub -t 'ucl/by-unid///UnifyHumidityControl/Commands/ForceRea + +

+ ++ ++ ++ ++\section enum_multilevel_sensor_sensor_type MultilevelSensorSensorType Enum ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "MultilevelSensorSensorType Enum Properties", ++ "type": "string", ++ "enum": [ ++ "AirTemperature", ++ "Illuminance", ++ "Power", ++ "Humidity", ++ "Velocity", ++ "Direction", ++ "AtmosphericPressure", ++ "BarometricPressure", ++ "SolarRadiation", ++ "DewPoint", ++ "RainRate", ++ "TideLevel", ++ "Weight", ++ "Voltage", ++ "Current", ++ "CarbonDioxideCO2Level", ++ "AirFlow", ++ "TankCapacity", ++ "Distance", ++ "Rotation", ++ "WaterTempurature", ++ "SoilTempurature", ++ "SeismicIntensity", ++ "SeismicMagnitude", ++ "Ultraviolet", ++ "ElectricalResistivity", ++ "ElectricalConductivity", ++ "Loudness", ++ "Moisture", ++ "Frequency", ++ "Time", ++ "TargetTemperature", ++ "ParticulateMatter2.5", ++ "FormaldehydeLevel", ++ "RadonConcentration", ++ "MethaneDensity", ++ "VolatileOrganicCompoundLevel", ++ "CarbonMonoxideLevel", ++ "SoilHumidity", ++ "SoilReactivity", ++ "SoilSalinity", ++ "HeartRate", ++ "BloodPressure", ++ "MuscleMass", ++ "FatMass", ++ "BoneMass", ++ "TotalBodyWater", ++ "BasisMetabolicRate", ++ "BodyMassIndex", ++ "AccelerationX-axis", ++ "AccelerationY-axis", ++ "AccelerationZ-axis", ++ "SmokeDensity", ++ "WaterFlow", ++ "WaterPressure", ++ "RFSignalStrength", ++ "ParticulateMatter10", ++ "RespiratoryRate", ++ "RelativeModulationLevel", ++ "BoilerWaterTemperature", ++ "DomesticHotWaterTemperature", ++ "OutsideTemperature", ++ "ExhaustTemperature", ++ "WaterChlorineLevel", ++ "WaterAcidity", ++ "WaterOxidationReductionPotential", ++ "HeartRateLFHFRatio", ++ "MotionDirection", ++ "AppliedForceOnTheSensor", ++ "ReturnAirTemperature", ++ "SupplyAirTemperature", ++ "CondenserCoilTemperature", ++ "EvaproratorCoilTemperature", ++ "LiquidLineTemperature", ++ "DischargeLineTemperature", ++ "SuctionPressure", ++ "DischargePressure", ++ "DefrostTemperature", ++ "Ozone", ++ "SulfurDioxide", ++ "NitrogenDioxide", ++ "Ammonia", ++ "Lead", ++ "ParticulateMatter1", ++ "PersonCounterEntering", ++ "PersonCounterExiting" ++ ] ++} ++``` ++ ++ ++ ++ ++ ++

++ + + + +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 badc743381..98ebe6435d 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 +@@ -1947,6 +1947,19 @@ const char *uic_dotdot_get_attribute_name(dotdot_cluster_id_t cluster_id, + return "Unknown"; + } + // clang-format off ++ case DOTDOT_MULTILEVEL_SENSOR_CLUSTER_ID: ++ // clang-format on ++ switch (attribute_id) { ++ // clang-format off ++ case DOTDOT_MULTILEVEL_SENSOR_SENSOR_VALUES_ATTRIBUTE_ID: ++ return "SensorValues"; ++ case DOTDOT_MULTILEVEL_SENSOR_SENSOR_TYPE_ATTRIBUTE_ID: ++ return "SensorType"; ++ // clang-format on ++ default: ++ return "Unknown"; ++ } ++ // clang-format off + case DOTDOT_AOX_LOCATOR_CLUSTER_ID: + // clang-format on + switch (attribute_id) { +@@ -4415,6 +4428,14 @@ dotdot_attribute_id_t + return DOTDOT_CONFIGURATION_PARAMETERS_CONFIGURATION_PARAMETERS_ATTRIBUTE_ID; + } + break; ++ case DOTDOT_MULTILEVEL_SENSOR_CLUSTER_ID: ++ if (strcmp ("SensorValues", attribute_name) == 0) { ++ return DOTDOT_MULTILEVEL_SENSOR_SENSOR_VALUES_ATTRIBUTE_ID; ++ } ++ if (strcmp ("SensorType", attribute_name) == 0) { ++ return DOTDOT_MULTILEVEL_SENSOR_SENSOR_TYPE_ATTRIBUTE_ID; ++ } ++ break; + case DOTDOT_AOX_LOCATOR_CLUSTER_ID: + if (strcmp ("ReportingMode", attribute_name) == 0) { + return DOTDOT_AOX_LOCATOR_REPORTING_MODE_ATTRIBUTE_ID; +@@ -6506,6 +6527,19 @@ dotdot_attribute_json_type_t + return JSON_TYPE_UNKNOWN; + } + // clang-format off ++ case DOTDOT_MULTILEVEL_SENSOR_CLUSTER_ID: ++ // clang-format on ++ switch (attribute_id) { ++ // clang-format off ++ case DOTDOT_MULTILEVEL_SENSOR_SENSOR_VALUES_ATTRIBUTE_ID: ++ return JSON_TYPE_OBJECT; ++ case DOTDOT_MULTILEVEL_SENSOR_SENSOR_TYPE_ATTRIBUTE_ID: ++ return JSON_TYPE_NUMBER; ++ // clang-format on ++ default: ++ return JSON_TYPE_UNKNOWN; ++ } ++ // clang-format off + case DOTDOT_AOX_LOCATOR_CLUSTER_ID: + // clang-format on + switch (attribute_id) { +@@ -6982,6 +7016,12 @@ bool uic_dotdot_attribute_is_enum(dotdot_cluster_id_t cluster_id, + if (64775 == cluster_id) { + } + ++ if (64777 == cluster_id) { ++ if (1 == attribute_id) { ++ return true; ++ } ++ } ++ + if (64786 == cluster_id) { + } + +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 8699e827dc..4c251d9e02 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 +@@ -120,6 +120,8 @@ const char* uic_dotdot_get_cluster_name(dotdot_cluster_id_t cluster_id) { + return "NameAndLocation"; + case DOTDOT_CONFIGURATION_PARAMETERS_CLUSTER_ID: + return "ConfigurationParameters"; ++ case DOTDOT_MULTILEVEL_SENSOR_CLUSTER_ID: ++ return "MultilevelSensor"; + case DOTDOT_AOX_LOCATOR_CLUSTER_ID: + return "AoXLocator"; + case DOTDOT_AOX_POSITION_ESTIMATION_CLUSTER_ID: +@@ -293,6 +295,9 @@ dotdot_cluster_id_t uic_dotdot_get_cluster_id(const char* cluster_name) { + if (strcmp ("ConfigurationParameters", cluster_name) == 0) { + return DOTDOT_CONFIGURATION_PARAMETERS_CLUSTER_ID; + } ++ if (strcmp ("MultilevelSensor", cluster_name) == 0) { ++ return DOTDOT_MULTILEVEL_SENSOR_CLUSTER_ID; ++ } + if (strcmp ("AoXLocator", cluster_name) == 0) { + return DOTDOT_AOX_LOCATOR_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 bd703a2daf..7606ec4c85 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h ++++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h +@@ -39077,6 +39077,189 @@ void uic_mqtt_dotdot_configuration_parameters_publish_supported_commands( + void uic_mqtt_dotdot_configuration_parameters_publish_empty_supported_commands( + const dotdot_unid_t unid + ,dotdot_endpoint_id_t endpoint); ++// Callback types used by the multilevel_sensor cluster ++ ++typedef struct { ++ SensorValue sensor_values; ++ uint8_t sensor_type; ++} uic_mqtt_dotdot_multilevel_sensor_state_t; ++ ++typedef struct { ++ bool sensor_values; ++ bool sensor_type; ++} uic_mqtt_dotdot_multilevel_sensor_updated_state_t; ++ ++typedef sl_status_t (*uic_mqtt_dotdot_multilevel_sensor_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_multilevel_sensor_state_t, ++ uic_mqtt_dotdot_multilevel_sensor_updated_state_t ++); ++ ++typedef sl_status_t (*uic_mqtt_dotdot_multilevel_sensor_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_multilevel_sensor_updated_state_t ++); ++ ++ ++ ++ ++/** ++ * @brief Setup a callback for WriteAttribute to be called when a ++ * +/multilevel_sensor/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_multilevel_sensor_write_attributes_callback( ++ const uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback_t callback ++); ++/** ++ * @brief Unsets a callback for WriteAttribute to be called when a ++ * +/multilevel_sensor/Commands/WriteAttributes is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unset_multilevel_sensor_write_attributes_callback( ++ const uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback_t callback ++); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/multilevel_sensor/Commands/WriteAttributes is received. ++ */ ++void uic_mqtt_dotdot_clear_multilevel_sensor_write_attributes_callbacks(); ++ ++/** ++ * @brief Setup a callback for ForceReadAttributes to be called when a ++ * +/multilevel_sensor/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_multilevel_sensor_force_read_attributes_callback( ++ const uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback_t callback ++); ++/** ++ * @brief Unsets a callback for ForceReadAttributes to be called when a ++ * +/multilevel_sensor/Commands/ForceReadAttributes is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unset_multilevel_sensor_force_read_attributes_callback( ++ const uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback_t callback ++); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/multilevel_sensor/Commands/ForceReadAttributes is received. ++ */ ++void uic_mqtt_dotdot_clear_multilevel_sensor_force_read_attributes_callbacks(); ++ ++/** ++ * @brief Publish the attribute; MultilevelSensor/Attributes/SensorValues ++ * ++ * @param base_topic topic prefix to publish, /sensor_values ++ * 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_multilevel_sensor_sensor_values_publish( ++ const char *base_topic, ++ SensorValue value, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Unretains a published attribute; MultilevelSensor/Attributes/SensorValues ++ * ++ * @param base_topic topic prefix to publish, /sensor_values ++ * 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_multilevel_sensor_sensor_values_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Publish the attribute; MultilevelSensor/Attributes/SensorType ++ * ++ * @param base_topic topic prefix to publish, /sensor_type ++ * 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_multilevel_sensor_sensor_type_publish( ++ const char *base_topic, ++ uint8_t value, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Unretains a published attribute; MultilevelSensor/Attributes/SensorType ++ * ++ * @param base_topic topic prefix to publish, /sensor_type ++ * 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_multilevel_sensor_sensor_type_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++ ++/** ++ * @brief Publish the MultilevelSensor/ClusterRevision attribute ++ * ++ * @param base_topic topic prefix to publish, /MultilevelSensor/Attributes/ClusterRevision ++ * will be appended. ++ * @param value Value to publish. ++ */ ++void uic_mqtt_dotdot_multilevel_sensor_publish_cluster_revision(const char* base_topic, uint16_t value); ++ ++/** ++ * @brief Unretain a publication to MultilevelSensor/ClusterRevision attribute ++ * ++ * @param base_topic topic prefix to publish, /MultilevelSensor/Attributes/ClusterRevision ++ * will be appended. ++ */ ++void uic_mqtt_dotdot_multilevel_sensor_unretain_cluster_revision(const char* base_topic); ++ ++/** ++ * @brief Publish the SupportedCommands for UNID/EndPoint for the MultilevelSensor Cluster ++ * ++ * This function will iterate over all Commands in the MultilevelSensor 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_multilevel_sensor_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 MultilevelSensor Cluster ++ * ++ * @param unid ++ * @param endpoint ) ++ */ ++void uic_mqtt_dotdot_multilevel_sensor_publish_empty_supported_commands( ++ const dotdot_unid_t unid ++ ,dotdot_endpoint_id_t endpoint); + // Callback types used by the protocol_controller_network_management cluster + typedef sl_status_t (*uic_mqtt_dotdot_protocol_controller_network_management_write_callback_t)( + dotdot_unid_t unid, +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 68b51b7e03..003f75549d 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 +@@ -4978,6 +4978,21 @@ typedef sl_status_t (*uic_mqtt_dotdot_configuration_parameters_attribute_configu + size_t configuration_parameters_count, + const ConfigurationParameter* configuration_parameters + ); ++// Callback types used by the multilevel_sensor cluster ++typedef sl_status_t (*uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_values_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ bool unretained, ++ uic_mqtt_dotdot_attribute_update_type_t update_type, ++ SensorValue sensor_values ++); ++typedef sl_status_t (*uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_type_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ bool unretained, ++ uic_mqtt_dotdot_attribute_update_type_t update_type, ++ uint8_t sensor_type ++); + // Callback types used by the protocol_controller_network_management cluster + typedef sl_status_t (*uic_mqtt_dotdot_protocol_controller_network_management_attribute_network_management_state_callback_t)( + dotdot_unid_t unid, +@@ -9739,6 +9754,26 @@ sl_status_t uic_mqtt_dotdot_configuration_parameters_attributes_init(); + void uic_mqtt_dotdot_configuration_parameters_attribute_configuration_parameters_callback_set(const uic_mqtt_dotdot_configuration_parameters_attribute_configuration_parameters_callback_t callback); + + ++/** ++ * Initializes the attributes features for the MultilevelSensor cluster, ++ * allowing to receive attribute updates from other UNIDs. ++ */ ++sl_status_t uic_mqtt_dotdot_multilevel_sensor_attributes_init(); ++ ++/** ++ * Setup callback to be called when a ++ * MultilevelSensor/Attributes/sensor_values/# is received. Setting ++ * this callback will overwrite the previous set callback ++ */ ++void uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_values_callback_set(const uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_values_callback_t callback); ++/** ++ * Setup callback to be called when a ++ * MultilevelSensor/Attributes/sensor_type/# is received. Setting ++ * this callback will overwrite the previous set callback ++ */ ++void uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_type_callback_set(const uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_type_callback_t callback); ++ ++ + /** + * Initializes the attributes features for the ProtocolController-NetworkManagement cluster, + * allowing to receive attribute updates from other UNIDs. +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 011a75ddf9..aa8ac95998 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 +@@ -4838,6 +4838,28 @@ void uic_mqtt_dotdot_configuration_parameters_publish_generated_write_attributes + uic_mqtt_dotdot_configuration_parameters_updated_state_t attribute_list + ); + ++ ++/** ++ * @brief Publishes an incoming/generated WriteAttributes command for ++ * the MultilevelSensor cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/MultilevelSensor/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_multilevel_sensor_publish_generated_write_attributes_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_multilevel_sensor_state_t attribute_values, ++ uic_mqtt_dotdot_multilevel_sensor_updated_state_t attribute_list ++); ++ + /** + * @brief Publishes an incoming/generated Write command for + * the ProtocolController-NetworkManagement cluster. +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 ac85664a4f..caeee80ffa 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 +@@ -3610,6 +3610,23 @@ void uic_mqtt_dotdot_by_group_configuration_parameters_write_attributes_callback + + + ++typedef void (*uic_mqtt_dotdot_by_group_multilevel_sensor_write_attributes_callback_t)( ++ const dotdot_group_id_t group_id, ++ uic_mqtt_dotdot_multilevel_sensor_state_t, ++ uic_mqtt_dotdot_multilevel_sensor_updated_state_t ++); ++ ++/** ++ * Setup a callback for WriteAttribute to be called when a ++ * ucl/by-group/+/multilevel_sensor/Commands/WriteAttributes is received. ++ * Setting this callback will overwrite any previously set callback. ++ */ ++void uic_mqtt_dotdot_by_group_multilevel_sensor_write_attributes_callback_set( ++ const uic_mqtt_dotdot_by_group_multilevel_sensor_write_attributes_callback_t callback ++); ++ ++ ++ + typedef void (*uic_mqtt_dotdot_by_group_descriptor_write_attributes_callback_t)( + const dotdot_group_id_t group_id, + uic_mqtt_dotdot_descriptor_state_t, +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 80d87abc45..a9b42d482c 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 +@@ -538,6 +538,13 @@ char *move_step_mode_get_enum_value_name_c( + uint32_t value, char *result, size_t max_result_size); + /** Get move_step_mode enum representation from string. */ + uint32_t move_step_mode_get_enum_value_number_c(const char *str); ++#define MULTILEVEL_SENSOR_SENSOR_TYPE_ENUM_NAME_AVAILABLE 1 ++ ++/** Get multilevel_sensor_sensor_type string representation from enum. */ ++char *multilevel_sensor_sensor_type_get_enum_value_name_c( ++ uint32_t value, char *result, size_t max_result_size); ++/** Get multilevel_sensor_sensor_type enum representation from string. */ ++uint32_t multilevel_sensor_sensor_type_get_enum_value_number_c(const char *str); + #define NM_STATE_ENUM_NAME_AVAILABLE 1 + + /** Get nm_state 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 14befa43ce..d227c69cc2 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 +@@ -1271,6 +1271,23 @@ std::string move_step_mode_get_enum_value_name( + */ + uint32_t move_step_mode_get_enum_value_number(const std::string &str); + ++#define MULTILEVEL_SENSOR_SENSOR_TYPE_ENUM_NAME_AVAILABLE 1 ++ ++/** ++ * @brief Finds the name of a field for the MultilevelSensorSensorType enum ++ * ++ * @returns A string representation of the value. ++ */ ++std::string multilevel_sensor_sensor_type_get_enum_value_name( ++ uint32_t value); ++ ++/** ++ * @brief Finds the enum number of a string representation for the MultilevelSensorSensorType enum ++ * ++ * @returns A number enum value. ++ */ ++uint32_t multilevel_sensor_sensor_type_get_enum_value_number(const std::string &str); ++ + #define NM_STATE_ENUM_NAME_AVAILABLE 1 + + /** +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 3ee01c0c62..31b5b4443d 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 +@@ -1552,6 +1552,34 @@ void uic_mqtt_dotdot_configuration_parameters_publish_supported_generated_comman + ); + + ++/** ++ * @brief Struct containing the list of commands for MultilevelSensor ++ */ ++typedef struct _uic_mqtt_dotdot_multilevel_sensor_supported_commands_ { ++ bool write_attributes; ++} uic_mqtt_dotdot_multilevel_sensor_supported_commands_t; ++ ++/** ++ * @brief Sends/Publishes a the SupportedGenerated commands for ++ * the MultilevelSensor cluster for a UNID/Endpoint ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/MultilevelSensor/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_multilevel_sensor_publish_supported_generated_commands( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_multilevel_sensor_supported_commands_t *command_list ++); ++ ++ + /** + * @brief Struct containing the list of commands for ProtocolController-NetworkManagement + */ +diff --git a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_translators.h b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_translators.h +index d72db40ead..999d4c726e 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_translators.h ++++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt_translators.h +@@ -493,6 +493,32 @@ inline void to_json(nlohmann::json& jsn, const SSceneTable& field) + } + + ++/** ++ * Parse SensorValue type from json object. ++ * ++ * @param jsn JSON object to parse from. ++ * @param field field to be populated from JSON object. ++ */ ++inline void from_json(const nlohmann::json& jsn, SensorValue& field) ++{ ++ jsn.at("Value").get_to(field.Value); ++ jsn.at("Scale").get_to(field.Scale); ++} ++ ++ ++/** ++ * Build JSON object from SensorValue type. ++ * ++ * @param jsn JSON object to be populated. ++ * @param field Reference data. ++ */ ++inline void to_json(nlohmann::json& jsn, const SensorValue& field) ++{ ++ jsn["Value"] = field.Value; ++ jsn["Scale"] = field.Scale; ++} ++ ++ + /** + * Parse SphericalCoordinates type from json object. + * +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 d1122bf8dd..fb910272aa 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp +@@ -91829,6 +91829,340 @@ sl_status_t uic_mqtt_dotdot_configuration_parameters_init() + return SL_STATUS_OK; + } + ++// Callbacks pointers ++static std::set uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback; ++static std::set uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback; ++ ++// Callbacks setters ++ ++void uic_mqtt_dotdot_set_multilevel_sensor_write_attributes_callback( ++ const uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unset_multilevel_sensor_write_attributes_callback( ++ const uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback_t callback) ++{ ++ uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback.erase(callback); ++} ++void uic_mqtt_dotdot_clear_multilevel_sensor_write_attributes_callbacks() ++{ ++ uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback() ++{ ++ return uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback; ++} ++ ++void uic_mqtt_dotdot_set_multilevel_sensor_force_read_attributes_callback( ++ const uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unset_multilevel_sensor_force_read_attributes_callback( ++ const uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback_t callback) ++{ ++ uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback.erase(callback); ++} ++void uic_mqtt_dotdot_clear_multilevel_sensor_force_read_attributes_callbacks() ++{ ++ uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback.clear(); ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/MultilevelSensor/Commands/WriteAttributes ++void uic_mqtt_dotdot_on_multilevel_sensor_WriteAttributes( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (uic_mqtt_dotdot_multilevel_sensor_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_multilevel_sensor_state_t new_state = {}; ++ uic_mqtt_dotdot_multilevel_sensor_updated_state_t new_updated_state = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ uic_mqtt_dotdot_parse_multilevel_sensor_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, "MultilevelSensor", "WriteAttributes"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "MultilevelSensor", "WriteAttributes", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "MultilevelSensor", "WriteAttributes", ""); ++ return; ++ } ++ ++ for (const auto& callback: uic_mqtt_dotdot_multilevel_sensor_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_multilevel_sensor_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_multilevel_sensor_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_multilevel_sensor_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.sensor_values = true; ++ force_update.sensor_type = true; ++ trigger_handler = true; ++ } else { ++ std::unordered_map supported_attrs = { ++ {"SensorValues", &force_update.sensor_values }, ++ {"SensorType", &force_update.sensor_type }, ++ }; ++ ++ 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_multilevel_sensor_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, "MultilevelSensor/Commands/ForceReadAttributes: Unable to parse JSON payload"); ++ return; ++ } ++} ++ ++sl_status_t uic_mqtt_dotdot_multilevel_sensor_sensor_values_publish( ++ const char *base_topic, ++ SensorValue value, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++) ++{ ++ nlohmann::json jsn; ++ ++ // This is a single value ++ ++ nlohmann::json json_object = nlohmann::json::object(); ++ json_object["Value"] = value.Value; ++ json_object["Scale"] = value.Scale; ++ jsn["value"]= json_object; ++ ++ ++ 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, "MultilevelSensor/Attributes/SensorValues", e.what()); ++ return SL_STATUS_OK; ++ } ++ ++ ++ std::string topic = std::string(base_topic) + "/MultilevelSensor/Attributes/SensorValues"; ++ 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_multilevel_sensor_sensor_values_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type) ++{ ++ // clang-format on ++ std::string topic ++ = std::string(base_topic) ++ + "/MultilevelSensor/Attributes/SensorValues"; ++ ++ 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_multilevel_sensor_sensor_type_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 MULTILEVEL_SENSOR_SENSOR_TYPE_ENUM_NAME_AVAILABLE ++ jsn["value"] = multilevel_sensor_sensor_type_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 MULTILEVEL_SENSOR_SENSOR_TYPE. 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, "MultilevelSensor/Attributes/SensorType", e.what()); ++ return SL_STATUS_OK; ++ } ++ ++ ++ std::string topic = std::string(base_topic) + "/MultilevelSensor/Attributes/SensorType"; ++ 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_multilevel_sensor_sensor_type_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type) ++{ ++ // clang-format on ++ std::string topic ++ = std::string(base_topic) ++ + "/MultilevelSensor/Attributes/SensorType"; ++ ++ 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_multilevel_sensor_init() ++{ ++ std::string base_topic = "ucl/by-unid/+/+/"; ++ ++ std::string subscription_topic; ++ if(!uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback.empty()) { ++ subscription_topic = base_topic + "MultilevelSensor/Commands/WriteAttributes"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_multilevel_sensor_WriteAttributes); ++ } ++ ++ if(!uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback.empty()) { ++ subscription_topic = base_topic + "MultilevelSensor/Commands/ForceReadAttributes"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_multilevel_sensor_force_read_attributes); ++ } ++ ++ // Init the attributes for that cluster ++ uic_mqtt_dotdot_multilevel_sensor_attributes_init(); ++ ++ uic_mqtt_dotdot_by_group_multilevel_sensor_init(); ++ ++ return SL_STATUS_OK; ++} ++ + // Callbacks pointers + static std::set uic_mqtt_dotdot_protocol_controller_network_management_write_callback; + static std::set uic_mqtt_dotdot_protocol_controller_network_management_generated_write_callback; +@@ -95747,6 +96081,10 @@ sl_status_t uic_mqtt_dotdot_init() { + status_flag = uic_mqtt_dotdot_configuration_parameters_init(); + } + ++ if (status_flag == SL_STATUS_OK) { ++ status_flag = uic_mqtt_dotdot_multilevel_sensor_init(); ++ } ++ + if (status_flag == SL_STATUS_OK) { + status_flag = uic_mqtt_dotdot_protocol_controller_network_management_init(); + } +@@ -95824,6 +96162,7 @@ void uic_mqtt_dotdot_publish_supported_commands( + uic_mqtt_dotdot_application_monitoring_publish_supported_commands(unid, 0); + uic_mqtt_dotdot_name_and_location_publish_supported_commands(unid, endpoint_id); + uic_mqtt_dotdot_configuration_parameters_publish_supported_commands(unid, endpoint_id); ++ uic_mqtt_dotdot_multilevel_sensor_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_fan_control_publish_supported_commands(unid, endpoint_id); +@@ -95883,6 +96222,7 @@ void uic_mqtt_dotdot_publish_empty_supported_commands( + uic_mqtt_dotdot_application_monitoring_publish_empty_supported_commands(unid); + uic_mqtt_dotdot_name_and_location_publish_empty_supported_commands(unid, endpoint_id); + uic_mqtt_dotdot_configuration_parameters_publish_empty_supported_commands(unid, endpoint_id); ++ uic_mqtt_dotdot_multilevel_sensor_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_fan_control_publish_empty_supported_commands(unid, endpoint_id); +@@ -108646,6 +108986,154 @@ void uic_mqtt_dotdot_configuration_parameters_publish_empty_supported_commands( + } + } + ++// Publishing Cluster Revision for MultilevelSensor Cluster ++void uic_mqtt_dotdot_multilevel_sensor_publish_cluster_revision(const char* base_topic, uint16_t value) ++{ ++ std::string cluster_topic = std::string(base_topic) + "/MultilevelSensor/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 MultilevelSensor Cluster ++void uic_mqtt_dotdot_multilevel_sensor_unretain_cluster_revision(const char* base_topic) ++{ ++ // clang-format on ++ std::string cluster_topic ++ = std::string(base_topic) ++ + "/MultilevelSensor/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_multilevel_sensor_write_attributes_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ for (const auto& callback: uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback) { ++ uic_mqtt_dotdot_multilevel_sensor_state_t multilevel_sensor_new_state = {}; ++ uic_mqtt_dotdot_multilevel_sensor_updated_state_t multilevel_sensor_new_updated_state = {}; ++ ++ if (callback( ++ unid, ++ endpoint_id, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, ++ multilevel_sensor_new_state, ++ multilevel_sensor_new_updated_state ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ return false; ++} ++ ++static inline bool uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ for (const auto& callback: uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback) { ++ uic_mqtt_dotdot_multilevel_sensor_updated_state_t multilevel_sensor_force_update = {0}; ++ if (callback( ++ unid, ++ endpoint_id, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, ++ multilevel_sensor_force_update ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ return false; ++} ++ ++// Publishing Supported Commands for MultilevelSensor Cluster ++void uic_mqtt_dotdot_multilevel_sensor_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 ++ ++ // Check for a WriteAttributes Callback ++ if(uic_mqtt_dotdot_multilevel_sensor_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_multilevel_sensor_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 += "/MultilevelSensor/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 += "/MultilevelSensor/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 MultilevelSensor Cluster ++void uic_mqtt_dotdot_multilevel_sensor_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 += "/MultilevelSensor/SupportedCommands"; ++ ++ if (uic_mqtt_count_topics(topic.c_str()) > 0) { ++ uic_mqtt_publish(topic.c_str(), ++ EMPTY_VALUE_ARRAY, ++ strlen(EMPTY_VALUE_ARRAY), ++ true); ++ } ++} ++ + // Publishing Cluster Revision for ProtocolController-NetworkManagement Cluster + void uic_mqtt_dotdot_protocol_controller_network_management_publish_cluster_revision(const char* base_topic, uint16_t value) + { +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 63ed3b0949..9fbbc1ede6 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.hpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.hpp +@@ -343,6 +343,13 @@ sl_status_t uic_mqtt_dotdot_by_group_name_and_location_init(); + */ + sl_status_t uic_mqtt_dotdot_by_group_configuration_parameters_init(); + ++/** ++ * @brief Initialize MultilevelSensor dotdot bygroup command handlers ++ * ++ * @returns SL_STATUS_OK on success, error otherwise. ++ */ ++sl_status_t uic_mqtt_dotdot_by_group_multilevel_sensor_init(); ++ + /** + * @brief Initialize Descriptor dotdot bygroup command handlers + * +@@ -4915,6 +4922,27 @@ void uic_mqtt_dotdot_on_configuration_parameters_WriteAttributes( + 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_multilevel_sensor_write_attributes_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/MultilevelSensor/Commands/WriteAttributes ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_multilevel_sensor_WriteAttributes( ++ const char *topic, ++ const char *message, ++ const size_t message_length); ++ ++ + // clang-format on + + /** +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 51bb0cd1eb..25ce61e26a 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 +@@ -61125,6 +61125,212 @@ void uic_mqtt_dotdot_configuration_parameters_attribute_configuration_parameters + + // End of supported cluster. + ++/////////////////////////////////////////////////////////////////////////////// ++// Callback pointers for MultilevelSensor ++/////////////////////////////////////////////////////////////////////////////// ++static uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_values_callback_t uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_values_callback = nullptr; ++static uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_type_callback_t uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_type_callback = nullptr; ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Attribute update handlers for MultilevelSensor ++/////////////////////////////////////////////////////////////////////////////// ++static void uic_mqtt_dotdot_on_multilevel_sensor_sensor_values_attribute_update( ++ const char *topic, ++ const char *message, ++ const size_t message_length) { ++ if (uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_values_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; ++ } ++ ++ ++ SensorValue sensor_values = {}; ++ ++ 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, "MultilevelSensor::SensorValues: Missing attribute element: 'value'\n"); ++ return; ++ } ++// Start parsing value ++ sensor_values.Value = json_payload.at("value").at("Value").get(); ++ sensor_values.Scale = json_payload.at("value").at("Scale").get(); ++ ++ // End parsing value ++ } ++ ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "value", message); ++ return; ++ } ++ ++ uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_values_callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ unretained, ++ update_type, ++ sensor_values ++ ); ++ ++} ++static void uic_mqtt_dotdot_on_multilevel_sensor_sensor_type_attribute_update( ++ const char *topic, ++ const char *message, ++ const size_t message_length) { ++ if (uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_type_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 sensor_type = {}; ++ ++ 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, "MultilevelSensor::SensorType: 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 MULTILEVEL_SENSOR_SENSOR_TYPE_ENUM_NAME_AVAILABLE ++ tmp = multilevel_sensor_sensor_type_get_enum_value_number(json_payload.at("value").get()); ++ #elif defined(SENSOR_TYPE_ENUM_NAME_AVAILABLE) ++ tmp = sensor_type_get_enum_value_number(json_payload.at("value").get()); ++ #endif ++ } ++ sensor_type = 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_multilevel_sensor_attribute_sensor_type_callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ unretained, ++ update_type, ++ sensor_type ++ ); ++ ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Attribute init functions for MultilevelSensor ++/////////////////////////////////////////////////////////////////////////////// ++sl_status_t uic_mqtt_dotdot_multilevel_sensor_attributes_init() ++{ ++ std::string base_topic = "ucl/by-unid/+/+/"; ++ ++ std::string subscription_topic; ++ if(uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_values_callback) { ++ subscription_topic = base_topic + "MultilevelSensor/Attributes/SensorValues/#"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_multilevel_sensor_sensor_values_attribute_update); ++ } ++ if(uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_type_callback) { ++ subscription_topic = base_topic + "MultilevelSensor/Attributes/SensorType/#"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_multilevel_sensor_sensor_type_attribute_update); ++ } ++ ++ return SL_STATUS_OK; ++} ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Callback setters and getters for MultilevelSensor ++/////////////////////////////////////////////////////////////////////////////// ++void uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_values_callback_set(const uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_values_callback_t callback) ++{ ++ uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_values_callback = callback; ++} ++void uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_type_callback_set(const uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_type_callback_t callback) ++{ ++ uic_mqtt_dotdot_multilevel_sensor_attribute_sensor_type_callback = callback; ++} ++ ++// End of supported cluster. ++ + /////////////////////////////////////////////////////////////////////////////// + // Callback pointers for ProtocolController-NetworkManagement + /////////////////////////////////////////////////////////////////////////////// +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 a738479fb0..25c2c2aced 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 +@@ -14318,6 +14318,22 @@ void uic_mqtt_dotdot_parse_configuration_parameters_write_attributes( + + + ++} ++ ++ ++/** ++ * @brief JSON parser for ::WriteAttributes command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_multilevel_sensor_write_attributes( ++ nlohmann::json &jsn, ++ uic_mqtt_dotdot_multilevel_sensor_state_t &new_state, ++ uic_mqtt_dotdot_multilevel_sensor_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 6f34c390dc..4bb5c71735 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 +@@ -5915,6 +5915,18 @@ void uic_mqtt_dotdot_parse_configuration_parameters_write_attributes( + ); + + ++/** ++ * @brief JSON parser for MultilevelSensor WriteAttributes command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_multilevel_sensor_write_attributes( ++ nlohmann::json &jsn, ++ uic_mqtt_dotdot_multilevel_sensor_state_t &new_state, ++ uic_mqtt_dotdot_multilevel_sensor_updated_state_t &new_updated_state ++); ++ ++ + /** + * @brief Private helper function that will create a JSON string based on the + * fields of a ProtocolController/NetworkManagement Write command +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 6faf125b5f..9c5b838ded 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 +@@ -10915,6 +10915,46 @@ void uic_mqtt_dotdot_configuration_parameters_publish_generated_write_attributes + false); + } + ++ ++ ++/** ++ * @brief Publishes an incoming/generated WriteAttributes command for ++ * the MultilevelSensor cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/MultilevelSensor/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_multilevel_sensor_publish_generated_write_attributes_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_multilevel_sensor_state_t attribute_values, ++ uic_mqtt_dotdot_multilevel_sensor_updated_state_t attribute_list ++){ ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "MultilevelSensor/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); ++} ++ + /** + * @brief Publishes an incoming/generated Write command for + * the ProtocolController-NetworkManagement cluster. +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 7c2fca7faf..36023fc2e7 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 +@@ -354,6 +354,9 @@ static uic_mqtt_dotdot_by_group_configuration_parameters_discover_parameter_rang + static uic_mqtt_dotdot_by_group_configuration_parameters_write_attributes_callback_t uic_mqtt_dotdot_by_group_configuration_parameters_write_attributes_callback = nullptr; + + ++static uic_mqtt_dotdot_by_group_multilevel_sensor_write_attributes_callback_t uic_mqtt_dotdot_by_group_multilevel_sensor_write_attributes_callback = nullptr; ++ ++ + static uic_mqtt_dotdot_by_group_descriptor_write_attributes_callback_t uic_mqtt_dotdot_by_group_descriptor_write_attributes_callback = nullptr; + + +@@ -1835,6 +1838,15 @@ void uic_mqtt_dotdot_by_group_configuration_parameters_write_attributes_callback + + + ++// Callbacks setters ++void uic_mqtt_dotdot_by_group_multilevel_sensor_write_attributes_callback_set( ++ const uic_mqtt_dotdot_by_group_multilevel_sensor_write_attributes_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_multilevel_sensor_write_attributes_callback = callback; ++} ++ ++ ++ + // Callbacks setters + void uic_mqtt_dotdot_by_group_descriptor_write_attributes_callback_set( + const uic_mqtt_dotdot_by_group_descriptor_write_attributes_callback_t callback) +@@ -22908,6 +22920,91 @@ sl_status_t uic_mqtt_dotdot_by_group_configuration_parameters_init() + + + ++static void uic_mqtt_dotdot_on_by_group_multilevel_sensor_WriteAttributes( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_multilevel_sensor_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_multilevel_sensor_write_attributes_callback().empty())) { ++ try { ++ group_dispatch_callback(group_id, ++ "MultilevelSensor", ++ "WriteAttributes", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_multilevel_sensor_WriteAttributes); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "MultilevelSensor: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } else if (uic_mqtt_dotdot_by_group_multilevel_sensor_write_attributes_callback != nullptr) { ++ ++ uic_mqtt_dotdot_multilevel_sensor_state_t new_state = {}; ++ uic_mqtt_dotdot_multilevel_sensor_updated_state_t new_updated_state = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ uic_mqtt_dotdot_parse_multilevel_sensor_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, "MultilevelSensor", "WriteAttributes"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "MultilevelSensor", "WriteAttributes", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "MultilevelSensor", "WriteAttributes", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_multilevel_sensor_write_attributes_callback( ++ group_id, ++ new_state, ++ new_updated_state ++ ); ++ } ++} ++ ++sl_status_t uic_mqtt_dotdot_by_group_multilevel_sensor_init() ++{ ++ std::string subscription_topic; ++ const std::string topic_bygroup = TOPIC_BY_GROUP_PREFIX; ++ if(uic_mqtt_dotdot_by_group_multilevel_sensor_write_attributes_callback) { ++ subscription_topic = topic_bygroup + "MultilevelSensor/Commands/WriteAttributes"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_multilevel_sensor_WriteAttributes); ++ } ++ ++ return SL_STATUS_OK; ++} ++ ++ ++ ++ + static void uic_mqtt_dotdot_on_by_group_descriptor_WriteAttributes( + const char *topic, + const char *message, +@@ -23882,6 +23979,8 @@ void uic_mqtt_dotdot_set_group_dispatch_callback(group_dispatch_t callback) + uic_mqtt_subscribe("ucl/by-group/+/ConfigurationParameters/Commands/SetParameter", uic_mqtt_dotdot_on_by_group_configuration_parameters_set_parameter); + uic_mqtt_subscribe("ucl/by-group/+/ConfigurationParameters/Commands/DiscoverParameterRange", uic_mqtt_dotdot_on_by_group_configuration_parameters_discover_parameter_range); + ++ uic_mqtt_subscribe("ucl/by-group/+/MultilevelSensor/Commands/WriteAttributes", uic_mqtt_dotdot_on_by_group_multilevel_sensor_WriteAttributes); ++ + uic_mqtt_subscribe("ucl/by-group/+/Descriptor/Commands/WriteAttributes", uic_mqtt_dotdot_on_by_group_descriptor_WriteAttributes); + + uic_mqtt_subscribe("ucl/by-group/+/UnifyFanControl/Commands/WriteAttributes", uic_mqtt_dotdot_on_by_group_unify_fan_control_WriteAttributes); +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 c1531c376c..3cfdb34365 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 +@@ -3423,6 +3423,211 @@ uint32_t move_step_mode_get_enum_value_number(const std::string &str) + return std::numeric_limits::max(); + } + ++// Enum to string map for MultilevelSensorSensorType ++const std::map multilevel_sensor_sensor_type_enum_id_to_string_map { ++ { 1, "AirTemperature" }, ++ { 3, "Illuminance" }, ++ { 4, "Power" }, ++ { 5, "Humidity" }, ++ { 6, "Velocity" }, ++ { 7, "Direction" }, ++ { 8, "AtmosphericPressure" }, ++ { 9, "BarometricPressure" }, ++ { 10, "SolarRadiation" }, ++ { 11, "DewPoint" }, ++ { 12, "RainRate" }, ++ { 13, "TideLevel" }, ++ { 14, "Weight" }, ++ { 15, "Voltage" }, ++ { 16, "Current" }, ++ { 17, "CarbonDioxideCO2Level" }, ++ { 18, "AirFlow" }, ++ { 19, "TankCapacity" }, ++ { 20, "Distance" }, ++ { 22, "Rotation" }, ++ { 23, "WaterTempurature" }, ++ { 24, "SoilTempurature" }, ++ { 25, "SeismicIntensity" }, ++ { 26, "SeismicMagnitude" }, ++ { 27, "Ultraviolet" }, ++ { 28, "ElectricalResistivity" }, ++ { 29, "ElectricalConductivity" }, ++ { 30, "Loudness" }, ++ { 31, "Moisture" }, ++ { 32, "Frequency" }, ++ { 33, "Time" }, ++ { 34, "TargetTemperature" }, ++ { 35, "ParticulateMatter2.5" }, ++ { 36, "FormaldehydeLevel" }, ++ { 37, "RadonConcentration" }, ++ { 38, "MethaneDensity" }, ++ { 39, "VolatileOrganicCompoundLevel" }, ++ { 40, "CarbonMonoxideLevel" }, ++ { 41, "SoilHumidity" }, ++ { 42, "SoilReactivity" }, ++ { 43, "SoilSalinity" }, ++ { 44, "HeartRate" }, ++ { 45, "BloodPressure" }, ++ { 46, "MuscleMass" }, ++ { 47, "FatMass" }, ++ { 48, "BoneMass" }, ++ { 49, "TotalBodyWater" }, ++ { 50, "BasisMetabolicRate" }, ++ { 51, "BodyMassIndex" }, ++ { 52, "AccelerationX-axis" }, ++ { 53, "AccelerationY-axis" }, ++ { 54, "AccelerationZ-axis" }, ++ { 55, "SmokeDensity" }, ++ { 56, "WaterFlow" }, ++ { 57, "WaterPressure" }, ++ { 58, "RFSignalStrength" }, ++ { 59, "ParticulateMatter10" }, ++ { 60, "RespiratoryRate" }, ++ { 61, "RelativeModulationLevel" }, ++ { 62, "BoilerWaterTemperature" }, ++ { 63, "DomesticHotWaterTemperature" }, ++ { 64, "OutsideTemperature" }, ++ { 65, "ExhaustTemperature" }, ++ { 66, "WaterChlorineLevel" }, ++ { 67, "WaterAcidity" }, ++ { 68, "WaterOxidationReductionPotential" }, ++ { 69, "HeartRateLFHFRatio" }, ++ { 70, "MotionDirection" }, ++ { 71, "AppliedForceOnTheSensor" }, ++ { 72, "ReturnAirTemperature" }, ++ { 73, "SupplyAirTemperature" }, ++ { 74, "CondenserCoilTemperature" }, ++ { 75, "EvaproratorCoilTemperature" }, ++ { 76, "LiquidLineTemperature" }, ++ { 77, "DischargeLineTemperature" }, ++ { 78, "SuctionPressure" }, ++ { 79, "DischargePressure" }, ++ { 80, "DefrostTemperature" }, ++ { 81, "Ozone" }, ++ { 82, "SulfurDioxide" }, ++ { 83, "NitrogenDioxide" }, ++ { 84, "Ammonia" }, ++ { 85, "Lead" }, ++ { 86, "ParticulateMatter1" }, ++ { 87, "PersonCounterEntering" }, ++ { 88, "PersonCounterExiting" }, ++}; ++ ++// String to enum map for MultilevelSensorSensorType ++const std::map multilevel_sensor_sensor_type_enum_string_to_id_map { ++ { "AirTemperature", 1 }, ++ { "Illuminance", 3 }, ++ { "Power", 4 }, ++ { "Humidity", 5 }, ++ { "Velocity", 6 }, ++ { "Direction", 7 }, ++ { "AtmosphericPressure", 8 }, ++ { "BarometricPressure", 9 }, ++ { "SolarRadiation", 10 }, ++ { "DewPoint", 11 }, ++ { "RainRate", 12 }, ++ { "TideLevel", 13 }, ++ { "Weight", 14 }, ++ { "Voltage", 15 }, ++ { "Current", 16 }, ++ { "CarbonDioxideCO2Level", 17 }, ++ { "AirFlow", 18 }, ++ { "TankCapacity", 19 }, ++ { "Distance", 20 }, ++ { "Rotation", 22 }, ++ { "WaterTempurature", 23 }, ++ { "SoilTempurature", 24 }, ++ { "SeismicIntensity", 25 }, ++ { "SeismicMagnitude", 26 }, ++ { "Ultraviolet", 27 }, ++ { "ElectricalResistivity", 28 }, ++ { "ElectricalConductivity", 29 }, ++ { "Loudness", 30 }, ++ { "Moisture", 31 }, ++ { "Frequency", 32 }, ++ { "Time", 33 }, ++ { "TargetTemperature", 34 }, ++ { "ParticulateMatter2.5", 35 }, ++ { "FormaldehydeLevel", 36 }, ++ { "RadonConcentration", 37 }, ++ { "MethaneDensity", 38 }, ++ { "VolatileOrganicCompoundLevel", 39 }, ++ { "CarbonMonoxideLevel", 40 }, ++ { "SoilHumidity", 41 }, ++ { "SoilReactivity", 42 }, ++ { "SoilSalinity", 43 }, ++ { "HeartRate", 44 }, ++ { "BloodPressure", 45 }, ++ { "MuscleMass", 46 }, ++ { "FatMass", 47 }, ++ { "BoneMass", 48 }, ++ { "TotalBodyWater", 49 }, ++ { "BasisMetabolicRate", 50 }, ++ { "BodyMassIndex", 51 }, ++ { "AccelerationX-axis", 52 }, ++ { "AccelerationY-axis", 53 }, ++ { "AccelerationZ-axis", 54 }, ++ { "SmokeDensity", 55 }, ++ { "WaterFlow", 56 }, ++ { "WaterPressure", 57 }, ++ { "RFSignalStrength", 58 }, ++ { "ParticulateMatter10", 59 }, ++ { "RespiratoryRate", 60 }, ++ { "RelativeModulationLevel", 61 }, ++ { "BoilerWaterTemperature", 62 }, ++ { "DomesticHotWaterTemperature", 63 }, ++ { "OutsideTemperature", 64 }, ++ { "ExhaustTemperature", 65 }, ++ { "WaterChlorineLevel", 66 }, ++ { "WaterAcidity", 67 }, ++ { "WaterOxidationReductionPotential", 68 }, ++ { "HeartRateLFHFRatio", 69 }, ++ { "MotionDirection", 70 }, ++ { "AppliedForceOnTheSensor", 71 }, ++ { "ReturnAirTemperature", 72 }, ++ { "SupplyAirTemperature", 73 }, ++ { "CondenserCoilTemperature", 74 }, ++ { "EvaproratorCoilTemperature", 75 }, ++ { "LiquidLineTemperature", 76 }, ++ { "DischargeLineTemperature", 77 }, ++ { "SuctionPressure", 78 }, ++ { "DischargePressure", 79 }, ++ { "DefrostTemperature", 80 }, ++ { "Ozone", 81 }, ++ { "SulfurDioxide", 82 }, ++ { "NitrogenDioxide", 83 }, ++ { "Ammonia", 84 }, ++ { "Lead", 85 }, ++ { "ParticulateMatter1", 86 }, ++ { "PersonCounterEntering", 87 }, ++ { "PersonCounterExiting", 88 }, ++}; ++ ++std::string multilevel_sensor_sensor_type_get_enum_value_name( ++ uint32_t value) ++{ ++ auto it = multilevel_sensor_sensor_type_enum_id_to_string_map.find(value); ++ if (it != multilevel_sensor_sensor_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 multilevel_sensor_sensor_type_get_enum_value_number(const std::string &str) ++{ ++ auto it = multilevel_sensor_sensor_type_enum_string_to_id_map.find(str); ++ if (it != multilevel_sensor_sensor_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 NM_State + const std::map nm_state_enum_id_to_string_map { + { 0, "idle" }, +@@ -10193,6 +10398,21 @@ std::string get_enum_value_name( + #endif + } + ++ if (64777 == cluster_id) { ++ #ifdef MULTILEVEL_SENSOR_SENSOR_VALUES_ENUM_NAME_AVAILABLE ++ if (0 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: multilevel_sensorsensor_values instead of this: multilevel_sensor_sensor_values ++ return multilevel_sensor_sensor_values_get_enum_value_name(value); ++ } ++ #endif ++ #ifdef MULTILEVEL_SENSOR_SENSOR_TYPE_ENUM_NAME_AVAILABLE ++ if (1 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: multilevel_sensorsensor_type instead of this: multilevel_sensor_sensor_type ++ return multilevel_sensor_sensor_type_get_enum_value_name(value); ++ } ++ #endif ++ } ++ + if (64786 == cluster_id) { + #ifdef PROTOCOL_CONTROLLER_NETWORK_MANAGEMENT_NETWORK_MANAGEMENT_STATE_ENUM_NAME_AVAILABLE + if (1 == attribute_id) { +@@ -14700,6 +14920,21 @@ uint32_t get_enum_name_value( + #endif + } + ++ if (64777 == cluster_id) { ++ #ifdef MULTILEVEL_SENSOR_SENSOR_VALUES_ENUM_NAME_AVAILABLE ++ if (0 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: multilevel_sensorsensor_values instead of this: multilevel_sensor_sensor_values ++ return multilevel_sensor_sensor_values_get_enum_value_number(name); ++ } ++ #endif ++ #ifdef MULTILEVEL_SENSOR_SENSOR_TYPE_ENUM_NAME_AVAILABLE ++ if (1 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: multilevel_sensorsensor_type instead of this: multilevel_sensor_sensor_type ++ return multilevel_sensor_sensor_type_get_enum_value_number(name); ++ } ++ #endif ++ } ++ + if (64786 == cluster_id) { + #ifdef PROTOCOL_CONTROLLER_NETWORK_MANAGEMENT_NETWORK_MANAGEMENT_STATE_ENUM_NAME_AVAILABLE + if (1 == attribute_id) { +@@ -15688,6 +15923,17 @@ uint32_t move_step_mode_get_enum_value_number_c(const char *str) + { + return move_step_mode_get_enum_value_number(std::string(str)); + } ++char *multilevel_sensor_sensor_type_get_enum_value_name_c( ++ uint32_t value, char *result, size_t max_result_size) ++{ ++ snprintf(result, max_result_size, "%s", multilevel_sensor_sensor_type_get_enum_value_name(value).c_str()); ++ return result; ++} ++ ++uint32_t multilevel_sensor_sensor_type_get_enum_value_number_c(const char *str) ++{ ++ return multilevel_sensor_sensor_type_get_enum_value_number(std::string(str)); ++} + char *nm_state_get_enum_value_name_c( + uint32_t value, char *result, size_t max_result_size) + { +diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp +index 4d6e0f16c3..f7db295e9c 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp +@@ -2635,6 +2635,49 @@ void uic_mqtt_dotdot_configuration_parameters_publish_supported_generated_comman + } + + ++/** ++ * @brief Sends/Publishes a the SupportedGenerated commands for ++ * the MultilevelSensor cluster for a UNID/Endpoint ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/MultilevelSensor/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_multilevel_sensor_publish_supported_generated_commands( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_multilevel_sensor_supported_commands_t *command_list) ++{ ++ std::string topic = "ucl/by-unid/" + std::string(unid); ++ topic += "/ep"+ std::to_string(endpoint); ++ topic += "/MultilevelSensor/SupportedGeneratedCommands"; ++ ++ // Assemble of vector of strings for the Supported Commands: ++ std::vector command_vector; ++ if (command_list->write_attributes == true) { ++ command_vector.emplace_back("WriteAttributes"); ++ } ++ ++ // JSONify, then Stringify ++ nlohmann::json json_payload; ++ json_payload["value"] = command_vector; ++ std::string string_payload = json_payload.dump(); ++ ++ // Publish to MQTT ++ uic_mqtt_publish(topic.c_str(), ++ string_payload.c_str(), ++ string_payload.length(), ++ true); ++ ++} ++ ++ + /** + * @brief Sends/Publishes a the SupportedGenerated commands for + * the ProtocolController-NetworkManagement cluster for a UNID/Endpoint +diff --git a/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include b/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include +index f3ec21da18..c1fe725721 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include ++++ b/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include +@@ -3653,6 +3653,7 @@ static void unset_all_callbacks() + uic_mqtt_dotdot_configuration_parameters_set_parameter_callback_clear(); + uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callback_clear(); + uic_mqtt_dotdot_clear_configuration_parameters_write_attributes_callbacks(); ++ uic_mqtt_dotdot_clear_multilevel_sensor_write_attributes_callbacks(); + uic_mqtt_dotdot_protocol_controller_network_management_write_callback_clear(); + uic_mqtt_dotdot_clear_protocol_controller_network_management_write_attributes_callbacks(); + uic_mqtt_dotdot_clear_descriptor_write_attributes_callbacks(); +diff --git a/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes.uam b/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes.uam +index 2bf45a75f1..0c168c053a 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes.uam ++++ b/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes.uam +@@ -834,6 +834,10 @@ def DOTDOT_ATTRIBUTE_ID_NAME_AND_LOCATION_LOCATION 0xfd060001 + // This represents the attributes in the DotDot ConfigurationParameters cluster + def DOTDOT_ATTRIBUTE_ID_CONFIGURATION_PARAMETERS_CONFIGURATION_PARAMETERS 0xfd070000 + ++// This represents the attributes in the DotDot MultilevelSensor cluster ++def DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES 0xfd090000 ++def DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE 0xfd090001 ++ + // This represents the attributes in the DotDot AoXLocator cluster + def DOTDOT_ATTRIBUTE_ID_AOX_LOCATOR_REPORTING_MODE 0xfd100001 + def DOTDOT_ATTRIBUTE_ID_AOX_LOCATOR_POSITION_AND_ORIENTATION_VALID 0xfd100002 +diff --git a/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes_camel_case.uam b/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes_camel_case.uam +index ceb159d2c2..b867ea5a05 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes_camel_case.uam ++++ b/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes_camel_case.uam +@@ -834,6 +834,10 @@ def zb_Location 0xfd060001 + // This represents short CamelCase labels the attributes in the DotDot ConfigurationParameters cluster + def zb_ConfigurationParameters 0xfd070000 + ++// This represents short CamelCase labels the attributes in the DotDot MultilevelSensor cluster ++def zb_SensorValues 0xfd090000 ++def zb_SensorType 0xfd090001 ++ + // This represents short CamelCase labels the attributes in the DotDot AoXLocator cluster + def zb_ReportingMode 0xfd100001 + def zb_PositionAndOrientationValid 0xfd100002 +diff --git a/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_attribute_store_helpers.h b/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_attribute_store_helpers.h +index f99ee31747..e98230c88f 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_attribute_store_helpers.h ++++ b/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_attribute_store_helpers.h +@@ -75293,6 +75293,246 @@ bool dotdot_is_any_configuration_parameters_writable_attribute_supported( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint_id); + ++//////////////////////////////////////////////////////////////////////////////// ++// Start of cluster MultilevelSensor ++//////////////////////////////////////////////////////////////////////////////// ++// MultilevelSensor SensorValues ++/** ++ * @brief Verifies if the DotDot MultilevelSensor - SensorValues is supported ++ * under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * ++ * @returns true if SensorValues is supported ++ * @returns false if SensorValues is not supported ++ */ ++bool dotdot_is_supported_multilevel_sensor_sensor_values ( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Gets the DotDot MultilevelSensor - SensorValues attribute value under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to get, ++ * see \ref attribute_store_get_node_attribute_value ++ * ++ * ++ * @returns SensorValues attribute ++ */ ++SensorValue dotdot_get_multilevel_sensor_sensor_values( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state); ++ ++/** ++ * @brief Set the DotDot MultilevelSensor - SensorValues attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to write for the node, ++ * see \ref attribute_store_set_node_attribute_value ++ * ++ * @param new_sensor_values new value to set ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_set_multilevel_sensor_sensor_values( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ SensorValue new_sensor_values ++ ); ++ ++/** ++ * @brief Undefines the Reported value of the the DotDot MultilevelSensor - SensorValues ++ * attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_multilevel_sensor_sensor_values_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Undefines the Desired value of the DotDot ++ * MultilevelSensor - SensorValues attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_multilevel_sensor_sensor_values_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the reported value is defined for the DotDot ++ * MultilevelSensor - SensorValues attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_multilevel_sensor_sensor_values_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the desired value is defined for the DotDot ++ * MultilevelSensor - SensorValues attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_multilevel_sensor_sensor_values_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Creates a DotDot MultilevelSensor - SensorValues attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_create_multilevel_sensor_sensor_values( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++// MultilevelSensor SensorType ++/** ++ * @brief Verifies if the DotDot MultilevelSensor - SensorType is supported ++ * under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * ++ * @returns true if SensorType is supported ++ * @returns false if SensorType is not supported ++ */ ++bool dotdot_is_supported_multilevel_sensor_sensor_type ( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Gets the DotDot MultilevelSensor - SensorType attribute value under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to get, ++ * see \ref attribute_store_get_node_attribute_value ++ * ++ * ++ * @returns SensorType attribute ++ */ ++uint8_t dotdot_get_multilevel_sensor_sensor_type( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state); ++ ++/** ++ * @brief Set the DotDot MultilevelSensor - SensorType attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to write for the node, ++ * see \ref attribute_store_set_node_attribute_value ++ * ++ * @param new_sensor_type new value to set ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_set_multilevel_sensor_sensor_type( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_sensor_type ++ ); ++ ++/** ++ * @brief Undefines the Reported value of the the DotDot MultilevelSensor - SensorType ++ * attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_multilevel_sensor_sensor_type_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Undefines the Desired value of the DotDot ++ * MultilevelSensor - SensorType attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_multilevel_sensor_sensor_type_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the reported value is defined for the DotDot ++ * MultilevelSensor - SensorType attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_multilevel_sensor_sensor_type_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the desired value is defined for the DotDot ++ * MultilevelSensor - SensorType attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_multilevel_sensor_sensor_type_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Creates a DotDot MultilevelSensor - SensorType attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_create_multilevel_sensor_sensor_type( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if a UNID/Endpoint supports any attribute for the MultilevelSensor ++ * Cluster ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if at least 1 attribute in the Attribute Store, false otherwise ++ */ ++bool dotdot_is_any_multilevel_sensor_attribute_supported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if a UNID/Endpoint supports any writable attribute for the ++ * MultilevelSensor Cluster ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if at least 1 writable attribute in the Attribute Store, false otherwise ++ */ ++bool dotdot_is_any_multilevel_sensor_writable_attribute_supported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ + //////////////////////////////////////////////////////////////////////////////// + // Start of cluster ProtocolController-NetworkManagement + //////////////////////////////////////////////////////////////////////////////// +diff --git a/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_defined_attribute_types.h b/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_defined_attribute_types.h +index 46668d1948..6150a9ae87 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_defined_attribute_types.h ++++ b/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_defined_attribute_types.h +@@ -769,6 +769,9 @@ DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_NAME_AND_LOCATION_NAME , 0xfd060000) + DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_NAME_AND_LOCATION_LOCATION , 0xfd060001) + // Attribute Defines for ConfigurationParameters + DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_CONFIGURATION_PARAMETERS_CONFIGURATION_PARAMETERS , 0xfd070000) ++// Attribute Defines for MultilevelSensor ++DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES , 0xfd090000) ++DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE , 0xfd090001) + // Attribute Defines for ProtocolController-NetworkManagement + DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_PROTOCOL_CONTROLLER_NETWORK_MANAGEMENT_NETWORK_MANAGEMENT_STATE , 0xfd120001) + // Attribute Defines for Descriptor +diff --git a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_attribute_publisher.cpp b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_attribute_publisher.cpp +index 8446b11a47..d208971476 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_attribute_publisher.cpp ++++ b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_attribute_publisher.cpp +@@ -24477,6 +24477,235 @@ static void configuration_parameters_cluster_cluster_revision_callback( + } + + ++/** ++ * @brief Publishes the desired value of an updated attribute store node for ++ * the MultilevelSensor cluster. ++ * @param updated_node Updated attribute store node ++ * @param change Type of change applied ++ */ ++static void multilevel_sensor_cluster_publish_desired_value_callback( ++ attribute_store_node_t updated_node, attribute_store_change_t change) ++{ ++ // clang-format on ++ if (false == is_publish_desired_attribute_values_to_mqtt_enabled()) { ++ return; ++ } ++ if (change == ATTRIBUTE_DELETED || change == ATTRIBUTE_CREATED) { ++ return; ++ } ++ // Scene exception: check that the attribute is not under the Scene Table extension, which is a config and not the node's state. ++ if (ATTRIBUTE_STORE_INVALID_NODE ++ != attribute_store_get_first_parent_with_type( ++ updated_node, ++ DOTDOT_ATTRIBUTE_ID_SCENES_SCENE_TABLE)) { ++ return; ++ } ++ ++ // Get the UNID and EndPoint, and prepare the basic topic ++ char unid[MAXIMUM_UNID_SIZE] = {}; ++ // clang-format off ++ // clang-format on ++ dotdot_endpoint_id_t endpoint_id = 0; ++ if (SL_STATUS_OK ++ != unify_dotdot_attributes_get_unid_endpoint()(updated_node, ++ unid, ++ &endpoint_id)) { ++ return; ++ } ++ // clang-format off ++ // clang-format on ++ ++ std::string base_topic = "ucl/by-unid/" + std::string(unid); ++ // clang-format off ++ base_topic += "/ep" + std::to_string(endpoint_id); ++ // clang-format on ++ ++ attribute_store_type_t type = attribute_store_get_node_type(updated_node); ++ if (type == ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE) { ++ sl_log_debug(LOG_TAG, ++ "Warning: Invalid type for Attribute ID %d, " ++ "this should not happen.", ++ updated_node); ++ return; ++ } ++ ++ // If the value got updated but both Reported and Desired undefined, we skip publication ++ if (false == attribute_store_is_reported_defined(updated_node) ++ && false == attribute_store_is_desired_defined(updated_node)) { ++ sl_log_debug(LOG_TAG, ++ "Reported/Desired values are undefined. " ++ "Skipping publication"); ++ return; ++ } ++ ++ // clang-format off ++ try { ++ attribute_store::attribute attr(updated_node); ++ // Skip attribute SensorValues because it is a struct, ++ // we typically don't save them as structs in the attribute store. ++ sl_log_debug(LOG_TAG,"Warning: Cannot publish desired value for attribute MultilevelSensor SensorValues. Structs are not supported"); ++ if (type == DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE) { ++ uic_mqtt_dotdot_multilevel_sensor_sensor_type_publish( ++ base_topic.c_str(), ++ static_cast(attr.desired_or_reported()), ++ UCL_MQTT_PUBLISH_TYPE_DESIRED); ++ return; ++ } ++ } catch (std::exception &ex) { ++ sl_log_warning(LOG_TAG, "Failed to publish the Desired attribute value: %s", ex.what()); ++ } ++} ++ ++/** ++ * @brief Publishes the reported value of an updated attribute store node for ++ * the MultilevelSensor cluster. ++ * @param updated_node Updated attribute store node ++ * @param change Type of change applied ++ */ ++static void multilevel_sensor_cluster_publish_reported_value_callback( ++ attribute_store_node_t updated_node, attribute_store_change_t change) ++{ ++ // clang-format on ++ if (false == is_publish_reported_attribute_values_to_mqtt_enabled()) { ++ return; ++ } ++ if (change == ATTRIBUTE_CREATED) { ++ return; ++ } ++ // Scene exception: check that the attribute is not under the Scene Table extension, which is a config and not the node's state. ++ if (ATTRIBUTE_STORE_INVALID_NODE ++ != attribute_store_get_first_parent_with_type( ++ updated_node, ++ DOTDOT_ATTRIBUTE_ID_SCENES_SCENE_TABLE)) { ++ return; ++ } ++ ++ // Get the UNID and EndPoint, and prepare the basic topic ++ char unid[MAXIMUM_UNID_SIZE] = {}; ++ // clang-format off ++ // clang-format on ++ dotdot_endpoint_id_t endpoint_id = 0; ++ if (SL_STATUS_OK ++ != unify_dotdot_attributes_get_unid_endpoint()(updated_node, ++ unid, ++ &endpoint_id)) { ++ return; ++ } ++ // clang-format off ++ // clang-format on ++ ++ std::string base_topic = "ucl/by-unid/" + std::string(unid); ++ // clang-format off ++ base_topic += "/ep" + std::to_string(endpoint_id); ++ // clang-format on ++ ++ attribute_store_type_t type = attribute_store_get_node_type(updated_node); ++ if (type == ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE) { ++ sl_log_debug(LOG_TAG, ++ "Warning: Invalid type for Attribute ID %d, " ++ "this should not happen.", ++ updated_node); ++ return; ++ } ++ ++ // Deletion case: ++ if (change == ATTRIBUTE_DELETED) { ++ // clang-format off ++ switch(type) { ++ case DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES: ++ // clang-format on ++ sl_log_debug(LOG_TAG, ++ "Unretaining MultilevelSensor::SensorValues under topic %s", ++ base_topic.c_str()); ++ // clang-format off ++ uic_mqtt_dotdot_multilevel_sensor_sensor_values_unretain(base_topic.c_str(), UCL_MQTT_PUBLISH_TYPE_ALL); ++ break; ++ case DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE: ++ // clang-format on ++ sl_log_debug(LOG_TAG, ++ "Unretaining MultilevelSensor::SensorType under topic %s", ++ base_topic.c_str()); ++ // clang-format off ++ uic_mqtt_dotdot_multilevel_sensor_sensor_type_unretain(base_topic.c_str(), UCL_MQTT_PUBLISH_TYPE_ALL); ++ break; ++ default: ++ break; ++ } ++ // clang-format on ++ return; ++ } ++ ++ // If the value got updated but undefined, we skip publication ++ if (false == attribute_store_is_reported_defined(updated_node)) { ++ sl_log_debug(LOG_TAG, "Reported value is undefined. Skipping publication"); ++ return; ++ } ++ ++ // Else we assume update case: ++ // clang-format off ++ try { ++ attribute_store::attribute attr(updated_node); ++ // Skip attribute SensorValues because it is a struct, ++ // we typically don't save them as structs in the attribute store. ++ sl_log_debug(LOG_TAG,"Warning: Cannot publish reported value for attribute MultilevelSensor SensorValues. Structs are not supported"); ++ if (type == DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE) { ++ uic_mqtt_dotdot_multilevel_sensor_sensor_type_publish( ++ base_topic.c_str(), ++ static_cast(attr.reported()), ++ (attr.desired_exists() && !attribute_store_is_value_matched(updated_node)) ? UCL_MQTT_PUBLISH_TYPE_REPORTED : UCL_MQTT_PUBLISH_TYPE_ALL); ++ return; ++ } ++ } catch (std::exception &ex) { ++ sl_log_warning(LOG_TAG, "Failed to publish the Reported attribute value: %s", ex.what()); ++ } ++} ++ ++static void multilevel_sensor_cluster_cluster_revision_callback( ++ attribute_store_node_t updated_node, attribute_store_change_t change) ++{ ++ // clang-format on ++ if (false == is_publish_reported_attribute_values_to_mqtt_enabled()) { ++ return; ++ } ++ ++ // Get the UNID and EndPoint, and prepare the basic topic ++ char unid[MAXIMUM_UNID_SIZE] = {}; ++ dotdot_endpoint_id_t endpoint_id = 0; ++ // clang-format off ++ // clang-format on ++ if (SL_STATUS_OK ++ != unify_dotdot_attributes_get_unid_endpoint()(updated_node, ++ unid, ++ &endpoint_id)) { ++ return; ++ } ++ // clang-format off ++ // clang-format on ++ ++ std::string base_topic = "ucl/by-unid/" + std::string(unid); ++ // clang-format off ++ base_topic += "/ep" + std::to_string(endpoint_id); ++ ++ if ((change == ATTRIBUTE_CREATED) || (change == ATTRIBUTE_UPDATED)) { ++ // On attribute creation, make sure to publish the attribute revision for the first time ++ std::string cluster_revision_topic = base_topic + "/MultilevelSensor/Attributes/ClusterRevision"; ++ if (uic_mqtt_count_topics(cluster_revision_topic.c_str()) == 0) { ++ uic_mqtt_dotdot_multilevel_sensor_publish_cluster_revision(base_topic.c_str(), 1); ++ } ++ } ++ ++ if (change == ATTRIBUTE_DELETED) { ++ // Check if we just erased the last attribute under a cluster, if yes, unretain ++ // the Cluster revision too. ++ if (false == dotdot_is_any_multilevel_sensor_attribute_supported(unid, endpoint_id)) { ++ base_topic += "/MultilevelSensor"; ++ sl_log_debug(LOG_TAG, "No more attributes supported for MultilevelSensor cluster for UNID %s Endpoint %d. Unretaining leftover topics at %s",unid, endpoint_id, base_topic.c_str()); ++ uic_mqtt_unretain(base_topic.c_str()); ++ } ++ } ++} ++ ++ + /** + * @brief Publishes the desired value of an updated attribute store node for + * the ProtocolController-NetworkManagement cluster. +@@ -35755,6 +35984,34 @@ sl_status_t unify_dotdot_attribute_store_attribute_publisher_init() + configuration_parameters_cluster_cluster_revision_callback, + DOTDOT_ATTRIBUTE_ID_CONFIGURATION_PARAMETERS_CONFIGURATION_PARAMETERS); + //Desired attribute state ++ attribute_store_register_callback_by_type_and_state( ++ multilevel_sensor_cluster_publish_desired_value_callback, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES, ++ DESIRED_ATTRIBUTE); ++ //Reported attribute state ++ attribute_store_register_callback_by_type_and_state( ++ multilevel_sensor_cluster_publish_reported_value_callback, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES, ++ REPORTED_ATTRIBUTE); ++ //registering a callback when an attribute is created for publishing cluster revision ++ attribute_store_register_callback_by_type( ++ multilevel_sensor_cluster_cluster_revision_callback, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES); ++ //Desired attribute state ++ attribute_store_register_callback_by_type_and_state( ++ multilevel_sensor_cluster_publish_desired_value_callback, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE, ++ DESIRED_ATTRIBUTE); ++ //Reported attribute state ++ attribute_store_register_callback_by_type_and_state( ++ multilevel_sensor_cluster_publish_reported_value_callback, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE, ++ REPORTED_ATTRIBUTE); ++ //registering a callback when an attribute is created for publishing cluster revision ++ attribute_store_register_callback_by_type( ++ multilevel_sensor_cluster_cluster_revision_callback, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE); ++ //Desired attribute state + attribute_store_register_callback_by_type_and_state( + protocol_controller_network_management_cluster_publish_desired_value_callback, + DOTDOT_ATTRIBUTE_ID_PROTOCOL_CONTROLLER_NETWORK_MANAGEMENT_NETWORK_MANAGEMENT_STATE, +diff --git a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_force_read_attributes_command_callbacks.c b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_force_read_attributes_command_callbacks.c +index 8237315595..9774152fb6 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_force_read_attributes_command_callbacks.c ++++ b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_force_read_attributes_command_callbacks.c +@@ -4325,6 +4325,41 @@ static sl_status_t uic_mqtt_dotdot_configuration_parameters_force_read_attribute + return SL_STATUS_OK; + } + //////////////////////////////////////////////////////////////////////////////// ++// Start of cluster MultilevelSensor ++//////////////////////////////////////////////////////////////////////////////// ++static sl_status_t uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback ( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uic_mqtt_dotdot_multilevel_sensor_updated_state_t attribute_list) { ++ ++ if (false == is_force_read_attributes_enabled()){ ++ return SL_STATUS_FAIL; ++ } ++ ++ if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { ++ if (is_automatic_deduction_of_supported_commands_enabled()) { ++ return dotdot_is_any_multilevel_sensor_attribute_supported(unid, endpoint_id) ? ++ SL_STATUS_OK : SL_STATUS_FAIL; ++ } else { ++ return SL_STATUS_FAIL; ++ } ++ } ++ ++ // Go and undefine everything that needs to be read again: ++ if (true == attribute_list.sensor_values) { ++ if (SL_STATUS_OK == dotdot_multilevel_sensor_sensor_values_undefine_reported(unid, endpoint_id)) { ++ sl_log_debug(LOG_TAG, "Undefined Reported value of MultilevelSensor::SensorValues under %s - Endpoint %d", unid, endpoint_id); ++ } ++ } ++ if (true == attribute_list.sensor_type) { ++ if (SL_STATUS_OK == dotdot_multilevel_sensor_sensor_type_undefine_reported(unid, endpoint_id)) { ++ sl_log_debug(LOG_TAG, "Undefined Reported value of MultilevelSensor::SensorType under %s - Endpoint %d", unid, endpoint_id); ++ } ++ } ++ return SL_STATUS_OK; ++} ++//////////////////////////////////////////////////////////////////////////////// + // Start of cluster Descriptor + //////////////////////////////////////////////////////////////////////////////// + static sl_status_t uic_mqtt_dotdot_descriptor_force_read_attributes_callback ( +@@ -4657,6 +4692,8 @@ sl_status_t + + uic_mqtt_dotdot_set_configuration_parameters_force_read_attributes_callback(&uic_mqtt_dotdot_configuration_parameters_force_read_attributes_callback); + ++ uic_mqtt_dotdot_set_multilevel_sensor_force_read_attributes_callback(&uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback); ++ + + uic_mqtt_dotdot_set_descriptor_force_read_attributes_callback(&uic_mqtt_dotdot_descriptor_force_read_attributes_callback); + +diff --git a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_helpers.cpp b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_helpers.cpp +index bbcc3f7fad..95fffa41fc 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_helpers.cpp ++++ b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_helpers.cpp +@@ -81051,6 +81051,255 @@ bool dotdot_is_any_configuration_parameters_writable_attribute_supported( + const dotdot_endpoint_id_t endpoint_id) { + + ++ return false; ++} ++//////////////////////////////////////////////////////////////////////////////// ++// Start of cluster MultilevelSensor ++//////////////////////////////////////////////////////////////////////////////// ++bool dotdot_is_supported_multilevel_sensor_sensor_values( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES); ++ return attribute_store_node_exists(node); ++} ++ ++SensorValue dotdot_get_multilevel_sensor_sensor_values( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES); ++ ++ SensorValue result = {}; ++ attribute_store_read_value(node, ++ value_state, ++ (uint8_t *)&result, ++ sizeof(result)); ++ return result; ++} ++ ++sl_status_t dotdot_set_multilevel_sensor_sensor_values( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ SensorValue new_sensor_values ++ ) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES); ++ ++ // Skip attribute SensorValues because it is a struct, ++ // we typically don't save them as structs in the attribute store. ++ sl_log_error(LOG_TAG, "Error, skipping to change the desired value of SensorValues, Attribute %d, " ++ "because it is a complicated type (struct: SensorValue). " ++ "Please change the code to do this manually.", node); ++ return SL_STATUS_FAIL; ++} ++ ++sl_status_t dotdot_multilevel_sensor_sensor_values_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES); ++ attribute_store_undefine_reported(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++sl_status_t dotdot_multilevel_sensor_sensor_values_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES); ++ attribute_store_undefine_desired(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++ ++bool dotdot_multilevel_sensor_sensor_values_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES); ++ return attribute_store_is_reported_defined(node); ++} ++ ++bool dotdot_multilevel_sensor_sensor_values_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES); ++ return attribute_store_is_desired_defined(node); ++} ++ ++sl_status_t dotdot_create_multilevel_sensor_sensor_values( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node = ++ attribute_store_create_child_if_missing(endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES); ++ ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++bool dotdot_is_supported_multilevel_sensor_sensor_type( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE); ++ return attribute_store_node_exists(node); ++} ++ ++uint8_t dotdot_get_multilevel_sensor_sensor_type( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE); ++ ++ uint8_t result = {}; ++ attribute_store_read_value(node, ++ value_state, ++ (uint8_t *)&result, ++ sizeof(result)); ++ return result; ++} ++ ++sl_status_t dotdot_set_multilevel_sensor_sensor_type( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_sensor_type ++ ) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE); ++ ++ return attribute_store_set_node_attribute_value(node, ++ value_state, ++ (uint8_t *)&new_sensor_type, ++ sizeof(uint8_t)); ++ } ++ ++sl_status_t dotdot_multilevel_sensor_sensor_type_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE); ++ attribute_store_undefine_reported(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++sl_status_t dotdot_multilevel_sensor_sensor_type_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE); ++ attribute_store_undefine_desired(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++ ++bool dotdot_multilevel_sensor_sensor_type_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE); ++ return attribute_store_is_reported_defined(node); ++} ++ ++bool dotdot_multilevel_sensor_sensor_type_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE); ++ return attribute_store_is_desired_defined(node); ++} ++ ++sl_status_t dotdot_create_multilevel_sensor_sensor_type( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node = ++ attribute_store_create_child_if_missing(endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE); ++ ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++bool dotdot_is_any_multilevel_sensor_attribute_supported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ if (true == dotdot_is_supported_multilevel_sensor_sensor_values(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_multilevel_sensor_sensor_type(unid, endpoint_id)) { ++ return true; ++ } ++ ++ return false; ++} ++ ++bool dotdot_is_any_multilevel_sensor_writable_attribute_supported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ + return false; + } + //////////////////////////////////////////////////////////////////////////////// +diff --git a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_registration.cpp b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_registration.cpp +index a321941cf6..bbc56dd97a 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_registration.cpp ++++ b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_registration.cpp +@@ -16807,6 +16807,54 @@ sl_status_t unify_dotdot_attribute_store_registration_init() + // clang-format off + // clang-format on + ++ { ++ // SensorValue // SensorValue // SensorValue ++ std::string attribute_type_string = "SensorValue"; ++ attribute_store_storage_type_t storage_type = UNKNOWN_STORAGE_TYPE; ++ ++ // clang-format off ++ storage_type = BYTE_ARRAY_STORAGE_TYPE; ++ ++ if (storage_type == UNKNOWN_STORAGE_TYPE) { ++ sl_log_warning(LOG_TAG, ++ "Unkown storage type for ZCL MultilevelSensor SensorValues, " ++ "type: SensorValue // SensorValue"); ++ } ++ ++ status |= attribute_store_register_type( ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES, ++ "ZCL MultilevelSensor SensorValues", ++ ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE, ++ storage_type); ++ } ++ ++ // clang-format off ++ // clang-format on ++ ++ { ++ // enum8 // enum8 // uint8_t ++ std::string attribute_type_string = "uint8_t"; ++ attribute_store_storage_type_t storage_type = UNKNOWN_STORAGE_TYPE; ++ ++ // clang-format off ++ storage_type = attribute_storage_type_conversion(attribute_type_string); ++ ++ if (storage_type == UNKNOWN_STORAGE_TYPE) { ++ sl_log_warning(LOG_TAG, ++ "Unkown storage type for ZCL MultilevelSensor SensorType, " ++ "type: enum8 // uint8_t"); ++ } ++ ++ status |= attribute_store_register_type( ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE, ++ "ZCL MultilevelSensor SensorType", ++ ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE, ++ storage_type); ++ } ++ ++ // clang-format off ++ // clang-format on ++ + { + // NetworkManagementState // NetworkManagementState // NetworkManagementState + std::string attribute_type_string = "NetworkManagementState"; +diff --git a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_write_attributes_command_callbacks.c b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_write_attributes_command_callbacks.c +index 799780c184..0eb24791b3 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_write_attributes_command_callbacks.c ++++ b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_write_attributes_command_callbacks.c +@@ -2398,6 +2398,36 @@ static sl_status_t configuration_parameters_cluster_write_attributes_callback( + return SL_STATUS_OK; + } + //////////////////////////////////////////////////////////////////////////////// ++// Start of cluster MultilevelSensor ++//////////////////////////////////////////////////////////////////////////////// ++// WriteAttribute Callbacks multilevel_sensor ++static sl_status_t multilevel_sensor_cluster_write_attributes_callback( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uic_mqtt_dotdot_multilevel_sensor_state_t attributes, ++ uic_mqtt_dotdot_multilevel_sensor_updated_state_t updated_attributes) ++{ ++ if (false == is_write_attributes_enabled()) { ++ return SL_STATUS_FAIL; ++ } ++ ++ if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { ++ if (is_automatic_deduction_of_supported_commands_enabled()) { ++ return dotdot_is_any_multilevel_sensor_writable_attribute_supported(unid, endpoint_id) ? ++ SL_STATUS_OK : SL_STATUS_FAIL; ++ } else { ++ return SL_STATUS_FAIL; ++ } ++ } ++ ++ sl_log_debug(LOG_TAG, ++ "multilevel_sensor: Incoming WriteAttributes command for %s, endpoint %d.\n", ++ unid, ++ endpoint_id); ++ return SL_STATUS_OK; ++} ++//////////////////////////////////////////////////////////////////////////////// + // Start of cluster ProtocolController-NetworkManagement + //////////////////////////////////////////////////////////////////////////////// + // WriteAttribute Callbacks protocol_controller_network_management +@@ -2710,6 +2740,9 @@ sl_status_t + uic_mqtt_dotdot_set_configuration_parameters_write_attributes_callback( + &configuration_parameters_cluster_write_attributes_callback); + ++ uic_mqtt_dotdot_set_multilevel_sensor_write_attributes_callback( ++ &multilevel_sensor_cluster_write_attributes_callback); ++ + uic_mqtt_dotdot_set_protocol_controller_network_management_write_attributes_callback( + &protocol_controller_network_management_cluster_write_attributes_callback); + +diff --git a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c +index d43942b157..a5dd3ae27f 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c ++++ b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c +@@ -1260,6 +1260,16 @@ static uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callbac + uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callback_t get_uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callback(){ + return test_uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callback; + } ++static uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback_t test_uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback = NULL; ++static uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback_t test_uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback = NULL; ++ ++uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback_t get_uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback(){ ++ return test_uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback; ++} ++uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback_t get_uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback(){ ++ return test_uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback; ++} ++ + static uic_mqtt_dotdot_protocol_controller_network_management_force_read_attributes_callback_t test_uic_mqtt_dotdot_protocol_controller_network_management_force_read_attributes_callback = NULL; + static uic_mqtt_dotdot_protocol_controller_network_management_write_attributes_callback_t test_uic_mqtt_dotdot_protocol_controller_network_management_write_attributes_callback = NULL; + +@@ -2856,6 +2866,16 @@ void uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callback_ + { + test_uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callback = callback; + } ++void set_uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback_stub( ++ const uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback = callback; ++} ++void set_uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback_stub( ++ const uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback = callback; ++} + void set_uic_mqtt_dotdot_protocol_controller_network_management_force_read_attributes_callback_stub( + const uic_mqtt_dotdot_protocol_controller_network_management_force_read_attributes_callback_t callback, int cmock_num_calls) + { +@@ -3818,6 +3838,12 @@ void setUp() + test_uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callback = NULL; + uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callback_set_Stub( + &uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callback_set_stub); ++ test_uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback = NULL; ++ uic_mqtt_dotdot_set_multilevel_sensor_force_read_attributes_callback_Stub( ++ &set_uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback_stub); ++ test_uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback = NULL; ++ uic_mqtt_dotdot_set_multilevel_sensor_write_attributes_callback_Stub( ++ &set_uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback_stub); + test_uic_mqtt_dotdot_protocol_controller_network_management_force_read_attributes_callback = NULL; + uic_mqtt_dotdot_set_protocol_controller_network_management_force_read_attributes_callback_Stub( + &set_uic_mqtt_dotdot_protocol_controller_network_management_force_read_attributes_callback_stub); +@@ -4604,6 +4630,8 @@ void test_automatic_deduction_of_supported_commands() + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_name_and_location_name(expected_unid,expected_endpoint_id) ); + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_name_and_location_location(expected_unid,expected_endpoint_id) ); + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_configuration_parameters_configuration_parameters(expected_unid,expected_endpoint_id) ); ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_multilevel_sensor_sensor_values(expected_unid,expected_endpoint_id) ); ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_multilevel_sensor_sensor_type(expected_unid,expected_endpoint_id) ); + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_protocol_controller_network_management_network_management_state(expected_unid,expected_endpoint_id) ); + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_descriptor_device_type_list(expected_unid,expected_endpoint_id) ); + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_fan_control_z_wave_fan_mode(expected_unid,expected_endpoint_id) ); +diff --git a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h +index 73c36434ca..35ada30800 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h ++++ b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h +@@ -769,6 +769,10 @@ + uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callback_t get_uic_mqtt_dotdot_configuration_parameters_discover_parameter_range_callback(); + + ++ uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback_t get_uic_mqtt_dotdot_multilevel_sensor_force_read_attributes_callback(); ++ uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback_t get_uic_mqtt_dotdot_multilevel_sensor_write_attributes_callback(); ++ ++ + uic_mqtt_dotdot_protocol_controller_network_management_force_read_attributes_callback_t get_uic_mqtt_dotdot_protocol_controller_network_management_force_read_attributes_callback(); + uic_mqtt_dotdot_protocol_controller_network_management_write_attributes_callback_t get_uic_mqtt_dotdot_protocol_controller_network_management_write_attributes_callback(); + +-- +2.39.5 + diff --git a/patches/UnifySDK/0010-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch b/patches/UnifySDK/0010-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch new file mode 100644 index 000000000..304876f6b --- /dev/null +++ b/patches/UnifySDK/0010-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch @@ -0,0 +1,101 @@ +From c0ecd3accaa8958ed7c698c31eda84c504352413 Mon Sep 17 00:00:00 2001 +From: Philippe Coval +Date: Tue, 16 Sep 2025 10:58:38 +0200 +Subject: [PATCH] UIC-3273: Generated files for Unify_MultilevelSensor using + latest zap + +Relate-to: https://github.com/project-chip/zap/releases/download/v2025.07.24/zap-linux-x64.deb +Signed-off-by: Philippe Coval +--- + .../src/eed_attribute_store_clusters.c | 8 +++++ + .../src/eed_dotdot_create_clusters.cpp | 34 +++++++++++++++++++ + 2 files changed, 42 insertions(+) + +diff --git a/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_attribute_store_clusters.c b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_attribute_store_clusters.c +index 8780c887c8..981d5e7ef4 100644 +--- a/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_attribute_store_clusters.c ++++ b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_attribute_store_clusters.c +@@ -2687,6 +2687,14 @@ sl_status_t eed_attribute_store_clusters_init() + &on_zcl_desired_value_update, + DOTDOT_ATTRIBUTE_ID_CONFIGURATION_PARAMETERS_CONFIGURATION_PARAMETERS, + DESIRED_ATTRIBUTE); ++ attribute_store_register_callback_by_type_and_state( ++ &on_zcl_desired_value_update, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES, ++ DESIRED_ATTRIBUTE); ++ attribute_store_register_callback_by_type_and_state( ++ &on_zcl_desired_value_update, ++ DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE, ++ DESIRED_ATTRIBUTE); + attribute_store_register_callback_by_type_and_state( + &on_zcl_desired_value_update, + DOTDOT_ATTRIBUTE_ID_DESCRIPTOR_DEVICE_TYPE_LIST, +diff --git a/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_dotdot_create_clusters.cpp b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_dotdot_create_clusters.cpp +index 8230ced6c8..0a74dd6e3e 100644 +--- a/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_dotdot_create_clusters.cpp ++++ b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_dotdot_create_clusters.cpp +@@ -3990,6 +3990,22 @@ void dotdot_create_configuration_parameters_wrapper(const dotdot_unid_t unid, co + + } + ++void dotdot_create_multilevel_sensor_wrapper(const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id){ ++ // Create and set a default value if undefined. ++ dotdot_create_multilevel_sensor_sensor_values(unid,endpoint_id); ++ if (false == dotdot_multilevel_sensor_sensor_values_is_reported_defined(unid,endpoint_id)){ ++ SensorValue value = {}; ++ dotdot_set_multilevel_sensor_sensor_values(unid,endpoint_id,REPORTED_ATTRIBUTE, value); ++ } ++ ++ // Create and set a default value if undefined. ++ dotdot_create_multilevel_sensor_sensor_type(unid,endpoint_id); ++ if (false == dotdot_multilevel_sensor_sensor_type_is_reported_defined(unid,endpoint_id)){ ++ dotdot_set_multilevel_sensor_sensor_type(unid,endpoint_id,REPORTED_ATTRIBUTE, static_cast(0)); ++ } ++ ++} ++ + void dotdot_create_descriptor_wrapper(const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id){ + // Create and set a default value if undefined. + dotdot_create_descriptor_device_type_list(unid,endpoint_id); +@@ -6515,6 +6531,22 @@ void dotdot_unretain_configuration_parameters_wrapper(const dotdot_unid_t unid, + uic_mqtt_dotdot_configuration_parameters_publish_empty_supported_commands(unid, endpoint_id); + } + ++void dotdot_unretain_multilevel_sensor_wrapper(const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id){ ++ char base_topic[256]; ++ snprintf(base_topic, sizeof(base_topic), "ucl/by-unid/%s/ep%d", unid, endpoint_id); ++ attribute_store::attribute ep_node = eed_attribute_store_get_endpoint_node(unid, endpoint_id); ++ ++ uic_mqtt_dotdot_multilevel_sensor_sensor_values_unretain(base_topic,UCL_MQTT_PUBLISH_TYPE_ALL); ++ ep_node.child_by_type(DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_VALUES).delete_node(); ++ ++ uic_mqtt_dotdot_multilevel_sensor_sensor_type_unretain(base_topic,UCL_MQTT_PUBLISH_TYPE_ALL); ++ ep_node.child_by_type(DOTDOT_ATTRIBUTE_ID_MULTILEVEL_SENSOR_SENSOR_TYPE).delete_node(); ++ ++ ++ uic_mqtt_dotdot_multilevel_sensor_unretain_cluster_revision(base_topic); ++ uic_mqtt_dotdot_multilevel_sensor_publish_empty_supported_commands(unid, endpoint_id); ++} ++ + void dotdot_unretain_descriptor_wrapper(const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id){ + char base_topic[256]; + snprintf(base_topic, sizeof(base_topic), "ucl/by-unid/%s/ep%d", unid, endpoint_id); +@@ -6707,6 +6739,7 @@ std::map CreateClusterMap = { + { "Binding", dotdot_create_binding_wrapper }, + { "NameAndLocation", dotdot_create_name_and_location_wrapper }, + { "ConfigurationParameters", dotdot_create_configuration_parameters_wrapper }, ++{ "MultilevelSensor", dotdot_create_multilevel_sensor_wrapper }, + { "Descriptor", dotdot_create_descriptor_wrapper }, + { "UnifyFanControl", dotdot_create_unify_fan_control_wrapper }, + { "UnifyThermostat", dotdot_create_unify_thermostat_wrapper }, +@@ -6758,6 +6791,7 @@ std::map CreateUnretainMap = { + { "Binding", dotdot_unretain_binding_wrapper }, + { "NameAndLocation", dotdot_unretain_name_and_location_wrapper }, + { "ConfigurationParameters", dotdot_unretain_configuration_parameters_wrapper }, ++{ "MultilevelSensor", dotdot_unretain_multilevel_sensor_wrapper }, + { "Descriptor", dotdot_unretain_descriptor_wrapper }, + { "UnifyFanControl", dotdot_unretain_unify_fan_control_wrapper }, + { "UnifyThermostat", dotdot_unretain_unify_thermostat_wrapper }, +-- +2.39.5 + From b2040529675dbbd1b42889d9e545659b9e10071d Mon Sep 17 00:00:00 2001 From: Philippe Coval Date: Tue, 16 Sep 2025 14:51:39 +0200 Subject: [PATCH 02/12] WIP: mod: patches/UnifySDK/0010-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch (phcoval/cc/review/main) Signed-off-by: Philippe Coval --- ...0-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/UnifySDK/0010-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch b/patches/UnifySDK/0010-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch index 304876f6b..bf261c225 100644 --- a/patches/UnifySDK/0010-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch +++ b/patches/UnifySDK/0010-UIC-3273-Generated-files-for-Unify_MultilevelSensor-.patch @@ -1,4 +1,4 @@ -From c0ecd3accaa8958ed7c698c31eda84c504352413 Mon Sep 17 00:00:00 2001 +From 6bb1911c76658081391ac3bd8c268c374e3617f0 Mon Sep 17 00:00:00 2001 From: Philippe Coval Date: Tue, 16 Sep 2025 10:58:38 +0200 Subject: [PATCH] UIC-3273: Generated files for Unify_MultilevelSensor using From 797882de648dc401f597398eea7cbb9ed0e89c04 Mon Sep 17 00:00:00 2001 From: ptphan Date: Wed, 2 Oct 2024 10:40:35 +0700 Subject: [PATCH 03/12] UIC-3273: Custom Unify_MultilevelSensor cluster Apply splited change from uic, [Philippe Coval] This patch was split in two, this version is the change that apply to Unify, please refer to previous commit to undestand the flow, I after the failed cherry-pick, I just used patch -p1 < patch and commited only the changes that applies to z-p-c, the same operation was done in UnifySDK (see log in provious patchset) Origin: ver_1.7.0-unstable-23-g38f24ffb48 Bug-SiliconLabs: UIC-3273 Origin: s.s.com/projects/UIC/repos/uic/pull-requests/2855 Relate-to: https://github.com/SiliconLabsSoftware/z-wave-protocol-controller/issues/44 Forwarded: https://github.com/rzr/UnifySDK/tree/z-wave/core/zpc/main Forwarded: https://github.com/SiliconLabsSoftware/z-wave-protocol-controller/pull/143 Signed-off-by: Philippe Coval --- .../zcl_cluster_servers/CMakeLists.txt | 1 + .../src/multilevel_sensor_cluster_server.cpp | 181 ++++++++++++++++++ .../src/multilevel_sensor_cluster_server.h | 44 +++++ .../src/zcl_cluster_servers.cpp | 2 + 4 files changed, 228 insertions(+) create mode 100644 applications/zpc/components/zcl_cluster_servers/src/multilevel_sensor_cluster_server.cpp create mode 100644 applications/zpc/components/zcl_cluster_servers/src/multilevel_sensor_cluster_server.h diff --git a/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt b/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt index 8827e1f08..41a947535 100644 --- a/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt +++ b/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt @@ -17,6 +17,7 @@ add_library( src/zcl_OTA_cluster_server.cpp src/zcl_rf_telemetry_cluster_server.c src/zcl_scenes_cluster_server.cpp + src/multilevel_sensor_cluster_server.cpp ) target_include_directories( diff --git a/applications/zpc/components/zcl_cluster_servers/src/multilevel_sensor_cluster_server.cpp b/applications/zpc/components/zcl_cluster_servers/src/multilevel_sensor_cluster_server.cpp new file mode 100644 index 000000000..0645623b8 --- /dev/null +++ b/applications/zpc/components/zcl_cluster_servers/src/multilevel_sensor_cluster_server.cpp @@ -0,0 +1,181 @@ +/****************************************************************************** + * # License + * Copyright 2022 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 "multilevel_sensor_cluster_server.h" +#include "zcl_cluster_servers_helpers.hpp" + +// Interfaces +#include "zwave_command_class_version_types.h" +#include "zwave_command_class_configuration_types.h" + +// ZPC includes +#include "zpc_attribute_store.h" +#include "zpc_attribute_store_network_helper.h" +#include "zwave_command_class_generic_types.h" +#include "attribute_store_defined_attribute_types.h" + +// Includes from Unify shared components +#include "attribute.hpp" +#include "attribute_store_helper.h" +#include "sl_log.h" + +// Includes from auto-generated files +#include "dotdot_mqtt.h" +#include "zap-types.h" +#include "dotdot_mqtt_helpers.hpp" + +// Generic includes +#include +#include +#include + +using namespace attribute_store; + +// Setup Log ID +constexpr char LOG_TAG[] = "multilevel_sensor_cluster_server"; + +// Attribute macro, shortening those long defines for attribute types: +#define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_SENSOR_MULTILEVEL_##type + +// List of attributes of SensorValues +namespace +{ +const std::vector sensor_values_attributes + = {ATTRIBUTE(SENSOR_VALUE), ATTRIBUTE(SCALE)}; +} + +/////////////////////////////////////////////////////////////////////////////// +// Attribute publication functions +////////////////////////////////////////////////////////////////////////////// + +/** + * @brief Publishes the Multilevel Sensor Cluster Server attributes + * + * @param unid unid for which we want to publish the + * SensorValues attributes. + * @param endpoint_id Endpoint ID for which we want to publish the + * SensorValues attributes. + * @param sensor_type Sensor Type node ID for which we want to publish the + * SensorValues attributes. + */ +static sl_status_t publish_multilevel_sensor_cluster_attributes( + const std::string &unid, + attribute_store::attribute sensor_type_node, + zwave_endpoint_id_t endpoint_id) +{ + // Do not publish any state supported commands for ourselves. + if (is_zpc_unid(unid.c_str())) { + return SL_STATUS_FAIL; + } + + // Build the base topic and pass it on to DotDot MQTT. + try { + // Get reported sensor type ID + uint8_t sensor_type = sensor_type_node.reported(); + + // Get SensorType name + const std::string sensor_type_str + = multilevel_sensor_sensor_type_get_enum_value_name(sensor_type); + + // Added sensor type name to base topic + const std::string base_topic = "ucl/by-unid/" + std::string(unid) + "/ep" + + std::to_string(endpoint_id) + "/" + + std::string(sensor_type_str); + + SensorValue value = {0, 0}; + // Get report sensor value + attribute_store::attribute sensor_value_node + = sensor_type_node.child_by_type(ATTRIBUTE(SENSOR_VALUE)); + if (sensor_value_node.reported_exists()) { + value.Value = sensor_value_node.reported(); + } + // Get report sensor scale + attribute_store::attribute sensor_scale_node + = sensor_type_node.child_by_type(ATTRIBUTE(SCALE)); + if (sensor_scale_node.reported_exists()) { + value.Scale = static_cast(sensor_scale_node.reported()); + } + + // Pulish the sensor value attribute + if (SL_STATUS_OK + != uic_mqtt_dotdot_multilevel_sensor_sensor_values_publish( + base_topic.c_str(), + value, + UCL_MQTT_PUBLISH_TYPE_REPORTED)) { + return SL_STATUS_FAIL; + } + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while get base topic and sensor data : %s", + e.what()); + + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// Attribute store callback functions +////////////////////////////////////////////////////////////////////////////// +/** + * @brief Listens to updates to the SensorValues then publishes the attributes. + * + * @param updated_node Attribute Store node that was modified. + * @param change Type of change applied to the node. + */ +void on_sensor_values_update(attribute_store_node_t updated_node, + attribute_store_change_t change) +{ + if (change == ATTRIBUTE_CREATED || change == ATTRIBUTE_DELETED) { + return; + } + + // Go up and find the UNID/Endpoint and its network status. + unid_t unid; + zwave_endpoint_id_t endpoint_id = 0; + if (SL_STATUS_OK + != attribute_store_network_helper_get_unid_endpoint_from_node( + updated_node, + unid, + &endpoint_id)) { + return; + } + + attribute_store::attribute sensor_type_node + = attribute_store_get_first_parent_with_type(updated_node, + ATTRIBUTE(SENSOR_TYPE)); + + // Publish the multilevel sensor values: + if (SL_STATUS_OK + != publish_multilevel_sensor_cluster_attributes(std::string(unid), + sensor_type_node, + endpoint_id)) { + return; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Init and teardown functions. +////////////////////////////////////////////////////////////////////////////// +sl_status_t multilevel_sensor_cluster_server_init(void) +{ + sl_log_debug(LOG_TAG, "Multilevel sensor server initialization"); + + // Register attribute updates + + attribute_store_register_callback_by_type_to_array( + &on_sensor_values_update, + sensor_values_attributes.data(), + static_cast(sensor_values_attributes.size())); + + return SL_STATUS_OK; +} diff --git a/applications/zpc/components/zcl_cluster_servers/src/multilevel_sensor_cluster_server.h b/applications/zpc/components/zcl_cluster_servers/src/multilevel_sensor_cluster_server.h new file mode 100644 index 000000000..7abce7475 --- /dev/null +++ b/applications/zpc/components/zcl_cluster_servers/src/multilevel_sensor_cluster_server.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * # License + * Copyright 2022 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 multilevel_sensor_cluster_server ZCL Multilevel Sensor cluster + * @ingroup zcl_cluster_servers + * @brief The module handlers the Multilevel Sensor Cluster attribute and + * publish directly the attribute via MQTT. + * + * @{ + */ + +#ifndef MULTILEVEL_SENSOR_CLUSTER_SERVER_H +#define MULTILEVEL_SENSOR_CLUSTER_SERVER_H + +#include "sl_status.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the Multilevel Sensor Cluster Commands handler. + * + * @returns SL_STATUS_OK on success, any other code on failure + */ +sl_status_t multilevel_sensor_cluster_server_init(void); + +#ifdef __cplusplus +} +#endif + +#endif //MULTILEVEL_SENSOR_CLUSTER_SERVER_H +/** @} end configuration_cluster_mapper */ diff --git a/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp b/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp index 7c959d555..736b3d7f3 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp +++ b/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp @@ -19,6 +19,7 @@ #include "zcl_OTA_cluster_server.hpp" #include "user_code_cluster_server.h" #include "fan_control_cluster_server.h" +#include "multilevel_sensor_cluster_server.h" //Includes from other components #include "attribute_store.h" @@ -42,6 +43,7 @@ sl_status_t zcl_cluster_servers_init() init_status |= zcl_scenes_cluster_server_init(); init_status |= user_code_cluster_server_init(); init_status |= fan_control_cluster_server_init(); + init_status |= multilevel_sensor_cluster_server_init(); return init_status; } From c4863046f525b38f6e04111f2262f5c08066737a Mon Sep 17 00:00:00 2001 From: ptphan Date: Thu, 17 Oct 2024 13:54:43 +0700 Subject: [PATCH 04/12] UIC-3273: Updated documentation for command class Origin: ver_1.7.0-unstable-24-geddc303adc Forwarded: https://github.com/SiliconLabsSoftware/z-wave-protocol-controller/pull/143 Signed-off-by: Philippe Coval --- .../zpc/doc/command_classes/multilevel_sensor.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/applications/zpc/doc/command_classes/multilevel_sensor.rst b/applications/zpc/doc/command_classes/multilevel_sensor.rst index e78562e65..4c64a1d64 100644 --- a/applications/zpc/doc/command_classes/multilevel_sensor.rst +++ b/applications/zpc/doc/command_classes/multilevel_sensor.rst @@ -160,6 +160,9 @@ UAM files * - ``Time_to_MultilevelSensorCC.uam`` - ``Time.xml`` - Use to operate Local Time + * - N/A + - ``Unify_MultilevelSensor.xml`` + - Use for reporting sensor values. Bindings -------- @@ -197,6 +200,15 @@ Bindings * - ``SENSOR_VALUE`` - Time MeasuredValue - If ``SENSOR_TYPE`` = 0x21. Z-Wave -> Cluster (ReadOnly) + * - ``SENSOR_VALUE`` + - SensorValues + - ``SENSOR_VALUE`` mapping with ``Value`` field of SensorValues attribute. Z-Wave -> Cluster (ReadOnly) + * - ``SCALE`` + - SensorValues + - ``SCALE`` mapping with ``Scale`` field of SensorValues attribute. Z-Wave -> Cluster (ReadOnly) + * - ``SENSOR_TYPE`` + - SensorType + - ``SENSOR_TYPE`` mapping with SensorType attribute. Z-Wave -> Cluster (ReadOnly) Command actions --------------- @@ -295,3 +307,6 @@ Command actions * - Get Local Time - ``ucl/by-unid/+/+/Time/Attributes/LocalTime/Reported { "value": }`` - Only reported values + * - Report sensor values + - ``ucl/by-unid/+/+//MultilevelSensor/Attributes/SensorValues/Reported {"value": {"Scale": ,"Value": }}`` + - Only reported values \ No newline at end of file From eaf80b9c52b7da577c03983711e774ebbb21c4d6 Mon Sep 17 00:00:00 2001 From: Philippe Coval Date: Tue, 16 Sep 2025 14:51:47 +0200 Subject: [PATCH 05/12] p/UnifySDK: Add Schedule Entry Lock Signed-off-by: Philippe Coval --- ...-mapper-setup-for-schedule-entry-loc.patch | 302 + ...command-handlers-in-ZPC-ScheduleEntr.patch | 9790 ++++++++++++ ...port-callback-Schedule-Entry-Lock-CC.patch | 521 + ...ed-files-for-ScheduleEntryLock-using.patch | 12466 ++++++++++++++++ 4 files changed, 23079 insertions(+) create mode 100644 patches/UnifySDK/0011-UIC-3438-dot-dot-mapper-setup-for-schedule-entry-loc.patch create mode 100644 patches/UnifySDK/0012-UIC-3494-dotdot-command-handlers-in-ZPC-ScheduleEntr.patch create mode 100644 patches/UnifySDK/0013-UIC-3437-Report-callback-Schedule-Entry-Lock-CC.patch create mode 100644 patches/UnifySDK/0014-UIC-3437-Generated-files-for-ScheduleEntryLock-using.patch diff --git a/patches/UnifySDK/0011-UIC-3438-dot-dot-mapper-setup-for-schedule-entry-loc.patch b/patches/UnifySDK/0011-UIC-3438-dot-dot-mapper-setup-for-schedule-entry-loc.patch new file mode 100644 index 000000000..9d6221d30 --- /dev/null +++ b/patches/UnifySDK/0011-UIC-3438-dot-dot-mapper-setup-for-schedule-entry-loc.patch @@ -0,0 +1,302 @@ +From 9660b5676577440cc94dfb83f73b30dc117744d4 Mon Sep 17 00:00:00 2001 +From: Thirupathi S +Date: Tue, 17 Sep 2024 13:13:38 +0000 +Subject: [PATCH] UIC-3438: dot dot mapper setup for schedule entry lock CC + +Merge in UIC/uic from feature/UIC-3438-dotdot-mapper-Setup-Schedule-Entry-Lock-CC to feature/UIC-3271-Schedule-Entry-Lock-CC +--- + .../dotdot-xml/Unify_ScheduleEntryLock.xml | 282 ++++++++++++++++++ + 1 file changed, 282 insertions(+) + create mode 100644 components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml + +diff --git a/components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml b/components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml +new file mode 100644 +index 0000000000..8d37540615 +--- /dev/null ++++ b/components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml +@@ -0,0 +1,282 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.39.5 + diff --git a/patches/UnifySDK/0012-UIC-3494-dotdot-command-handlers-in-ZPC-ScheduleEntr.patch b/patches/UnifySDK/0012-UIC-3494-dotdot-command-handlers-in-ZPC-ScheduleEntr.patch new file mode 100644 index 000000000..4fee525fd --- /dev/null +++ b/patches/UnifySDK/0012-UIC-3494-dotdot-command-handlers-in-ZPC-ScheduleEntr.patch @@ -0,0 +1,9790 @@ +From 0bf584e7c1a862d0cace11019900f0b29c9d9bdb Mon Sep 17 00:00:00 2001 +From: Thirupathi S +Date: Wed, 25 Sep 2024 13:15:55 +0000 +Subject: [PATCH] UIC-3494:dotdot command handlers in ZPC ScheduleEntryLock CC + +Merge in UIC/uic from feature/UIC-3494-dotdot-command-handlers-in-ZPC-ScheduleEntryLock-CC to feature/UIC-3271-Schedule-Entry-Lock-CC +--- + .../cluster-types/cluster-type-attributes.ts | 245 ++ + .../src/cluster-types/cluster-types.ts | 1 + + .../src/cluster-types/supported-clusters.js | 1 + + .../dev_ui/dev_gui/zap/addon-helper.js | 3 +- + .../dotdot-xml/Unify_ScheduleEntryLock.xml | 47 +- + components/uic_dotdot/dotdot-xml/library.xml | 5 +- + .../zap-generated/include/dotdot_mqtt.h | 629 +++++ + .../include/dotdot_mqtt_attributes.h | 113 + + .../include/dotdot_mqtt_generated_commands.h | 85 + + .../include/dotdot_mqtt_group_commands.h | 65 + + .../include/dotdot_mqtt_send_commands.h | 117 + + ...dotdot_mqtt_supported_generated_commands.h | 31 + + .../zap-generated/src/dotdot_mqtt.cpp | 2017 ++++++++++++++++- + .../zap-generated/src/dotdot_mqtt.hpp | 85 + + .../src/dotdot_mqtt_attributes.cpp | 707 ++++++ + .../src/dotdot_mqtt_command_helpers.cpp | 462 ++++ + .../src/dotdot_mqtt_command_helpers.hpp | 142 ++ + .../src/dotdot_mqtt_generated_commands.cpp | 228 ++ + .../src/dotdot_mqtt_group_commands.cpp | 528 +++++ + .../zap-generated/src/dotdot_mqtt_helpers.cpp | 102 + + .../src/dotdot_mqtt_send_commands.cpp | 222 ++ + ...tdot_mqtt_supported_generated_commands.cpp | 52 + + .../test/dotdot_mqtt_test.include | 98 + + .../include/dotdot_attributes.uam | 10 + + .../include/dotdot_attributes_camel_case.uam | 10 + + .../unify_dotdot_attribute_store_helpers.h | 876 +++++++ + .../unify_dotdot_defined_attribute_types.h | 9 + + ...ot_attribute_store_attribute_publisher.cpp | 481 ++++ + ..._force_read_attributes_command_callbacks.c | 67 + + .../unify_dotdot_attribute_store_helpers.cpp | 955 ++++++++ + ...fy_dotdot_attribute_store_registration.cpp | 192 ++ + ...store_write_attributes_command_callbacks.c | 65 + + .../test/unify_dotdot_attribute_store_test.c | 320 +++ + .../test/unify_dotdot_attribute_store_test.h | 13 + + 34 files changed, 8900 insertions(+), 83 deletions(-) + +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 2fa7a4c728..c8f421a395 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 +@@ -15352,4 +15352,249 @@ export let ClusterTypeAttrs: any = { + ] + } + }, ++ UnifyScheduleEntryLock: { ++ server:{ ++ attributes: [ ++ { ++ id: 1, ++ name: "SlotsWeekDay", ++ type: "number", ++ max: 255, ++ min: 0, ++ required: true, ++ reportRequired: false, ++ sceneRequired: false, ++ writable: true, ++ isArray: false, ++ }, ++ { ++ id: 2, ++ name: "SlotsYearDay", ++ type: "number", ++ max: 255, ++ min: 0, ++ required: true, ++ reportRequired: false, ++ sceneRequired: false, ++ writable: true, ++ isArray: false, ++ }, ++ { ++ id: 3, ++ name: "SignTZO", ++ type: "number", ++ required: true, ++ reportRequired: false, ++ sceneRequired: false, ++ writable: true, ++ isArray: false, ++ }, ++ { ++ id: 4, ++ name: "HourTZO", ++ type: "number", ++ required: true, ++ reportRequired: false, ++ sceneRequired: false, ++ writable: true, ++ isArray: false, ++ }, ++ { ++ id: 5, ++ name: "MinuteTZO", ++ type: "number", ++ required: true, ++ reportRequired: false, ++ sceneRequired: false, ++ writable: true, ++ isArray: false, ++ }, ++ { ++ id: 6, ++ name: "DSTOffsetSign", ++ type: "number", ++ required: true, ++ reportRequired: false, ++ sceneRequired: false, ++ writable: true, ++ isArray: false, ++ }, ++ { ++ id: 7, ++ name: "DSTOffsetMinute", ++ type: "number", ++ required: true, ++ reportRequired: false, ++ sceneRequired: false, ++ writable: true, ++ isArray: false, ++ }, ++ { ++ id: 8, ++ name: "NumberOfSlotsDailyRepeating", ++ type: "number", ++ max: 255, ++ min: 0, ++ required: true, ++ reportRequired: false, ++ sceneRequired: false, ++ writable: true, ++ isArray: false, ++ } ++ ], ++ commands: [ ++ { ++ id: 1, ++ name: "ScheduleEntryLockWeekDayReport", ++ required: true, ++ fields: [ ++ { ++ name: "UserIdentifier", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "ScheduleSlotID", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "DayOfWeek", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StartHour", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StartMinute", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StopHour", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StopMinute", ++ type: "number", ++ isArray: false, ++ } ++ ] ++ }, ++ { ++ id: 2, ++ name: "ScheduleEntryLockYearDayReport", ++ required: true, ++ fields: [ ++ { ++ name: "SetAction", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "UserIdentifier", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "ScheduleSlotID", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StartYear", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StartDay", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StartHour", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StartMinute", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StopYear", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StopDay", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StopHour", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StopMinute", ++ type: "number", ++ isArray: false, ++ } ++ ] ++ }, ++ { ++ id: 3, ++ name: "ScheduleEntryLockDailyRepeatingReport", ++ required: true, ++ fields: [ ++ { ++ name: "SetAction", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "UserIdentifier", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "ScheduleSlotID", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "WeekDayBitmask", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StartHour", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "StartMinute", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "DurationHour", ++ type: "number", ++ isArray: false, ++ }, ++ { ++ name: "DurationMinute", ++ type: "number", ++ isArray: false, ++ } ++ ] ++ } ++ ] ++ } ++ }, + } +diff --git a/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-types.ts b/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-types.ts +index 192c0f68f9..b420ab28f5 100644 +--- a/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-types.ts ++++ b/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/cluster-types.ts +@@ -29,6 +29,7 @@ export enum ClusterTypes { + SoilMoisture = "SoilMoisture", + TemperatureMeasurement = "TemperatureMeasurement", + Thermostat = "Thermostat", ++ UnifyScheduleEntryLock = "UnifyScheduleEntryLock", + WindSpeedMeasurement = "WindSpeedMeasurement", + WindowCovering = "WindowCovering" + } +diff --git a/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/supported-clusters.js b/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/supported-clusters.js +index e19a8e938b..3fdf6d4432 100644 +--- a/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/supported-clusters.js ++++ b/applications/dev_ui/dev_gui/zap-generated/src/cluster-types/supported-clusters.js +@@ -32,6 +32,7 @@ const SupportedClusters = { + SoilMoisture: "SoilMoisture", + TemperatureMeasurement: "TemperatureMeasurement", + Thermostat: "Thermostat", ++ UnifyScheduleEntryLock: "UnifyScheduleEntryLock", + WindSpeedMeasurement: "WindSpeedMeasurement", + WindowCovering: "WindowCovering" + } +diff --git a/applications/dev_ui/dev_gui/zap/addon-helper.js b/applications/dev_ui/dev_gui/zap/addon-helper.js +index aa013c9f1a..1af98954be 100644 +--- a/applications/dev_ui/dev_gui/zap/addon-helper.js ++++ b/applications/dev_ui/dev_gui/zap/addon-helper.js +@@ -31,6 +31,7 @@ const supportedClusters = [ + "SystemMetrics", + "TemperatureMeasurement", + "Thermostat", ++ "UnifyScheduleEntryLock", + "WindSpeedMeasurement", + "WindowCovering" + ]; +@@ -272,4 +273,4 @@ exports.getClusterName = getClusterName + exports.isStruct = isStruct + exports.isArray = isArray + exports.getEnum = getEnum +-exports.getBitmap = getBitmap +\ No newline at end of file ++exports.getBitmap = getBitmap +diff --git a/components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml b/components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml +index 8d37540615..8b9f0685d6 100644 +--- a/components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml ++++ b/components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml +@@ -8,32 +8,29 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +- ++ + + + + + +- ++ + + + + +- ++ + + + +@@ -65,13 +62,13 @@ + + + +- ++ + + + + + +- ++ + + + +@@ -118,13 +115,13 @@ + + + +- ++ + + + + + +- ++ + + + +@@ -156,7 +153,7 @@ + + + +- ++ + + + +@@ -167,7 +164,7 @@ + + + +- ++ + + + +@@ -198,9 +195,8 @@ + + + +- ++ + +- + + + +@@ -245,9 +241,8 @@ + + + +- ++ + +- + + + +diff --git a/components/uic_dotdot/dotdot-xml/library.xml b/components/uic_dotdot/dotdot-xml/library.xml +index deec70c822..2fdb5c5778 100644 +--- a/components/uic_dotdot/dotdot-xml/library.xml ++++ b/components/uic_dotdot/dotdot-xml/library.xml +@@ -208,7 +208,7 @@ applicable to this document can be found in the LICENSE.md file. + + + +- ++ + + + +@@ -502,4 +502,5 @@ applicable to this document can be found in the LICENSE.md file. + + + +- +\ No newline at end of file ++ ++ +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 7606ec4c85..0a57bcf5ad 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h ++++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h +@@ -40139,6 +40139,635 @@ void uic_mqtt_dotdot_unify_thermostat_publish_supported_commands( + void uic_mqtt_dotdot_unify_thermostat_publish_empty_supported_commands( + const dotdot_unid_t unid + ,dotdot_endpoint_id_t endpoint); ++// Callback types used by the unify_schedule_entry_lock cluster ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ ++ uint8_t day_of_week, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_minute, ++ ++ uint8_t stop_hour, ++ ++ uint8_t stop_minute ++ ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uint8_t set_action, ++ ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ ++ uint8_t start_year, ++ ++ uint8_t start_day, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_minute, ++ ++ uint8_t stop_year, ++ ++ uint8_t stop_day, ++ ++ uint8_t stop_hour, ++ ++ uint8_t stop_minute ++ ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uint8_t set_action, ++ ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ ++ uint8_t week_day_bitmask, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_minute, ++ ++ uint8_t duration_hour, ++ ++ uint8_t duration_minute ++ ++); ++ ++typedef struct { ++ uint8_t slots_week_day; ++ uint8_t slots_year_day; ++ uint8_t signtzo; ++ uint8_t hourtzo; ++ uint8_t minutetzo; ++ uint8_t dst_offset_sign; ++ uint8_t dst_offset_minute; ++ uint8_t number_of_slots_daily_repeating; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_state_t; ++ ++typedef struct { ++ bool slots_week_day; ++ bool slots_year_day; ++ bool signtzo; ++ bool hourtzo; ++ bool minutetzo; ++ bool dst_offset_sign; ++ bool dst_offset_minute; ++ bool number_of_slots_daily_repeating; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t; ++ ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_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_schedule_entry_lock_state_t, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t ++); ++ ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_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_schedule_entry_lock_updated_state_t ++); ++ ++ ++/** ++ * @brief Command fields for UnifyScheduleEntryLock/ScheduleEntryLockWeekDayReport ++ */ ++typedef struct { ++ uint8_t user_identifier; ++ ++ uint8_t schedule_slotid; ++ ++ uint8_t day_of_week; ++ ++ uint8_t start_hour; ++ ++ uint8_t start_minute; ++ ++ uint8_t stop_hour; ++ ++ uint8_t stop_minute; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t; ++ ++/** ++ * @brief Command fields for UnifyScheduleEntryLock/ScheduleEntryLockYearDayReport ++ */ ++typedef struct { ++ uint8_t set_action; ++ ++ uint8_t user_identifier; ++ ++ uint8_t schedule_slotid; ++ ++ uint8_t start_year; ++ ++ uint8_t start_day; ++ ++ uint8_t start_hour; ++ ++ uint8_t start_minute; ++ ++ uint8_t stop_year; ++ ++ uint8_t stop_day; ++ ++ uint8_t stop_hour; ++ ++ uint8_t stop_minute; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t; ++ ++/** ++ * @brief Command fields for UnifyScheduleEntryLock/ScheduleEntryLockDailyRepeatingReport ++ */ ++typedef struct { ++ uint8_t set_action; ++ ++ uint8_t user_identifier; ++ ++ uint8_t schedule_slotid; ++ ++ uint8_t week_day_bitmask; ++ ++ uint8_t start_hour; ++ ++ uint8_t start_minute; ++ ++ uint8_t duration_hour; ++ ++ uint8_t duration_minute; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t; ++ ++ ++/** ++ * @brief Setup callback to be called when a ++ * UnifyScheduleEntryLock/Commands/schedule_entry_lock_week_day_report 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_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * UnifyScheduleEntryLock/Commands/schedule_entry_lock_week_day_report is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * UnifyScheduleEntryLock/Commands/schedule_entry_lock_week_day_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_clear(); ++ ++/** ++ * @brief Setup callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_week_day_report 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_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_week_day_report is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_week_day_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_clear(); ++/** ++ * @brief Setup callback to be called when a ++ * UnifyScheduleEntryLock/Commands/schedule_entry_lock_year_day_report 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_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * UnifyScheduleEntryLock/Commands/schedule_entry_lock_year_day_report is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * UnifyScheduleEntryLock/Commands/schedule_entry_lock_year_day_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_clear(); ++ ++/** ++ * @brief Setup callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_year_day_report 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_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_year_day_report is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_year_day_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_clear(); ++/** ++ * @brief Setup callback to be called when a ++ * UnifyScheduleEntryLock/Commands/schedule_entry_lock_daily_repeating_report 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_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * UnifyScheduleEntryLock/Commands/schedule_entry_lock_daily_repeating_report is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * UnifyScheduleEntryLock/Commands/schedule_entry_lock_daily_repeating_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_clear(); ++ ++/** ++ * @brief Setup callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_daily_repeating_report 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_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_daily_repeating_report is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_daily_repeating_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_clear(); ++ ++/** ++ * @brief Setup a callback for WriteAttribute to be called when a ++ * +/unify_schedule_entry_lock/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_schedule_entry_lock_write_attributes_callback( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t callback ++); ++/** ++ * @brief Unsets a callback for WriteAttribute to be called when a ++ * +/unify_schedule_entry_lock/Commands/WriteAttributes is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unset_unify_schedule_entry_lock_write_attributes_callback( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t callback ++); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/unify_schedule_entry_lock/Commands/WriteAttributes is received. ++ */ ++void uic_mqtt_dotdot_clear_unify_schedule_entry_lock_write_attributes_callbacks(); ++ ++/** ++ * @brief Setup a callback for ForceReadAttributes to be called when a ++ * +/unify_schedule_entry_lock/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_schedule_entry_lock_force_read_attributes_callback( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback_t callback ++); ++/** ++ * @brief Unsets a callback for ForceReadAttributes to be called when a ++ * +/unify_schedule_entry_lock/Commands/ForceReadAttributes is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unset_unify_schedule_entry_lock_force_read_attributes_callback( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback_t callback ++); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/unify_schedule_entry_lock/Commands/ForceReadAttributes is received. ++ */ ++void uic_mqtt_dotdot_clear_unify_schedule_entry_lock_force_read_attributes_callbacks(); ++ ++/** ++ * @brief Publish the attribute; UnifyScheduleEntryLock/Attributes/SlotsWeekDay ++ * ++ * @param base_topic topic prefix to publish, /slots_week_day ++ * 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_schedule_entry_lock_slots_week_day_publish( ++ const char *base_topic, ++ uint8_t value, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Unretains a published attribute; UnifyScheduleEntryLock/Attributes/SlotsWeekDay ++ * ++ * @param base_topic topic prefix to publish, /slots_week_day ++ * 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_schedule_entry_lock_slots_week_day_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Publish the attribute; UnifyScheduleEntryLock/Attributes/SlotsYearDay ++ * ++ * @param base_topic topic prefix to publish, /slots_year_day ++ * 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_schedule_entry_lock_slots_year_day_publish( ++ const char *base_topic, ++ uint8_t value, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Unretains a published attribute; UnifyScheduleEntryLock/Attributes/SlotsYearDay ++ * ++ * @param base_topic topic prefix to publish, /slots_year_day ++ * 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_schedule_entry_lock_slots_year_day_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Publish the attribute; UnifyScheduleEntryLock/Attributes/SignTZO ++ * ++ * @param base_topic topic prefix to publish, /signtzo ++ * 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_schedule_entry_lock_signtzo_publish( ++ const char *base_topic, ++ uint8_t value, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Unretains a published attribute; UnifyScheduleEntryLock/Attributes/SignTZO ++ * ++ * @param base_topic topic prefix to publish, /signtzo ++ * 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_schedule_entry_lock_signtzo_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Publish the attribute; UnifyScheduleEntryLock/Attributes/HourTZO ++ * ++ * @param base_topic topic prefix to publish, /hourtzo ++ * 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_schedule_entry_lock_hourtzo_publish( ++ const char *base_topic, ++ uint8_t value, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Unretains a published attribute; UnifyScheduleEntryLock/Attributes/HourTZO ++ * ++ * @param base_topic topic prefix to publish, /hourtzo ++ * 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_schedule_entry_lock_hourtzo_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Publish the attribute; UnifyScheduleEntryLock/Attributes/MinuteTZO ++ * ++ * @param base_topic topic prefix to publish, /minutetzo ++ * 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_schedule_entry_lock_minutetzo_publish( ++ const char *base_topic, ++ uint8_t value, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Unretains a published attribute; UnifyScheduleEntryLock/Attributes/MinuteTZO ++ * ++ * @param base_topic topic prefix to publish, /minutetzo ++ * 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_schedule_entry_lock_minutetzo_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Publish the attribute; UnifyScheduleEntryLock/Attributes/DSTOffsetSign ++ * ++ * @param base_topic topic prefix to publish, /dst_offset_sign ++ * 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_schedule_entry_lock_dst_offset_sign_publish( ++ const char *base_topic, ++ uint8_t value, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Unretains a published attribute; UnifyScheduleEntryLock/Attributes/DSTOffsetSign ++ * ++ * @param base_topic topic prefix to publish, /dst_offset_sign ++ * 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_schedule_entry_lock_dst_offset_sign_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Publish the attribute; UnifyScheduleEntryLock/Attributes/DSTOffsetMinute ++ * ++ * @param base_topic topic prefix to publish, /dst_offset_minute ++ * 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_schedule_entry_lock_dst_offset_minute_publish( ++ const char *base_topic, ++ uint8_t value, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Unretains a published attribute; UnifyScheduleEntryLock/Attributes/DSTOffsetMinute ++ * ++ * @param base_topic topic prefix to publish, /dst_offset_minute ++ * 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_schedule_entry_lock_dst_offset_minute_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Publish the attribute; UnifyScheduleEntryLock/Attributes/NumberOfSlotsDailyRepeating ++ * ++ * @param base_topic topic prefix to publish, /number_of_slots_daily_repeating ++ * 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_schedule_entry_lock_number_of_slots_daily_repeating_publish( ++ const char *base_topic, ++ uint8_t value, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++/** ++ * @brief Unretains a published attribute; UnifyScheduleEntryLock/Attributes/NumberOfSlotsDailyRepeating ++ * ++ * @param base_topic topic prefix to publish, /number_of_slots_daily_repeating ++ * 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_schedule_entry_lock_number_of_slots_daily_repeating_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type ++); ++ ++ ++/** ++ * @brief Publish the UnifyScheduleEntryLock/ClusterRevision attribute ++ * ++ * @param base_topic topic prefix to publish, /UnifyScheduleEntryLock/Attributes/ClusterRevision ++ * will be appended. ++ * @param value Value to publish. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_cluster_revision(const char* base_topic, uint16_t value); ++ ++/** ++ * @brief Unretain a publication to UnifyScheduleEntryLock/ClusterRevision attribute ++ * ++ * @param base_topic topic prefix to publish, /UnifyScheduleEntryLock/Attributes/ClusterRevision ++ * will be appended. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_unretain_cluster_revision(const char* base_topic); ++ ++/** ++ * @brief Publish the SupportedCommands for UNID/EndPoint for the UnifyScheduleEntryLock Cluster ++ * ++ * This function will iterate over all Commands in the UnifyScheduleEntryLock 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_schedule_entry_lock_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 UnifyScheduleEntryLock Cluster ++ * ++ * @param unid ++ * @param endpoint ) ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_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, +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 003f75549d..e8d7b7b258 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 +@@ -5054,6 +5054,63 @@ typedef sl_status_t (*uic_mqtt_dotdot_unify_thermostat_attribute_operating_state + uic_mqtt_dotdot_attribute_update_type_t update_type, + uint8_t operating_state + ); ++// Callback types used by the unify_schedule_entry_lock cluster ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_week_day_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ bool unretained, ++ uic_mqtt_dotdot_attribute_update_type_t update_type, ++ uint8_t slots_week_day ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_year_day_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ bool unretained, ++ uic_mqtt_dotdot_attribute_update_type_t update_type, ++ uint8_t slots_year_day ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_signtzo_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ bool unretained, ++ uic_mqtt_dotdot_attribute_update_type_t update_type, ++ uint8_t signtzo ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_hourtzo_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ bool unretained, ++ uic_mqtt_dotdot_attribute_update_type_t update_type, ++ uint8_t hourtzo ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_minutetzo_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ bool unretained, ++ uic_mqtt_dotdot_attribute_update_type_t update_type, ++ uint8_t minutetzo ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_sign_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ bool unretained, ++ uic_mqtt_dotdot_attribute_update_type_t update_type, ++ uint8_t dst_offset_sign ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_minute_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ bool unretained, ++ uic_mqtt_dotdot_attribute_update_type_t update_type, ++ uint8_t dst_offset_minute ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_number_of_slots_daily_repeating_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ bool unretained, ++ uic_mqtt_dotdot_attribute_update_type_t update_type, ++ uint8_t number_of_slots_daily_repeating ++); + // 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, +@@ -9854,6 +9911,62 @@ void uic_mqtt_dotdot_unify_thermostat_attribute_supported_thermostat_mode_callba + void uic_mqtt_dotdot_unify_thermostat_attribute_operating_state_callback_set(const uic_mqtt_dotdot_unify_thermostat_attribute_operating_state_callback_t callback); + + ++/** ++ * Initializes the attributes features for the UnifyScheduleEntryLock cluster, ++ * allowing to receive attribute updates from other UNIDs. ++ */ ++sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_attributes_init(); ++ ++/** ++ * Setup callback to be called when a ++ * UnifyScheduleEntryLock/Attributes/slots_week_day/# is received. Setting ++ * this callback will overwrite the previous set callback ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_week_day_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_week_day_callback_t callback); ++/** ++ * Setup callback to be called when a ++ * UnifyScheduleEntryLock/Attributes/slots_year_day/# is received. Setting ++ * this callback will overwrite the previous set callback ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_year_day_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_year_day_callback_t callback); ++/** ++ * Setup callback to be called when a ++ * UnifyScheduleEntryLock/Attributes/signtzo/# is received. Setting ++ * this callback will overwrite the previous set callback ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_signtzo_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_signtzo_callback_t callback); ++/** ++ * Setup callback to be called when a ++ * UnifyScheduleEntryLock/Attributes/hourtzo/# is received. Setting ++ * this callback will overwrite the previous set callback ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_hourtzo_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_hourtzo_callback_t callback); ++/** ++ * Setup callback to be called when a ++ * UnifyScheduleEntryLock/Attributes/minutetzo/# is received. Setting ++ * this callback will overwrite the previous set callback ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_minutetzo_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_minutetzo_callback_t callback); ++/** ++ * Setup callback to be called when a ++ * UnifyScheduleEntryLock/Attributes/dst_offset_sign/# is received. Setting ++ * this callback will overwrite the previous set callback ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_sign_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_sign_callback_t callback); ++/** ++ * Setup callback to be called when a ++ * UnifyScheduleEntryLock/Attributes/dst_offset_minute/# is received. Setting ++ * this callback will overwrite the previous set callback ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_minute_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_minute_callback_t callback); ++/** ++ * Setup callback to be called when a ++ * UnifyScheduleEntryLock/Attributes/number_of_slots_daily_repeating/# is received. Setting ++ * this callback will overwrite the previous set callback ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_number_of_slots_daily_repeating_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_number_of_slots_daily_repeating_callback_t callback); ++ ++ + /** + * Initializes the attributes features for the UnifyHumidityControl cluster, + * allowing to receive attribute updates from other UNIDs. +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 aa8ac95998..04e8e6b1a2 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 +@@ -4997,6 +4997,91 @@ void uic_mqtt_dotdot_unify_thermostat_publish_generated_write_attributes_command + uic_mqtt_dotdot_unify_thermostat_updated_state_t attribute_list + ); + ++/** ++ * @brief Publishes an incoming/generated ScheduleEntryLockWeekDayReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport ++ * ++ * @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_schedule_entry_lock_publish_generated_schedule_entry_lock_week_day_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ ++); ++/** ++ * @brief Publishes an incoming/generated ScheduleEntryLockYearDayReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport ++ * ++ * @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_schedule_entry_lock_publish_generated_schedule_entry_lock_year_day_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ ++); ++/** ++ * @brief Publishes an incoming/generated ScheduleEntryLockDailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_generated_schedule_entry_lock_daily_repeating_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ ++); ++ ++/** ++ * @brief Publishes an incoming/generated WriteAttributes command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/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_schedule_entry_lock_publish_generated_write_attributes_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_state_t attribute_values, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t attribute_list ++); ++ + /** + * @brief Publishes an incoming/generated ModeSet command for + * the UnifyHumidityControl cluster. +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 caeee80ffa..7220d03d38 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,71 @@ void uic_mqtt_dotdot_by_group_unify_thermostat_write_attributes_callback_set( + + + ++/** ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport command. ++ */ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t)( ++ const dotdot_group_id_t group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++); ++ ++/** ++ * Setup handler to be called when a ++ * ucl/by-group/+/UnifyScheduleEntryLock/schedule_entry_lock_week_day_report is received. ++ * Setting this callback will overwrite the previous set callback. ++ * ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback); ++ ++/** ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport command. ++ */ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t)( ++ const dotdot_group_id_t group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++); ++ ++/** ++ * Setup handler to be called when a ++ * ucl/by-group/+/UnifyScheduleEntryLock/schedule_entry_lock_year_day_report is received. ++ * Setting this callback will overwrite the previous set callback. ++ * ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback); ++ ++/** ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport command. ++ */ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t)( ++ const dotdot_group_id_t group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++); ++ ++/** ++ * Setup handler to be called when a ++ * ucl/by-group/+/UnifyScheduleEntryLock/schedule_entry_lock_daily_repeating_report is received. ++ * Setting this callback will overwrite the previous set callback. ++ * ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback); ++ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback_t)( ++ const dotdot_group_id_t group_id, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_state_t, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t ++); ++ ++/** ++ * Setup a callback for WriteAttribute to be called when a ++ * ucl/by-group/+/unify_schedule_entry_lock/Commands/WriteAttributes is received. ++ * Setting this callback will overwrite any previously set callback. ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback_set( ++ const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback_t callback ++); ++ ++ ++ + /** + * @brief Callback signature for by-group UnifyHumidityControl::ModeSet command. + */ +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 b49b9a5c1a..098475c6d2 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 +@@ -7108,6 +7108,123 @@ void uic_mqtt_dotdot_unify_fan_control_publish_turn_off_command( + void uic_mqtt_dotdot_unify_fan_control_publish_turn_off_command_to_group( + uint16_t destination_group_id + ); ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockWeekDayReport command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_week_day_report_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ ++); ++ ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockWeekDayReport command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_week_day_report_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ ++); ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockYearDayReport command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_year_day_report_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ ++); ++ ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockYearDayReport command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_year_day_report_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ ++); ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockDailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_daily_repeating_report_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ ++); ++ ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockDailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_daily_repeating_report_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ ++); + /** + * @brief Sends/Publishes a ModeSet command for + * the UnifyHumidityControl cluster to a destination. +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 31b5b4443d..3778a1ec8c 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 +@@ -1692,6 +1692,37 @@ void uic_mqtt_dotdot_unify_thermostat_publish_supported_generated_commands( + ); + + ++/** ++ * @brief Struct containing the list of commands for UnifyScheduleEntryLock ++ */ ++typedef struct _uic_mqtt_dotdot_unify_schedule_entry_lock_supported_commands_ { ++ bool schedule_entry_lock_week_day_report; ++ bool schedule_entry_lock_year_day_report; ++ bool schedule_entry_lock_daily_repeating_report; ++ bool write_attributes; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_supported_commands_t; ++ ++/** ++ * @brief Sends/Publishes a the SupportedGenerated commands for ++ * the UnifyScheduleEntryLock cluster for a UNID/Endpoint ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/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_schedule_entry_lock_publish_supported_generated_commands( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_supported_commands_t *command_list ++); ++ ++ + /** + * @brief Struct containing the list of commands for UnifyHumidityControl + */ +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 fb910272aa..02a9105975 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp +@@ -93961,6 +93961,1486 @@ sl_status_t uic_mqtt_dotdot_unify_thermostat_init() + return SL_STATUS_OK; + } + ++// Callbacks pointers ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback; ++ ++// Callbacks setters ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback; ++} ++ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback.clear(); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback; ++} ++ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback.clear(); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback; ++} ++ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback.clear(); ++} ++ ++void uic_mqtt_dotdot_set_unify_schedule_entry_lock_write_attributes_callback( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unset_unify_schedule_entry_lock_write_attributes_callback( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback.erase(callback); ++} ++void uic_mqtt_dotdot_clear_unify_schedule_entry_lock_write_attributes_callbacks() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback; ++} ++ ++void uic_mqtt_dotdot_set_unify_schedule_entry_lock_force_read_attributes_callback( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unset_unify_schedule_entry_lock_force_read_attributes_callback( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback.erase(callback); ++} ++void uic_mqtt_dotdot_clear_unify_schedule_entry_lock_force_read_attributes_callbacks() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback.clear(); ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_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; ++ } ++ ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t day_of_week = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t stop_hour = {}; ++ uint8_t stop_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ jsn, ++ user_identifier, ++ ++ schedule_slotid, ++ ++ day_of_week, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_hour, ++ ++ stop_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", ""); ++ return; ++ } ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ user_identifier, ++ ++ schedule_slotid, ++ ++ day_of_week, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_hour, ++ ++ stop_minute ++ ++ ); ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_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; ++ } ++ ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t day_of_week = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t stop_hour = {}; ++ uint8_t stop_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ jsn, ++ user_identifier, ++ ++ schedule_slotid, ++ ++ day_of_week, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_hour, ++ ++ stop_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", ""); ++ return; ++ } ++ ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ user_identifier, ++ ++ schedule_slotid, ++ ++ day_of_week, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_hour, ++ ++ stop_minute ++ ++ ); ++ } ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_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; ++ } ++ ++ uint8_t set_action = {}; ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t start_year = {}; ++ uint8_t start_day = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t stop_year = {}; ++ uint8_t stop_day = {}; ++ uint8_t stop_hour = {}; ++ uint8_t stop_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ jsn, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ start_year, ++ ++ start_day, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_year, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", ""); ++ return; ++ } ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ start_year, ++ ++ start_day, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_year, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute ++ ++ ); ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_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; ++ } ++ ++ uint8_t set_action = {}; ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t start_year = {}; ++ uint8_t start_day = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t stop_year = {}; ++ uint8_t stop_day = {}; ++ uint8_t stop_hour = {}; ++ uint8_t stop_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ jsn, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ start_year, ++ ++ start_day, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_year, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", ""); ++ return; ++ } ++ ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ start_year, ++ ++ start_day, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_year, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute ++ ++ ); ++ } ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_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; ++ } ++ ++ uint8_t set_action = {}; ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t week_day_bitmask = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t duration_hour = {}; ++ uint8_t duration_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ jsn, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", ""); ++ return; ++ } ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ++ ); ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_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; ++ } ++ ++ uint8_t set_action = {}; ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t week_day_bitmask = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t duration_hour = {}; ++ uint8_t duration_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ jsn, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", ""); ++ return; ++ } ++ ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ++ ); ++ } ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WriteAttributes ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_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_schedule_entry_lock_state_t new_state = {}; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t new_updated_state = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_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, "UnifyScheduleEntryLock", "WriteAttributes"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", ""); ++ return; ++ } ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_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_schedule_entry_lock_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_schedule_entry_lock_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_schedule_entry_lock_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.slots_week_day = true; ++ force_update.slots_year_day = true; ++ force_update.signtzo = true; ++ force_update.hourtzo = true; ++ force_update.minutetzo = true; ++ force_update.dst_offset_sign = true; ++ force_update.dst_offset_minute = true; ++ force_update.number_of_slots_daily_repeating = true; ++ trigger_handler = true; ++ } else { ++ std::unordered_map supported_attrs = { ++ {"SlotsWeekDay", &force_update.slots_week_day }, ++ {"SlotsYearDay", &force_update.slots_year_day }, ++ {"SignTZO", &force_update.signtzo }, ++ {"HourTZO", &force_update.hourtzo }, ++ {"MinuteTZO", &force_update.minutetzo }, ++ {"DSTOffsetSign", &force_update.dst_offset_sign }, ++ {"DSTOffsetMinute", &force_update.dst_offset_minute }, ++ {"NumberOfSlotsDailyRepeating", &force_update.number_of_slots_daily_repeating }, ++ }; ++ ++ 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_schedule_entry_lock_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, "UnifyScheduleEntryLock/Commands/ForceReadAttributes: Unable to parse JSON payload"); ++ return; ++ } ++} ++ ++sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_slots_week_day_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(64801,1,value)) { ++ jsn["value"] = uic_dotdot_get_attribute_value_name(64801,1,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, "UnifyScheduleEntryLock/Attributes/SlotsWeekDay", e.what()); ++ return SL_STATUS_OK; ++ } ++ ++ ++ std::string topic = std::string(base_topic) + "/UnifyScheduleEntryLock/Attributes/SlotsWeekDay"; ++ 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_schedule_entry_lock_slots_week_day_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type) ++{ ++ // clang-format on ++ std::string topic ++ = std::string(base_topic) ++ + "/UnifyScheduleEntryLock/Attributes/SlotsWeekDay"; ++ ++ 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_schedule_entry_lock_slots_year_day_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(64801,2,value)) { ++ jsn["value"] = uic_dotdot_get_attribute_value_name(64801,2,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, "UnifyScheduleEntryLock/Attributes/SlotsYearDay", e.what()); ++ return SL_STATUS_OK; ++ } ++ ++ ++ std::string topic = std::string(base_topic) + "/UnifyScheduleEntryLock/Attributes/SlotsYearDay"; ++ 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_schedule_entry_lock_slots_year_day_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type) ++{ ++ // clang-format on ++ std::string topic ++ = std::string(base_topic) ++ + "/UnifyScheduleEntryLock/Attributes/SlotsYearDay"; ++ ++ 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_schedule_entry_lock_signtzo_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(64801,3,value)) { ++ jsn["value"] = uic_dotdot_get_attribute_value_name(64801,3,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, "UnifyScheduleEntryLock/Attributes/SignTZO", e.what()); ++ return SL_STATUS_OK; ++ } ++ ++ ++ std::string topic = std::string(base_topic) + "/UnifyScheduleEntryLock/Attributes/SignTZO"; ++ 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_schedule_entry_lock_signtzo_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type) ++{ ++ // clang-format on ++ std::string topic ++ = std::string(base_topic) ++ + "/UnifyScheduleEntryLock/Attributes/SignTZO"; ++ ++ 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_schedule_entry_lock_hourtzo_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(64801,4,value)) { ++ jsn["value"] = uic_dotdot_get_attribute_value_name(64801,4,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, "UnifyScheduleEntryLock/Attributes/HourTZO", e.what()); ++ return SL_STATUS_OK; ++ } ++ ++ ++ std::string topic = std::string(base_topic) + "/UnifyScheduleEntryLock/Attributes/HourTZO"; ++ 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_schedule_entry_lock_hourtzo_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type) ++{ ++ // clang-format on ++ std::string topic ++ = std::string(base_topic) ++ + "/UnifyScheduleEntryLock/Attributes/HourTZO"; ++ ++ 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_schedule_entry_lock_minutetzo_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(64801,5,value)) { ++ jsn["value"] = uic_dotdot_get_attribute_value_name(64801,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, "UnifyScheduleEntryLock/Attributes/MinuteTZO", e.what()); ++ return SL_STATUS_OK; ++ } ++ ++ ++ std::string topic = std::string(base_topic) + "/UnifyScheduleEntryLock/Attributes/MinuteTZO"; ++ 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_schedule_entry_lock_minutetzo_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type) ++{ ++ // clang-format on ++ std::string topic ++ = std::string(base_topic) ++ + "/UnifyScheduleEntryLock/Attributes/MinuteTZO"; ++ ++ 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_schedule_entry_lock_dst_offset_sign_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(64801,6,value)) { ++ jsn["value"] = uic_dotdot_get_attribute_value_name(64801,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, "UnifyScheduleEntryLock/Attributes/DSTOffsetSign", e.what()); ++ return SL_STATUS_OK; ++ } ++ ++ ++ std::string topic = std::string(base_topic) + "/UnifyScheduleEntryLock/Attributes/DSTOffsetSign"; ++ 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_schedule_entry_lock_dst_offset_sign_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type) ++{ ++ // clang-format on ++ std::string topic ++ = std::string(base_topic) ++ + "/UnifyScheduleEntryLock/Attributes/DSTOffsetSign"; ++ ++ 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_schedule_entry_lock_dst_offset_minute_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(64801,7,value)) { ++ jsn["value"] = uic_dotdot_get_attribute_value_name(64801,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, "UnifyScheduleEntryLock/Attributes/DSTOffsetMinute", e.what()); ++ return SL_STATUS_OK; ++ } ++ ++ ++ std::string topic = std::string(base_topic) + "/UnifyScheduleEntryLock/Attributes/DSTOffsetMinute"; ++ 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_schedule_entry_lock_dst_offset_minute_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type) ++{ ++ // clang-format on ++ std::string topic ++ = std::string(base_topic) ++ + "/UnifyScheduleEntryLock/Attributes/DSTOffsetMinute"; ++ ++ 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_schedule_entry_lock_number_of_slots_daily_repeating_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(64801,8,value)) { ++ jsn["value"] = uic_dotdot_get_attribute_value_name(64801,8,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, "UnifyScheduleEntryLock/Attributes/NumberOfSlotsDailyRepeating", e.what()); ++ return SL_STATUS_OK; ++ } ++ ++ ++ std::string topic = std::string(base_topic) + "/UnifyScheduleEntryLock/Attributes/NumberOfSlotsDailyRepeating"; ++ 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_schedule_entry_lock_number_of_slots_daily_repeating_unretain( ++ const char *base_topic, ++ uic_mqtt_dotdot_attribute_publish_type_t publish_type) ++{ ++ // clang-format on ++ std::string topic ++ = std::string(base_topic) ++ + "/UnifyScheduleEntryLock/Attributes/NumberOfSlotsDailyRepeating"; ++ ++ 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_schedule_entry_lock_init() ++{ ++ std::string base_topic = "ucl/by-unid/+/+/"; ++ ++ std::string subscription_topic; ++ if(!uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/WriteAttributes"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes); ++ } ++ ++ if(!uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/ForceReadAttributes"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_force_read_attributes); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_week_day_report); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_week_day_report); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_report); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_year_day_report); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report); ++ } ++ ++ // Init the attributes for that cluster ++ uic_mqtt_dotdot_unify_schedule_entry_lock_attributes_init(); ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_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; +@@ -96101,6 +97581,10 @@ sl_status_t uic_mqtt_dotdot_init() { + status_flag = uic_mqtt_dotdot_unify_thermostat_init(); + } + ++ if (status_flag == SL_STATUS_OK) { ++ status_flag = uic_mqtt_dotdot_unify_schedule_entry_lock_init(); ++ } ++ + if (status_flag == SL_STATUS_OK) { + status_flag = uic_mqtt_dotdot_unify_humidity_control_init(); + } +@@ -96167,6 +97651,7 @@ void uic_mqtt_dotdot_publish_supported_commands( + uic_mqtt_dotdot_descriptor_publish_supported_commands(unid, endpoint_id); + uic_mqtt_dotdot_unify_fan_control_publish_supported_commands(unid, endpoint_id); + uic_mqtt_dotdot_unify_thermostat_publish_supported_commands(unid, endpoint_id); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_publish_supported_commands(unid, endpoint_id); + uic_mqtt_dotdot_unify_humidity_control_publish_supported_commands(unid, endpoint_id); + } + +@@ -96227,6 +97712,7 @@ void uic_mqtt_dotdot_publish_empty_supported_commands( + uic_mqtt_dotdot_descriptor_publish_empty_supported_commands(unid, endpoint_id); + uic_mqtt_dotdot_unify_fan_control_publish_empty_supported_commands(unid, endpoint_id); + uic_mqtt_dotdot_unify_thermostat_publish_empty_supported_commands(unid, endpoint_id); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_publish_empty_supported_commands(unid, endpoint_id); + uic_mqtt_dotdot_unify_humidity_control_publish_empty_supported_commands(unid, endpoint_id); + } + +@@ -109531,8 +111017,170 @@ static inline bool uic_mqtt_dotdot_unify_fan_control_write_attributes_is_support + unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, +- unify_fan_control_new_state, +- unify_fan_control_new_updated_state ++ unify_fan_control_new_state, ++ unify_fan_control_new_updated_state ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ return false; ++} ++ ++static inline bool uic_mqtt_dotdot_unify_fan_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_fan_control_force_read_attributes_callback) { ++ uic_mqtt_dotdot_unify_fan_control_updated_state_t unify_fan_control_force_update = {0}; ++ if (callback( ++ unid, ++ endpoint_id, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, ++ unify_fan_control_force_update ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ return false; ++} ++ ++// Publishing Supported Commands for UnifyFanControl Cluster ++void uic_mqtt_dotdot_unify_fan_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_fan_control_set_fan_mode_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("SetFanMode")"; ++ } ++ if (uic_mqtt_dotdot_unify_fan_control_turn_off_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("TurnOff")"; ++ } ++ ++ // Check for a WriteAttributes Callback ++ if(uic_mqtt_dotdot_unify_fan_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_fan_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 += "/UnifyFanControl/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 += "/UnifyFanControl/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 UnifyFanControl Cluster ++void uic_mqtt_dotdot_unify_fan_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 += "/UnifyFanControl/SupportedCommands"; ++ ++ if (uic_mqtt_count_topics(topic.c_str()) > 0) { ++ uic_mqtt_publish(topic.c_str(), ++ EMPTY_VALUE_ARRAY, ++ strlen(EMPTY_VALUE_ARRAY), ++ true); ++ } ++} ++ ++// Publishing Cluster Revision for UnifyThermostat Cluster ++void uic_mqtt_dotdot_unify_thermostat_publish_cluster_revision(const char* base_topic, uint16_t value) ++{ ++ std::string cluster_topic = std::string(base_topic) + "/UnifyThermostat/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 UnifyThermostat Cluster ++void uic_mqtt_dotdot_unify_thermostat_unretain_cluster_revision(const char* base_topic) ++{ ++ // clang-format on ++ std::string cluster_topic ++ = std::string(base_topic) ++ + "/UnifyThermostat/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_thermostat_write_attributes_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ for (const auto& callback: uic_mqtt_dotdot_unify_thermostat_write_attributes_callback) { ++ uic_mqtt_dotdot_unify_thermostat_state_t unify_thermostat_new_state = {}; ++ uic_mqtt_dotdot_unify_thermostat_updated_state_t unify_thermostat_new_updated_state = {}; ++ ++ if (callback( ++ unid, ++ endpoint_id, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, ++ unify_thermostat_new_state, ++ unify_thermostat_new_updated_state + ) == SL_STATUS_OK) { + return true; + } +@@ -109540,17 +111188,17 @@ static inline bool uic_mqtt_dotdot_unify_fan_control_write_attributes_is_support + return false; + } + +-static inline bool uic_mqtt_dotdot_unify_fan_control_force_read_attributes_is_supported( ++static inline bool uic_mqtt_dotdot_unify_thermostat_force_read_attributes_is_supported( + const dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint_id) + { +- for (const auto& callback: uic_mqtt_dotdot_unify_fan_control_force_read_attributes_callback) { +- uic_mqtt_dotdot_unify_fan_control_updated_state_t unify_fan_control_force_update = {0}; ++ for (const auto& callback: uic_mqtt_dotdot_unify_thermostat_force_read_attributes_callback) { ++ uic_mqtt_dotdot_unify_thermostat_updated_state_t unify_thermostat_force_update = {0}; + if (callback( + unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, +- unify_fan_control_force_update ++ unify_thermostat_force_update + ) == SL_STATUS_OK) { + return true; + } +@@ -109558,8 +111206,8 @@ static inline bool uic_mqtt_dotdot_unify_fan_control_force_read_attributes_is_su + return false; + } + +-// Publishing Supported Commands for UnifyFanControl Cluster +-void uic_mqtt_dotdot_unify_fan_control_publish_supported_commands( ++// Publishing Supported Commands for UnifyThermostat Cluster ++void uic_mqtt_dotdot_unify_thermostat_publish_supported_commands( + const dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint_id) + { +@@ -109568,23 +111216,9 @@ void uic_mqtt_dotdot_unify_fan_control_publish_supported_commands( + ss.str(""); + + // check if there is callback for each command +- if (uic_mqtt_dotdot_unify_fan_control_set_fan_mode_is_supported(unid, endpoint_id)) { +- if (first_command == false) { +- ss << ", "; +- } +- first_command = false; +- ss << R"("SetFanMode")"; +- } +- if (uic_mqtt_dotdot_unify_fan_control_turn_off_is_supported(unid, endpoint_id)) { +- if (first_command == false) { +- ss << ", "; +- } +- first_command = false; +- ss << R"("TurnOff")"; +- } + + // Check for a WriteAttributes Callback +- if(uic_mqtt_dotdot_unify_fan_control_write_attributes_is_supported(unid, endpoint_id)) { ++ if(uic_mqtt_dotdot_unify_thermostat_write_attributes_is_supported(unid, endpoint_id)) { + if (first_command == false) { + ss << ", "; + } +@@ -109593,7 +111227,7 @@ void uic_mqtt_dotdot_unify_fan_control_publish_supported_commands( + } + + // Check for a ForceReadAttributes Callback +- if (uic_mqtt_dotdot_unify_fan_control_force_read_attributes_is_supported(unid, endpoint_id)) { ++ if (uic_mqtt_dotdot_unify_thermostat_force_read_attributes_is_supported(unid, endpoint_id)) { + if (first_command == false) { + ss << ", "; + } +@@ -109604,7 +111238,7 @@ void uic_mqtt_dotdot_unify_fan_control_publish_supported_commands( + // Publish supported commands + std::string topic = "ucl/by-unid/" + std::string(unid); + topic += "/ep"+ std::to_string(endpoint_id); +- topic += "/UnifyFanControl/SupportedCommands"; ++ topic += "/UnifyThermostat/SupportedCommands"; + std::string payload_str("{\"value\": [" + ss.str() + "]" + "}"); + if (first_command == false) { + uic_mqtt_publish(topic.c_str(), +@@ -109616,7 +111250,7 @@ void uic_mqtt_dotdot_unify_fan_control_publish_supported_commands( + // 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 += "/UnifyFanControl/Attributes"; ++ attributes_topic += "/UnifyThermostat/Attributes"; + + if (uic_mqtt_count_topics(attributes_topic.c_str()) > 0) { + uic_mqtt_publish(topic.c_str(), +@@ -109627,14 +111261,14 @@ void uic_mqtt_dotdot_unify_fan_control_publish_supported_commands( + } + } + +-// Publishing empty/no Supported Commands for UnifyFanControl Cluster +-void uic_mqtt_dotdot_unify_fan_control_publish_empty_supported_commands( ++// Publishing empty/no Supported Commands for UnifyThermostat Cluster ++void uic_mqtt_dotdot_unify_thermostat_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 += "/UnifyFanControl/SupportedCommands"; ++ topic += "/UnifyThermostat/SupportedCommands"; + + if (uic_mqtt_count_topics(topic.c_str()) > 0) { + uic_mqtt_publish(topic.c_str(), +@@ -109644,10 +111278,10 @@ void uic_mqtt_dotdot_unify_fan_control_publish_empty_supported_commands( + } + } + +-// Publishing Cluster Revision for UnifyThermostat Cluster +-void uic_mqtt_dotdot_unify_thermostat_publish_cluster_revision(const char* base_topic, uint16_t value) ++// Publishing Cluster Revision for UnifyScheduleEntryLock Cluster ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_cluster_revision(const char* base_topic, uint16_t value) + { +- std::string cluster_topic = std::string(base_topic) + "/UnifyThermostat/Attributes/ClusterRevision"; ++ std::string cluster_topic = std::string(base_topic) + "/UnifyScheduleEntryLock/Attributes/ClusterRevision"; + // Publish Desired + std::string pub_topic_des = cluster_topic + "/Desired"; + std::string payload = std::string(R"({"value": )") +@@ -109664,13 +111298,13 @@ void uic_mqtt_dotdot_unify_thermostat_publish_cluster_revision(const char* base_ + true); + } + +-// Unretain Cluster Revision for UnifyThermostat Cluster +-void uic_mqtt_dotdot_unify_thermostat_unretain_cluster_revision(const char* base_topic) ++// Unretain Cluster Revision for UnifyScheduleEntryLock Cluster ++void uic_mqtt_dotdot_unify_schedule_entry_lock_unretain_cluster_revision(const char* base_topic) + { + // clang-format on + std::string cluster_topic + = std::string(base_topic) +- + "/UnifyThermostat/Attributes/ClusterRevision"; ++ + "/UnifyScheduleEntryLock/Attributes/ClusterRevision"; + // Publish Desired + std::string desired_topic = cluster_topic + "/Desired"; + uic_mqtt_publish(desired_topic.c_str(), NULL, 0, true); +@@ -109680,21 +111314,167 @@ void uic_mqtt_dotdot_unify_thermostat_unretain_cluster_revision(const char* base + // clang-format off + } + ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t day_of_week_value; ++ memset(&day_of_week_value, 0x00, sizeof(day_of_week_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback) { ++ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ day_of_week_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ ++ return false; ++} ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ uint8_t set_action_value; ++ memset(&set_action_value, 0x00, sizeof(set_action_value)); ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t start_year_value; ++ memset(&start_year_value, 0x00, sizeof(start_year_value)); ++ uint8_t start_day_value; ++ memset(&start_day_value, 0x00, sizeof(start_day_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_year_value; ++ memset(&stop_year_value, 0x00, sizeof(stop_year_value)); ++ uint8_t stop_day_value; ++ memset(&stop_day_value, 0x00, sizeof(stop_day_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback) { ++ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ set_action_value, ++ ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ start_year_value, ++ ++ start_day_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ stop_year_value, ++ ++ stop_day_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } + +-static inline bool uic_mqtt_dotdot_unify_thermostat_write_attributes_is_supported( ++ return false; ++} ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_is_supported( + const dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint_id) + { +- for (const auto& callback: uic_mqtt_dotdot_unify_thermostat_write_attributes_callback) { +- uic_mqtt_dotdot_unify_thermostat_state_t unify_thermostat_new_state = {}; +- uic_mqtt_dotdot_unify_thermostat_updated_state_t unify_thermostat_new_updated_state = {}; ++ uint8_t set_action_value; ++ memset(&set_action_value, 0x00, sizeof(set_action_value)); ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t week_day_bitmask_value; ++ memset(&week_day_bitmask_value, 0x00, sizeof(week_day_bitmask_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t duration_hour_value; ++ memset(&duration_hour_value, 0x00, sizeof(duration_hour_value)); ++ uint8_t duration_minute_value; ++ memset(&duration_minute_value, 0x00, sizeof(duration_minute_value)); ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback) { ++ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ set_action_value, ++ ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ week_day_bitmask_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ duration_hour_value, ++ ++ duration_minute_value ++ ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_state_t unify_schedule_entry_lock_new_state = {}; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t unify_schedule_entry_lock_new_updated_state = {}; + + if (callback( + unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, +- unify_thermostat_new_state, +- unify_thermostat_new_updated_state ++ unify_schedule_entry_lock_new_state, ++ unify_schedule_entry_lock_new_updated_state + ) == SL_STATUS_OK) { + return true; + } +@@ -109702,17 +111482,17 @@ static inline bool uic_mqtt_dotdot_unify_thermostat_write_attributes_is_supporte + return false; + } + +-static inline bool uic_mqtt_dotdot_unify_thermostat_force_read_attributes_is_supported( ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_is_supported( + const dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint_id) + { +- for (const auto& callback: uic_mqtt_dotdot_unify_thermostat_force_read_attributes_callback) { +- uic_mqtt_dotdot_unify_thermostat_updated_state_t unify_thermostat_force_update = {0}; ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t unify_schedule_entry_lock_force_update = {0}; + if (callback( + unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, +- unify_thermostat_force_update ++ unify_schedule_entry_lock_force_update + ) == SL_STATUS_OK) { + return true; + } +@@ -109720,8 +111500,8 @@ static inline bool uic_mqtt_dotdot_unify_thermostat_force_read_attributes_is_sup + return false; + } + +-// Publishing Supported Commands for UnifyThermostat Cluster +-void uic_mqtt_dotdot_unify_thermostat_publish_supported_commands( ++// Publishing Supported Commands for UnifyScheduleEntryLock Cluster ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_supported_commands( + const dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint_id) + { +@@ -109730,9 +111510,30 @@ void uic_mqtt_dotdot_unify_thermostat_publish_supported_commands( + ss.str(""); + + // check if there is callback for each command ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("ScheduleEntryLockWeekDayReport")"; ++ } ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("ScheduleEntryLockYearDayReport")"; ++ } ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("ScheduleEntryLockDailyRepeatingReport")"; ++ } + + // Check for a WriteAttributes Callback +- if(uic_mqtt_dotdot_unify_thermostat_write_attributes_is_supported(unid, endpoint_id)) { ++ if(uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_is_supported(unid, endpoint_id)) { + if (first_command == false) { + ss << ", "; + } +@@ -109741,7 +111542,7 @@ void uic_mqtt_dotdot_unify_thermostat_publish_supported_commands( + } + + // Check for a ForceReadAttributes Callback +- if (uic_mqtt_dotdot_unify_thermostat_force_read_attributes_is_supported(unid, endpoint_id)) { ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_is_supported(unid, endpoint_id)) { + if (first_command == false) { + ss << ", "; + } +@@ -109752,7 +111553,7 @@ void uic_mqtt_dotdot_unify_thermostat_publish_supported_commands( + // Publish supported commands + std::string topic = "ucl/by-unid/" + std::string(unid); + topic += "/ep"+ std::to_string(endpoint_id); +- topic += "/UnifyThermostat/SupportedCommands"; ++ topic += "/UnifyScheduleEntryLock/SupportedCommands"; + std::string payload_str("{\"value\": [" + ss.str() + "]" + "}"); + if (first_command == false) { + uic_mqtt_publish(topic.c_str(), +@@ -109764,7 +111565,7 @@ void uic_mqtt_dotdot_unify_thermostat_publish_supported_commands( + // 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 += "/UnifyThermostat/Attributes"; ++ attributes_topic += "/UnifyScheduleEntryLock/Attributes"; + + if (uic_mqtt_count_topics(attributes_topic.c_str()) > 0) { + uic_mqtt_publish(topic.c_str(), +@@ -109775,14 +111576,14 @@ void uic_mqtt_dotdot_unify_thermostat_publish_supported_commands( + } + } + +-// Publishing empty/no Supported Commands for UnifyThermostat Cluster +-void uic_mqtt_dotdot_unify_thermostat_publish_empty_supported_commands( ++// Publishing empty/no Supported Commands for UnifyScheduleEntryLock Cluster ++void uic_mqtt_dotdot_unify_schedule_entry_lock_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 += "/UnifyThermostat/SupportedCommands"; ++ topic += "/UnifyScheduleEntryLock/SupportedCommands"; + + if (uic_mqtt_count_topics(topic.c_str()) > 0) { + uic_mqtt_publish(topic.c_str(), +@@ -116638,6 +118439,114 @@ void uic_mqtt_dotdot_unify_fan_control_publish_generated_turn_off_command( + payload.size(), + false); + } ++/** ++ * @brief Publishes an incoming/generated ScheduleEntryLockWeekDayReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport ++ * ++ * @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_schedule_entry_lock_publish_generated_schedule_entry_lock_week_day_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated ScheduleEntryLockYearDayReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport ++ * ++ * @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_schedule_entry_lock_publish_generated_schedule_entry_lock_year_day_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated ScheduleEntryLockDailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_generated_schedule_entry_lock_daily_repeating_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} + /** + * @brief Publishes an incoming/generated ModeSet command for + * the UnifyHumidityControl cluster. +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 9fbbc1ede6..bb5785ac9c 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.hpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.hpp +@@ -371,6 +371,13 @@ sl_status_t uic_mqtt_dotdot_by_group_unify_fan_control_init(); + */ + sl_status_t uic_mqtt_dotdot_by_group_unify_thermostat_init(); + ++/** ++ * @brief Initialize UnifyScheduleEntryLock dotdot bygroup command handlers ++ * ++ * @returns SL_STATUS_OK on success, error otherwise. ++ */ ++sl_status_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_init(); ++ + /** + * @brief Initialize UnifyHumidityControl dotdot bygroup command handlers + * +@@ -5063,6 +5070,84 @@ void uic_mqtt_dotdot_on_unify_fan_control_WriteAttributes( + const size_t message_length); + + ++// clang-format on ++ ++/** ++ * @brief Retrieves the container with callbacks pointer for ++ * by-unid UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport messages ++ * ++ * @returns std::set of callbacks. ++ */ ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length); ++// clang-format on ++ ++/** ++ * @brief Retrieves the container with callbacks pointer for ++ * by-unid UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport messages ++ * ++ * @returns std::set of callbacks. ++ */ ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length); ++// clang-format on ++ ++/** ++ * @brief Retrieves the container with callbacks pointer for ++ * by-unid UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport messages ++ * ++ * @returns std::set of callbacks. ++ */ ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ 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_schedule_entry_lock_write_attributes_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WriteAttributes ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes( ++ const char *topic, ++ const char *message, ++ const size_t message_length); ++ ++ + // clang-format on + + /** +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 25ce61e26a..d83f8e50ea 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 +@@ -62164,6 +62164,713 @@ void uic_mqtt_dotdot_unify_thermostat_attribute_operating_state_callback_set(con + + // End of supported cluster. + ++/////////////////////////////////////////////////////////////////////////////// ++// Callback pointers for UnifyScheduleEntryLock ++/////////////////////////////////////////////////////////////////////////////// ++static uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_week_day_callback_t uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_week_day_callback = nullptr; ++static uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_year_day_callback_t uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_year_day_callback = nullptr; ++static uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_signtzo_callback_t uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_signtzo_callback = nullptr; ++static uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_hourtzo_callback_t uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_hourtzo_callback = nullptr; ++static uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_minutetzo_callback_t uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_minutetzo_callback = nullptr; ++static uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_sign_callback_t uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_sign_callback = nullptr; ++static uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_minute_callback_t uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_minute_callback = nullptr; ++static uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_number_of_slots_daily_repeating_callback_t uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_number_of_slots_daily_repeating_callback = nullptr; ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Attribute update handlers for UnifyScheduleEntryLock ++/////////////////////////////////////////////////////////////////////////////// ++static void uic_mqtt_dotdot_on_unify_schedule_entry_lock_slots_week_day_attribute_update( ++ const char *topic, ++ const char *message, ++ const size_t message_length) { ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_week_day_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 slots_week_day = {}; ++ ++ 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, "UnifyScheduleEntryLock::SlotsWeekDay: Missing attribute element: 'value'\n"); ++ return; ++ } ++// Start parsing value ++ slots_week_day = 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_schedule_entry_lock_attribute_slots_week_day_callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ unretained, ++ update_type, ++ slots_week_day ++ ); ++ ++} ++static void uic_mqtt_dotdot_on_unify_schedule_entry_lock_slots_year_day_attribute_update( ++ const char *topic, ++ const char *message, ++ const size_t message_length) { ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_year_day_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 slots_year_day = {}; ++ ++ 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, "UnifyScheduleEntryLock::SlotsYearDay: Missing attribute element: 'value'\n"); ++ return; ++ } ++// Start parsing value ++ slots_year_day = 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_schedule_entry_lock_attribute_slots_year_day_callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ unretained, ++ update_type, ++ slots_year_day ++ ); ++ ++} ++static void uic_mqtt_dotdot_on_unify_schedule_entry_lock_signtzo_attribute_update( ++ const char *topic, ++ const char *message, ++ const size_t message_length) { ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_signtzo_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 signtzo = {}; ++ ++ 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, "UnifyScheduleEntryLock::SignTZO: Missing attribute element: 'value'\n"); ++ return; ++ } ++// Start parsing value ++ signtzo = 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_schedule_entry_lock_attribute_signtzo_callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ unretained, ++ update_type, ++ signtzo ++ ); ++ ++} ++static void uic_mqtt_dotdot_on_unify_schedule_entry_lock_hourtzo_attribute_update( ++ const char *topic, ++ const char *message, ++ const size_t message_length) { ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_hourtzo_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 hourtzo = {}; ++ ++ 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, "UnifyScheduleEntryLock::HourTZO: Missing attribute element: 'value'\n"); ++ return; ++ } ++// Start parsing value ++ hourtzo = 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_schedule_entry_lock_attribute_hourtzo_callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ unretained, ++ update_type, ++ hourtzo ++ ); ++ ++} ++static void uic_mqtt_dotdot_on_unify_schedule_entry_lock_minutetzo_attribute_update( ++ const char *topic, ++ const char *message, ++ const size_t message_length) { ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_minutetzo_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 minutetzo = {}; ++ ++ 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, "UnifyScheduleEntryLock::MinuteTZO: Missing attribute element: 'value'\n"); ++ return; ++ } ++// Start parsing value ++ minutetzo = 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_schedule_entry_lock_attribute_minutetzo_callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ unretained, ++ update_type, ++ minutetzo ++ ); ++ ++} ++static void uic_mqtt_dotdot_on_unify_schedule_entry_lock_dst_offset_sign_attribute_update( ++ const char *topic, ++ const char *message, ++ const size_t message_length) { ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_sign_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 dst_offset_sign = {}; ++ ++ 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, "UnifyScheduleEntryLock::DSTOffsetSign: Missing attribute element: 'value'\n"); ++ return; ++ } ++// Start parsing value ++ dst_offset_sign = 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_schedule_entry_lock_attribute_dst_offset_sign_callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ unretained, ++ update_type, ++ dst_offset_sign ++ ); ++ ++} ++static void uic_mqtt_dotdot_on_unify_schedule_entry_lock_dst_offset_minute_attribute_update( ++ const char *topic, ++ const char *message, ++ const size_t message_length) { ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_minute_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 dst_offset_minute = {}; ++ ++ 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, "UnifyScheduleEntryLock::DSTOffsetMinute: Missing attribute element: 'value'\n"); ++ return; ++ } ++// Start parsing value ++ dst_offset_minute = 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_schedule_entry_lock_attribute_dst_offset_minute_callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ unretained, ++ update_type, ++ dst_offset_minute ++ ); ++ ++} ++static void uic_mqtt_dotdot_on_unify_schedule_entry_lock_number_of_slots_daily_repeating_attribute_update( ++ const char *topic, ++ const char *message, ++ const size_t message_length) { ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_number_of_slots_daily_repeating_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 number_of_slots_daily_repeating = {}; ++ ++ 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, "UnifyScheduleEntryLock::NumberOfSlotsDailyRepeating: Missing attribute element: 'value'\n"); ++ return; ++ } ++// Start parsing value ++ number_of_slots_daily_repeating = 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_schedule_entry_lock_attribute_number_of_slots_daily_repeating_callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ unretained, ++ update_type, ++ number_of_slots_daily_repeating ++ ); ++ ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Attribute init functions for UnifyScheduleEntryLock ++/////////////////////////////////////////////////////////////////////////////// ++sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_attributes_init() ++{ ++ std::string base_topic = "ucl/by-unid/+/+/"; ++ ++ std::string subscription_topic; ++ if(uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_week_day_callback) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Attributes/SlotsWeekDay/#"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_schedule_entry_lock_slots_week_day_attribute_update); ++ } ++ if(uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_year_day_callback) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Attributes/SlotsYearDay/#"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_schedule_entry_lock_slots_year_day_attribute_update); ++ } ++ if(uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_signtzo_callback) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Attributes/SignTZO/#"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_schedule_entry_lock_signtzo_attribute_update); ++ } ++ if(uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_hourtzo_callback) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Attributes/HourTZO/#"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_schedule_entry_lock_hourtzo_attribute_update); ++ } ++ if(uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_minutetzo_callback) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Attributes/MinuteTZO/#"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_schedule_entry_lock_minutetzo_attribute_update); ++ } ++ if(uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_sign_callback) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Attributes/DSTOffsetSign/#"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_schedule_entry_lock_dst_offset_sign_attribute_update); ++ } ++ if(uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_minute_callback) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Attributes/DSTOffsetMinute/#"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_schedule_entry_lock_dst_offset_minute_attribute_update); ++ } ++ if(uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_number_of_slots_daily_repeating_callback) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Attributes/NumberOfSlotsDailyRepeating/#"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), &uic_mqtt_dotdot_on_unify_schedule_entry_lock_number_of_slots_daily_repeating_attribute_update); ++ } ++ ++ return SL_STATUS_OK; ++} ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Callback setters and getters for UnifyScheduleEntryLock ++/////////////////////////////////////////////////////////////////////////////// ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_week_day_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_week_day_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_week_day_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_year_day_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_year_day_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_slots_year_day_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_signtzo_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_signtzo_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_signtzo_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_hourtzo_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_hourtzo_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_hourtzo_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_minutetzo_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_minutetzo_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_minutetzo_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_sign_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_sign_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_sign_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_minute_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_minute_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_dst_offset_minute_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_number_of_slots_daily_repeating_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_number_of_slots_daily_repeating_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_attribute_number_of_slots_daily_repeating_callback = callback; ++} ++ ++// End of supported cluster. ++ + /////////////////////////////////////////////////////////////////////////////// + // Callback pointers for UnifyHumidityControl + /////////////////////////////////////////////////////////////////////////////// +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 25c2c2aced..0c1e90c9d9 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 +@@ -14523,6 +14523,468 @@ void uic_mqtt_dotdot_parse_unify_thermostat_write_attributes( + } + + ++std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_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 ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["UserIdentifier"] = nlohmann::json(fields->user_identifier); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["ScheduleSlotID"] = nlohmann::json(fields->schedule_slotid); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["DayOfWeek"] = nlohmann::json(fields->day_of_week); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartHour"] = nlohmann::json(fields->start_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartMinute"] = nlohmann::json(fields->start_minute); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopHour"] = nlohmann::json(fields->stop_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopMinute"] = nlohmann::json(fields->stop_minute); ++ ++ // 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_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ ++ uint8_t &day_of_week, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &stop_hour, ++ ++ uint8_t &stop_minute ++ ++) { ++ ++ if (jsn.at("UserIdentifier").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ user_identifier = jsn.at("UserIdentifier").get< uint8_t >(); ++ if (jsn.at("ScheduleSlotID").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ schedule_slotid = jsn.at("ScheduleSlotID").get< uint8_t >(); ++ if (jsn.at("DayOfWeek").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ day_of_week = jsn.at("DayOfWeek").get< uint8_t >(); ++ if (jsn.at("StartHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_hour = jsn.at("StartHour").get< uint8_t >(); ++ if (jsn.at("StartMinute").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_minute = jsn.at("StartMinute").get< uint8_t >(); ++ if (jsn.at("StopHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_hour = jsn.at("StopHour").get< uint8_t >(); ++ if (jsn.at("StopMinute").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_minute = jsn.at("StopMinute").get< uint8_t >(); ++ } ++ ++ ++std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_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 ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["SetAction"] = nlohmann::json(fields->set_action); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["UserIdentifier"] = nlohmann::json(fields->user_identifier); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["ScheduleSlotID"] = nlohmann::json(fields->schedule_slotid); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartYear"] = nlohmann::json(fields->start_year); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartDay"] = nlohmann::json(fields->start_day); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartHour"] = nlohmann::json(fields->start_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartMinute"] = nlohmann::json(fields->start_minute); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopYear"] = nlohmann::json(fields->stop_year); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopDay"] = nlohmann::json(fields->stop_day); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopHour"] = nlohmann::json(fields->stop_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopMinute"] = nlohmann::json(fields->stop_minute); ++ ++ // 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_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ nlohmann::json &jsn, ++ uint8_t &set_action, ++ ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ ++ uint8_t &start_year, ++ ++ uint8_t &start_day, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &stop_year, ++ ++ uint8_t &stop_day, ++ ++ uint8_t &stop_hour, ++ ++ uint8_t &stop_minute ++ ++) { ++ ++ if (jsn.at("SetAction").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ set_action = jsn.at("SetAction").get< uint8_t >(); ++ if (jsn.at("UserIdentifier").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ user_identifier = jsn.at("UserIdentifier").get< uint8_t >(); ++ if (jsn.at("ScheduleSlotID").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ schedule_slotid = jsn.at("ScheduleSlotID").get< uint8_t >(); ++ if (jsn.at("StartYear").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_year = jsn.at("StartYear").get< uint8_t >(); ++ if (jsn.at("StartDay").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_day = jsn.at("StartDay").get< uint8_t >(); ++ if (jsn.at("StartHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_hour = jsn.at("StartHour").get< uint8_t >(); ++ if (jsn.at("StartMinute").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_minute = jsn.at("StartMinute").get< uint8_t >(); ++ if (jsn.at("StopYear").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_year = jsn.at("StopYear").get< uint8_t >(); ++ if (jsn.at("StopDay").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_day = jsn.at("StopDay").get< uint8_t >(); ++ if (jsn.at("StopHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_hour = jsn.at("StopHour").get< uint8_t >(); ++ if (jsn.at("StopMinute").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_minute = jsn.at("StopMinute").get< uint8_t >(); ++ } ++ ++ ++std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_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 ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["SetAction"] = nlohmann::json(fields->set_action); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["UserIdentifier"] = nlohmann::json(fields->user_identifier); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["ScheduleSlotID"] = nlohmann::json(fields->schedule_slotid); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["WeekDayBitmask"] = nlohmann::json(fields->week_day_bitmask); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartHour"] = nlohmann::json(fields->start_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartMinute"] = nlohmann::json(fields->start_minute); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["DurationHour"] = nlohmann::json(fields->duration_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["DurationMinute"] = nlohmann::json(fields->duration_minute); ++ ++ // 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_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ nlohmann::json &jsn, ++ uint8_t &set_action, ++ ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ ++ uint8_t &week_day_bitmask, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &duration_hour, ++ ++ uint8_t &duration_minute ++ ++) { ++ ++ if (jsn.at("SetAction").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ set_action = jsn.at("SetAction").get< uint8_t >(); ++ if (jsn.at("UserIdentifier").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ user_identifier = jsn.at("UserIdentifier").get< uint8_t >(); ++ if (jsn.at("ScheduleSlotID").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ schedule_slotid = jsn.at("ScheduleSlotID").get< uint8_t >(); ++ if (jsn.at("WeekDayBitmask").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ week_day_bitmask = jsn.at("WeekDayBitmask").get< uint8_t >(); ++ if (jsn.at("StartHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_hour = jsn.at("StartHour").get< uint8_t >(); ++ if (jsn.at("StartMinute").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_minute = jsn.at("StartMinute").get< uint8_t >(); ++ if (jsn.at("DurationHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ duration_hour = jsn.at("DurationHour").get< uint8_t >(); ++ if (jsn.at("DurationMinute").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ duration_minute = jsn.at("DurationMinute").get< uint8_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_schedule_entry_lock_write_attributes( ++ nlohmann::json &jsn, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_state_t &new_state, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t &new_updated_state ++) { ++ ++ ++ if (jsn.find("SlotsWeekDay") != jsn.end()) { ++ ++ new_state.slots_week_day = jsn.at("SlotsWeekDay").get(); ++ ++ new_updated_state.slots_week_day = true; ++ } ++ ++ if (jsn.find("SlotsYearDay") != jsn.end()) { ++ ++ new_state.slots_year_day = jsn.at("SlotsYearDay").get(); ++ ++ new_updated_state.slots_year_day = true; ++ } ++ ++ if (jsn.find("SignTZO") != jsn.end()) { ++ ++ new_state.signtzo = jsn.at("SignTZO").get(); ++ ++ new_updated_state.signtzo = true; ++ } ++ ++ if (jsn.find("HourTZO") != jsn.end()) { ++ ++ new_state.hourtzo = jsn.at("HourTZO").get(); ++ ++ new_updated_state.hourtzo = true; ++ } ++ ++ if (jsn.find("MinuteTZO") != jsn.end()) { ++ ++ new_state.minutetzo = jsn.at("MinuteTZO").get(); ++ ++ new_updated_state.minutetzo = true; ++ } ++ ++ if (jsn.find("DSTOffsetSign") != jsn.end()) { ++ ++ new_state.dst_offset_sign = jsn.at("DSTOffsetSign").get(); ++ ++ new_updated_state.dst_offset_sign = true; ++ } ++ ++ if (jsn.find("DSTOffsetMinute") != jsn.end()) { ++ ++ new_state.dst_offset_minute = jsn.at("DSTOffsetMinute").get(); ++ ++ new_updated_state.dst_offset_minute = true; ++ } ++ ++ if (jsn.find("NumberOfSlotsDailyRepeating") != jsn.end()) { ++ ++ new_state.number_of_slots_daily_repeating = jsn.at("NumberOfSlotsDailyRepeating").get(); ++ ++ new_updated_state.number_of_slots_daily_repeating = true; ++ } ++ ++ ++} ++ ++ + 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 +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 4bb5c71735..1082c43494 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 +@@ -6029,6 +6029,148 @@ void uic_mqtt_dotdot_parse_unify_thermostat_write_attributes( + ); + + ++/** ++ * @brief Private helper function that will create a JSON string based on the ++ * fields of a UnifyScheduleEntryLock ScheduleEntryLockWeekDayReport 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_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ ++); ++ ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock ScheduleEntryLockWeekDayReport command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ ++ uint8_t &day_of_week, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &stop_hour, ++ ++ uint8_t &stop_minute ++ ++); ++ ++ ++ ++/** ++ * @brief Private helper function that will create a JSON string based on the ++ * fields of a UnifyScheduleEntryLock ScheduleEntryLockYearDayReport 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_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ ++); ++ ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock ScheduleEntryLockYearDayReport command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ nlohmann::json &jsn, ++ uint8_t &set_action, ++ ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ ++ uint8_t &start_year, ++ ++ uint8_t &start_day, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &stop_year, ++ ++ uint8_t &stop_day, ++ ++ uint8_t &stop_hour, ++ ++ uint8_t &stop_minute ++ ++); ++ ++ ++ ++/** ++ * @brief Private helper function that will create a JSON string based on the ++ * fields of a UnifyScheduleEntryLock ScheduleEntryLockDailyRepeatingReport 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_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ ++); ++ ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock ScheduleEntryLockDailyRepeatingReport command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ nlohmann::json &jsn, ++ uint8_t &set_action, ++ ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ ++ uint8_t &week_day_bitmask, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &duration_hour, ++ ++ uint8_t &duration_minute ++ ++); ++ ++ ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock WriteAttributes command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_write_attributes( ++ nlohmann::json &jsn, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_state_t &new_state, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t &new_updated_state ++); ++ ++ + /** + * @brief Private helper function that will create a JSON string based on the + * fields of a UnifyHumidityControl ModeSet command +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 9c5b838ded..03c7efb978 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 +@@ -11235,6 +11235,234 @@ void uic_mqtt_dotdot_unify_thermostat_publish_generated_write_attributes_command + false); + } + ++/** ++ * @brief Publishes an incoming/generated ScheduleEntryLockWeekDayReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport ++ * ++ * @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_schedule_entry_lock_publish_generated_schedule_entry_lock_week_day_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated ScheduleEntryLockYearDayReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport ++ * ++ * @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_schedule_entry_lock_publish_generated_schedule_entry_lock_year_day_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated ScheduleEntryLockDailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_generated_schedule_entry_lock_daily_repeating_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_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 UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/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_schedule_entry_lock_publish_generated_write_attributes_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_state_t attribute_values, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t attribute_list ++){ ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/WriteAttributes"; ++ ++ nlohmann::json json_object = nlohmann::json::object(); ++ ++ ++ if (attribute_list.slots_week_day == true) { ++ ++ // This is a single value ++ ++ json_object["SlotsWeekDay"] = attribute_values.slots_week_day; ++ ++ ++ } ++ ++ ++ if (attribute_list.slots_year_day == true) { ++ ++ // This is a single value ++ ++ json_object["SlotsYearDay"] = attribute_values.slots_year_day; ++ ++ ++ } ++ ++ ++ if (attribute_list.signtzo == true) { ++ ++ // This is a single value ++ ++ json_object["SignTZO"] = attribute_values.signtzo; ++ ++ ++ } ++ ++ ++ if (attribute_list.hourtzo == true) { ++ ++ // This is a single value ++ ++ json_object["HourTZO"] = attribute_values.hourtzo; ++ ++ ++ } ++ ++ ++ if (attribute_list.minutetzo == true) { ++ ++ // This is a single value ++ ++ json_object["MinuteTZO"] = attribute_values.minutetzo; ++ ++ ++ } ++ ++ ++ if (attribute_list.dst_offset_sign == true) { ++ ++ // This is a single value ++ ++ json_object["DSTOffsetSign"] = attribute_values.dst_offset_sign; ++ ++ ++ } ++ ++ ++ if (attribute_list.dst_offset_minute == true) { ++ ++ // This is a single value ++ ++ json_object["DSTOffsetMinute"] = attribute_values.dst_offset_minute; ++ ++ ++ } ++ ++ ++ if (attribute_list.number_of_slots_daily_repeating == true) { ++ ++ // This is a single value ++ ++ json_object["NumberOfSlotsDailyRepeating"] = attribute_values.number_of_slots_daily_repeating; ++ ++ ++ } ++ ++ ++ // 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); ++} ++ + /** + * @brief Publishes an incoming/generated ModeSet command for + * the UnifyHumidityControl cluster. +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 36023fc2e7..c63dd2a685 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 +@@ -368,6 +368,12 @@ static uic_mqtt_dotdot_by_group_unify_fan_control_write_attributes_callback_t ui + static uic_mqtt_dotdot_by_group_unify_thermostat_write_attributes_callback_t uic_mqtt_dotdot_by_group_unify_thermostat_write_attributes_callback = nullptr; + + ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_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; +@@ -1886,6 +1892,33 @@ void uic_mqtt_dotdot_by_group_unify_thermostat_write_attributes_callback_set( + + + ++// Callbacks setters ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback = callback; ++} ++ ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback = callback; ++} ++ ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback = callback; ++} ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback_set( ++ const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback = callback; ++} ++ ++ ++ + // 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) +@@ -23427,6 +23460,496 @@ sl_status_t uic_mqtt_dotdot_by_group_unify_thermostat_init() + + + ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_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_schedule_entry_lock_schedule_entry_lock_week_day_report_callback != nullptr) { ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t fields; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ jsn, ++ fields.user_identifier, ++ ++ fields.schedule_slotid, ++ ++ fields.day_of_week, ++ ++ fields.start_hour, ++ ++ fields.start_minute, ++ ++ fields.stop_hour, ++ ++ fields.stop_minute ++ ); ++ ++ // 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, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback( ++ group_id, ++ &fields ++ ); ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_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("UserIdentifier") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: UserIdentifier\n"); ++ return; ++ } ++ if (jsn.find("ScheduleSlotID") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: ScheduleSlotID\n"); ++ return; ++ } ++ if (jsn.find("DayOfWeek") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: DayOfWeek\n"); ++ return; ++ } ++ if (jsn.find("StartHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: StartHour\n"); ++ return; ++ } ++ if (jsn.find("StartMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: StartMinute\n"); ++ return; ++ } ++ if (jsn.find("StopHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: StopHour\n"); ++ return; ++ } ++ if (jsn.find("StopMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: StopMinute\n"); ++ return; ++ } ++ ++ group_dispatch_callback( ++ group_id, ++ "UnifyScheduleEntryLock", ++ "ScheduleEntryLockWeekDayReport", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_week_day_report); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "ScheduleEntryLockWeekDayReport: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_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_schedule_entry_lock_schedule_entry_lock_year_day_report_callback != nullptr) { ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t fields; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ jsn, ++ fields.set_action, ++ ++ fields.user_identifier, ++ ++ fields.schedule_slotid, ++ ++ fields.start_year, ++ ++ fields.start_day, ++ ++ fields.start_hour, ++ ++ fields.start_minute, ++ ++ fields.stop_year, ++ ++ fields.stop_day, ++ ++ fields.stop_hour, ++ ++ fields.stop_minute ++ ); ++ ++ // 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, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback( ++ group_id, ++ &fields ++ ); ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_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("SetAction") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: SetAction\n"); ++ return; ++ } ++ if (jsn.find("UserIdentifier") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: UserIdentifier\n"); ++ return; ++ } ++ if (jsn.find("ScheduleSlotID") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: ScheduleSlotID\n"); ++ return; ++ } ++ if (jsn.find("StartYear") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StartYear\n"); ++ return; ++ } ++ if (jsn.find("StartDay") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StartDay\n"); ++ return; ++ } ++ if (jsn.find("StartHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StartHour\n"); ++ return; ++ } ++ if (jsn.find("StartMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StartMinute\n"); ++ return; ++ } ++ if (jsn.find("StopYear") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StopYear\n"); ++ return; ++ } ++ if (jsn.find("StopDay") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StopDay\n"); ++ return; ++ } ++ if (jsn.find("StopHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StopHour\n"); ++ return; ++ } ++ if (jsn.find("StopMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StopMinute\n"); ++ return; ++ } ++ ++ group_dispatch_callback( ++ group_id, ++ "UnifyScheduleEntryLock", ++ "ScheduleEntryLockYearDayReport", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_report); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "ScheduleEntryLockYearDayReport: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_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_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback != nullptr) { ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t fields; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ jsn, ++ fields.set_action, ++ ++ fields.user_identifier, ++ ++ fields.schedule_slotid, ++ ++ fields.week_day_bitmask, ++ ++ fields.start_hour, ++ ++ fields.start_minute, ++ ++ fields.duration_hour, ++ ++ fields.duration_minute ++ ); ++ ++ // 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, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback( ++ group_id, ++ &fields ++ ); ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_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("SetAction") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: SetAction\n"); ++ return; ++ } ++ if (jsn.find("UserIdentifier") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: UserIdentifier\n"); ++ return; ++ } ++ if (jsn.find("ScheduleSlotID") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: ScheduleSlotID\n"); ++ return; ++ } ++ if (jsn.find("WeekDayBitmask") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: WeekDayBitmask\n"); ++ return; ++ } ++ if (jsn.find("StartHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: StartHour\n"); ++ return; ++ } ++ if (jsn.find("StartMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: StartMinute\n"); ++ return; ++ } ++ if (jsn.find("DurationHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: DurationHour\n"); ++ return; ++ } ++ if (jsn.find("DurationMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: DurationMinute\n"); ++ return; ++ } ++ ++ group_dispatch_callback( ++ group_id, ++ "UnifyScheduleEntryLock", ++ "ScheduleEntryLockDailyRepeatingReport", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "ScheduleEntryLockDailyRepeatingReport: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } ++ ++} ++ ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_WriteAttributes( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_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_schedule_entry_lock_write_attributes_callback().empty())) { ++ try { ++ group_dispatch_callback(group_id, ++ "UnifyScheduleEntryLock", ++ "WriteAttributes", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } else if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback != nullptr) { ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_state_t new_state = {}; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t new_updated_state = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_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, "UnifyScheduleEntryLock", "WriteAttributes"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback( ++ group_id, ++ new_state, ++ new_updated_state ++ ); ++ } ++} ++ ++sl_status_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_init() ++{ ++ std::string subscription_topic; ++ const std::string topic_bygroup = TOPIC_BY_GROUP_PREFIX; ++ if(uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/WriteAttributes"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_WriteAttributes); ++ } ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report); ++ } ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report); ++ } ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report); ++ } ++ ++ return SL_STATUS_OK; ++} ++ ++ ++ ++ + // 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, +@@ -23989,6 +24512,11 @@ void uic_mqtt_dotdot_set_group_dispatch_callback(group_dispatch_t callback) + + uic_mqtt_subscribe("ucl/by-group/+/UnifyThermostat/Commands/WriteAttributes", uic_mqtt_dotdot_on_by_group_unify_thermostat_WriteAttributes); + ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/WriteAttributes", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_WriteAttributes); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report); ++ + 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); +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 3cfdb34365..63daf43fec 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 +@@ -10473,6 +10473,57 @@ std::string get_enum_value_name( + #endif + } + ++ if (64801 == cluster_id) { ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY_ENUM_NAME_AVAILABLE ++ if (1 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockslots_week_day instead of this: unify_schedule_entry_lock_slots_week_day ++ return unify_schedule_entry_lock_slots_week_day_get_enum_value_name(value); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY_ENUM_NAME_AVAILABLE ++ if (2 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockslots_year_day instead of this: unify_schedule_entry_lock_slots_year_day ++ return unify_schedule_entry_lock_slots_year_day_get_enum_value_name(value); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO_ENUM_NAME_AVAILABLE ++ if (3 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_locksigntzo instead of this: unify_schedule_entry_lock_signtzo ++ return unify_schedule_entry_lock_signtzo_get_enum_value_name(value); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO_ENUM_NAME_AVAILABLE ++ if (4 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockhourtzo instead of this: unify_schedule_entry_lock_hourtzo ++ return unify_schedule_entry_lock_hourtzo_get_enum_value_name(value); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO_ENUM_NAME_AVAILABLE ++ if (5 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockminutetzo instead of this: unify_schedule_entry_lock_minutetzo ++ return unify_schedule_entry_lock_minutetzo_get_enum_value_name(value); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN_ENUM_NAME_AVAILABLE ++ if (6 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockdst_offset_sign instead of this: unify_schedule_entry_lock_dst_offset_sign ++ return unify_schedule_entry_lock_dst_offset_sign_get_enum_value_name(value); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE_ENUM_NAME_AVAILABLE ++ if (7 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockdst_offset_minute instead of this: unify_schedule_entry_lock_dst_offset_minute ++ return unify_schedule_entry_lock_dst_offset_minute_get_enum_value_name(value); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING_ENUM_NAME_AVAILABLE ++ if (8 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_locknumber_of_slots_daily_repeating instead of this: unify_schedule_entry_lock_number_of_slots_daily_repeating ++ return unify_schedule_entry_lock_number_of_slots_daily_repeating_get_enum_value_name(value); ++ } ++ #endif ++ } ++ + if (64928 == cluster_id) { + #ifdef UNIFY_HUMIDITY_CONTROL_REPORTING_MODE_ENUM_NAME_AVAILABLE + if (1 == attribute_id) { +@@ -14995,6 +15046,57 @@ uint32_t get_enum_name_value( + #endif + } + ++ if (64801 == cluster_id) { ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY_ENUM_NAME_AVAILABLE ++ if (1 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockslots_week_day instead of this: unify_schedule_entry_lock_slots_week_day ++ return unify_schedule_entry_lock_slots_week_day_get_enum_value_number(name); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY_ENUM_NAME_AVAILABLE ++ if (2 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockslots_year_day instead of this: unify_schedule_entry_lock_slots_year_day ++ return unify_schedule_entry_lock_slots_year_day_get_enum_value_number(name); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO_ENUM_NAME_AVAILABLE ++ if (3 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_locksigntzo instead of this: unify_schedule_entry_lock_signtzo ++ return unify_schedule_entry_lock_signtzo_get_enum_value_number(name); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO_ENUM_NAME_AVAILABLE ++ if (4 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockhourtzo instead of this: unify_schedule_entry_lock_hourtzo ++ return unify_schedule_entry_lock_hourtzo_get_enum_value_number(name); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO_ENUM_NAME_AVAILABLE ++ if (5 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockminutetzo instead of this: unify_schedule_entry_lock_minutetzo ++ return unify_schedule_entry_lock_minutetzo_get_enum_value_number(name); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN_ENUM_NAME_AVAILABLE ++ if (6 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockdst_offset_sign instead of this: unify_schedule_entry_lock_dst_offset_sign ++ return unify_schedule_entry_lock_dst_offset_sign_get_enum_value_number(name); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE_ENUM_NAME_AVAILABLE ++ if (7 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_lockdst_offset_minute instead of this: unify_schedule_entry_lock_dst_offset_minute ++ return unify_schedule_entry_lock_dst_offset_minute_get_enum_value_number(name); ++ } ++ #endif ++ #ifdef UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING_ENUM_NAME_AVAILABLE ++ if (8 == attribute_id) { ++ // FIXME: Some attributes don't work because multi-upper case names end up like this: unify_schedule_entry_locknumber_of_slots_daily_repeating instead of this: unify_schedule_entry_lock_number_of_slots_daily_repeating ++ return unify_schedule_entry_lock_number_of_slots_daily_repeating_get_enum_value_number(name); ++ } ++ #endif ++ } ++ + if (64928 == cluster_id) { + #ifdef UNIFY_HUMIDITY_CONTROL_REPORTING_MODE_ENUM_NAME_AVAILABLE + if (1 == attribute_id) { +diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_send_commands.cpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_send_commands.cpp +index 42fbbf8671..2f17f4fceb 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_send_commands.cpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_send_commands.cpp +@@ -13708,6 +13708,228 @@ void uic_mqtt_dotdot_unify_fan_control_publish_turn_off_command_to_group( + false); + } + ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockWeekDayReport command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_week_day_report_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + ++ std::to_string(destination_endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport"; ++ ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++ fields); ++ ++ sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockWeekDayReport command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_week_day_report_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ ++){ ++ // Create the topic ++ std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + ++ "/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++ fields); ++ ++ sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockYearDayReport command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_year_day_report_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + ++ std::to_string(destination_endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport"; ++ ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++ fields); ++ ++ sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockYearDayReport command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_year_day_report_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ ++){ ++ // Create the topic ++ std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + ++ "/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++ fields); ++ ++ sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockDailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_daily_repeating_report_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + ++ std::to_string(destination_endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport"; ++ ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_command( ++ fields); ++ ++ sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a ScheduleEntryLockDailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_schedule_entry_lock_daily_repeating_report_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ ++){ ++ // Create the topic ++ std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + ++ "/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_command( ++ fields); ++ ++ sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ + /** + * @brief Sends/Publishes a ModeSet command for + * the UnifyHumidityControl cluster to a destination. +diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp +index f7db295e9c..39ed2297f0 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp +@@ -2856,6 +2856,58 @@ void uic_mqtt_dotdot_unify_thermostat_publish_supported_generated_commands( + } + + ++/** ++ * @brief Sends/Publishes a the SupportedGenerated commands for ++ * the UnifyScheduleEntryLock cluster for a UNID/Endpoint ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/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_schedule_entry_lock_publish_supported_generated_commands( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_supported_commands_t *command_list) ++{ ++ std::string topic = "ucl/by-unid/" + std::string(unid); ++ topic += "/ep"+ std::to_string(endpoint); ++ topic += "/UnifyScheduleEntryLock/SupportedGeneratedCommands"; ++ ++ // Assemble of vector of strings for the Supported Commands: ++ std::vector command_vector; ++ if (command_list->schedule_entry_lock_week_day_report == true) { ++ command_vector.emplace_back("ScheduleEntryLockWeekDayReport"); ++ } ++ if (command_list->schedule_entry_lock_year_day_report == true) { ++ command_vector.emplace_back("ScheduleEntryLockYearDayReport"); ++ } ++ if (command_list->schedule_entry_lock_daily_repeating_report == true) { ++ command_vector.emplace_back("ScheduleEntryLockDailyRepeatingReport"); ++ } ++ if (command_list->write_attributes == true) { ++ command_vector.emplace_back("WriteAttributes"); ++ } ++ ++ // JSONify, then Stringify ++ nlohmann::json json_payload; ++ json_payload["value"] = command_vector; ++ std::string string_payload = json_payload.dump(); ++ ++ // Publish to MQTT ++ uic_mqtt_publish(topic.c_str(), ++ string_payload.c_str(), ++ string_payload.length(), ++ true); ++ ++} ++ ++ + /** + * @brief Sends/Publishes a the SupportedGenerated commands for + * the UnifyHumidityControl cluster for a UNID/Endpoint +diff --git a/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include b/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include +index c1fe725721..64c6d7fe29 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include ++++ b/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include +@@ -2995,6 +2995,91 @@ static sl_status_t uic_mqtt_dotdot_unify_fan_control_turn_off_callback_func( + return SL_STATUS_OK; + } + ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_func( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t callback_type, ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ ++ uint8_t day_of_week, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_minute, ++ ++ uint8_t stop_hour, ++ ++ uint8_t stop_minute ++ ++) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_count++; ++ num_command_callbacks++; ++ return SL_STATUS_OK; ++} ++ ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_func( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t callback_type, ++ uint8_t set_action, ++ ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ ++ uint8_t start_year, ++ ++ uint8_t start_day, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_minute, ++ ++ uint8_t stop_year, ++ ++ uint8_t stop_day, ++ ++ uint8_t stop_hour, ++ ++ uint8_t stop_minute ++ ++) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_count++; ++ num_command_callbacks++; ++ return SL_STATUS_OK; ++} ++ ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_func( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t callback_type, ++ uint8_t set_action, ++ ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ ++ uint8_t week_day_bitmask, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_minute, ++ ++ uint8_t duration_hour, ++ ++ uint8_t duration_minute ++ ++) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_count++; ++ num_command_callbacks++; ++ return SL_STATUS_OK; ++} ++ + static unsigned int uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_count; + static sl_status_t uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_func( + dotdot_unid_t unid, +@@ -3409,6 +3494,12 @@ static unsigned int set_all_callbacks() + num_callbacks++; + uic_mqtt_dotdot_unify_fan_control_turn_off_callback_set(&uic_mqtt_dotdot_unify_fan_control_turn_off_callback_func); + num_callbacks++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_func); ++ num_callbacks++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_func); ++ num_callbacks++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_func); ++ num_callbacks++; + uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_set(&uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_func); + num_callbacks++; + uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_set(&uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_func); +@@ -3661,6 +3752,10 @@ static void unset_all_callbacks() + uic_mqtt_dotdot_unify_fan_control_turn_off_callback_clear(); + uic_mqtt_dotdot_clear_unify_fan_control_write_attributes_callbacks(); + uic_mqtt_dotdot_clear_unify_thermostat_write_attributes_callbacks(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_clear(); ++ uic_mqtt_dotdot_clear_unify_schedule_entry_lock_write_attributes_callbacks(); + uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_clear(); + uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_clear(); + uic_mqtt_dotdot_clear_unify_humidity_control_write_attributes_callbacks(); +@@ -3858,6 +3953,9 @@ static void reset_callback_counters() + uic_mqtt_dotdot_protocol_controller_network_management_write_callback_count = 0; + uic_mqtt_dotdot_unify_fan_control_set_fan_mode_callback_count = 0; + uic_mqtt_dotdot_unify_fan_control_turn_off_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_count = 0; + uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_count = 0; + uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_count = 0; + } +diff --git a/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes.uam b/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes.uam +index 0c168c053a..df968cbd76 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes.uam ++++ b/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes.uam +@@ -877,6 +877,16 @@ def DOTDOT_ATTRIBUTE_ID_UNIFY_THERMOSTAT_THERMOSTAT_MODE 0xfd150001 + def DOTDOT_ATTRIBUTE_ID_UNIFY_THERMOSTAT_SUPPORTED_THERMOSTAT_MODE 0xfd150002 + def DOTDOT_ATTRIBUTE_ID_UNIFY_THERMOSTAT_OPERATING_STATE 0xfd150003 + ++// This represents the attributes in the DotDot UnifyScheduleEntryLock cluster ++def DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY 0xfd210001 ++def DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY 0xfd210002 ++def DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO 0xfd210003 ++def DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO 0xfd210004 ++def DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO 0xfd210005 ++def DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN 0xfd210006 ++def DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE 0xfd210007 ++def DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING 0xfd210008 ++ + // This represents the attributes in the DotDot UnifyHumidityControl cluster + def DOTDOT_ATTRIBUTE_ID_UNIFY_HUMIDITY_CONTROL_REPORTING_MODE 0xfda00001 + def DOTDOT_ATTRIBUTE_ID_UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE 0xfda00002 +diff --git a/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes_camel_case.uam b/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes_camel_case.uam +index b867ea5a05..4c4f44f2ba 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes_camel_case.uam ++++ b/components/unify_dotdot_attribute_store/zap-generated/include/dotdot_attributes_camel_case.uam +@@ -877,6 +877,16 @@ def zb_ThermostatMode 0xfd150001 + def zb_SupportedThermostatMode 0xfd150002 + def zb_OperatingState 0xfd150003 + ++// This represents short CamelCase labels the attributes in the DotDot UnifyScheduleEntryLock cluster ++def zb_SlotsWeekDay 0xfd210001 ++def zb_SlotsYearDay 0xfd210002 ++def zb_SignTZO 0xfd210003 ++def zb_HourTZO 0xfd210004 ++def zb_MinuteTZO 0xfd210005 ++def zb_DSTOffsetSign 0xfd210006 ++def zb_DSTOffsetMinute 0xfd210007 ++def zb_NumberOfSlotsDailyRepeating 0xfd210008 ++ + // This represents short CamelCase labels the attributes in the DotDot UnifyHumidityControl cluster + def zb_ReportingMode 0xfda00001 + def zb_SupportedReportingMode 0xfda00002 +diff --git a/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_attribute_store_helpers.h b/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_attribute_store_helpers.h +index e98230c88f..df476f6504 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_attribute_store_helpers.h ++++ b/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_attribute_store_helpers.h +@@ -76496,6 +76496,882 @@ bool dotdot_is_any_unify_thermostat_writable_attribute_supported( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint_id); + ++//////////////////////////////////////////////////////////////////////////////// ++// Start of cluster UnifyScheduleEntryLock ++//////////////////////////////////////////////////////////////////////////////// ++// UnifyScheduleEntryLock SlotsWeekDay ++/** ++ * @brief Verifies if the DotDot UnifyScheduleEntryLock - SlotsWeekDay is supported ++ * under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * ++ * @returns true if SlotsWeekDay is supported ++ * @returns false if SlotsWeekDay is not supported ++ */ ++bool dotdot_is_supported_unify_schedule_entry_lock_slots_week_day ( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Gets the DotDot UnifyScheduleEntryLock - SlotsWeekDay attribute value under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to get, ++ * see \ref attribute_store_get_node_attribute_value ++ * ++ * ++ * @returns SlotsWeekDay attribute ++ */ ++uint8_t dotdot_get_unify_schedule_entry_lock_slots_week_day( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state); ++ ++/** ++ * @brief Set the DotDot UnifyScheduleEntryLock - SlotsWeekDay attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to write for the node, ++ * see \ref attribute_store_set_node_attribute_value ++ * ++ * @param new_slots_week_day new value to set ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_set_unify_schedule_entry_lock_slots_week_day( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_slots_week_day ++ ); ++ ++/** ++ * @brief Undefines the Reported value of the the DotDot UnifyScheduleEntryLock - SlotsWeekDay ++ * attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_slots_week_day_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Undefines the Desired value of the DotDot ++ * UnifyScheduleEntryLock - SlotsWeekDay attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_slots_week_day_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the reported value is defined for the DotDot ++ * UnifyScheduleEntryLock - SlotsWeekDay attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_slots_week_day_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the desired value is defined for the DotDot ++ * UnifyScheduleEntryLock - SlotsWeekDay attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_slots_week_day_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Creates a DotDot UnifyScheduleEntryLock - SlotsWeekDay attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_create_unify_schedule_entry_lock_slots_week_day( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++// UnifyScheduleEntryLock SlotsYearDay ++/** ++ * @brief Verifies if the DotDot UnifyScheduleEntryLock - SlotsYearDay is supported ++ * under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * ++ * @returns true if SlotsYearDay is supported ++ * @returns false if SlotsYearDay is not supported ++ */ ++bool dotdot_is_supported_unify_schedule_entry_lock_slots_year_day ( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Gets the DotDot UnifyScheduleEntryLock - SlotsYearDay attribute value under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to get, ++ * see \ref attribute_store_get_node_attribute_value ++ * ++ * ++ * @returns SlotsYearDay attribute ++ */ ++uint8_t dotdot_get_unify_schedule_entry_lock_slots_year_day( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state); ++ ++/** ++ * @brief Set the DotDot UnifyScheduleEntryLock - SlotsYearDay attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to write for the node, ++ * see \ref attribute_store_set_node_attribute_value ++ * ++ * @param new_slots_year_day new value to set ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_set_unify_schedule_entry_lock_slots_year_day( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_slots_year_day ++ ); ++ ++/** ++ * @brief Undefines the Reported value of the the DotDot UnifyScheduleEntryLock - SlotsYearDay ++ * attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_slots_year_day_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Undefines the Desired value of the DotDot ++ * UnifyScheduleEntryLock - SlotsYearDay attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_slots_year_day_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the reported value is defined for the DotDot ++ * UnifyScheduleEntryLock - SlotsYearDay attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_slots_year_day_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the desired value is defined for the DotDot ++ * UnifyScheduleEntryLock - SlotsYearDay attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_slots_year_day_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Creates a DotDot UnifyScheduleEntryLock - SlotsYearDay attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_create_unify_schedule_entry_lock_slots_year_day( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++// UnifyScheduleEntryLock SignTZO ++/** ++ * @brief Verifies if the DotDot UnifyScheduleEntryLock - SignTZO is supported ++ * under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * ++ * @returns true if SignTZO is supported ++ * @returns false if SignTZO is not supported ++ */ ++bool dotdot_is_supported_unify_schedule_entry_lock_signtzo ( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Gets the DotDot UnifyScheduleEntryLock - SignTZO attribute value under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to get, ++ * see \ref attribute_store_get_node_attribute_value ++ * ++ * ++ * @returns SignTZO attribute ++ */ ++uint8_t dotdot_get_unify_schedule_entry_lock_signtzo( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state); ++ ++/** ++ * @brief Set the DotDot UnifyScheduleEntryLock - SignTZO attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to write for the node, ++ * see \ref attribute_store_set_node_attribute_value ++ * ++ * @param new_signtzo new value to set ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_set_unify_schedule_entry_lock_signtzo( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_signtzo ++ ); ++ ++/** ++ * @brief Undefines the Reported value of the the DotDot UnifyScheduleEntryLock - SignTZO ++ * attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_signtzo_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Undefines the Desired value of the DotDot ++ * UnifyScheduleEntryLock - SignTZO attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_signtzo_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the reported value is defined for the DotDot ++ * UnifyScheduleEntryLock - SignTZO attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_signtzo_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the desired value is defined for the DotDot ++ * UnifyScheduleEntryLock - SignTZO attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_signtzo_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Creates a DotDot UnifyScheduleEntryLock - SignTZO attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_create_unify_schedule_entry_lock_signtzo( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++// UnifyScheduleEntryLock HourTZO ++/** ++ * @brief Verifies if the DotDot UnifyScheduleEntryLock - HourTZO is supported ++ * under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * ++ * @returns true if HourTZO is supported ++ * @returns false if HourTZO is not supported ++ */ ++bool dotdot_is_supported_unify_schedule_entry_lock_hourtzo ( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Gets the DotDot UnifyScheduleEntryLock - HourTZO attribute value under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to get, ++ * see \ref attribute_store_get_node_attribute_value ++ * ++ * ++ * @returns HourTZO attribute ++ */ ++uint8_t dotdot_get_unify_schedule_entry_lock_hourtzo( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state); ++ ++/** ++ * @brief Set the DotDot UnifyScheduleEntryLock - HourTZO attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to write for the node, ++ * see \ref attribute_store_set_node_attribute_value ++ * ++ * @param new_hourtzo new value to set ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_set_unify_schedule_entry_lock_hourtzo( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_hourtzo ++ ); ++ ++/** ++ * @brief Undefines the Reported value of the the DotDot UnifyScheduleEntryLock - HourTZO ++ * attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_hourtzo_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Undefines the Desired value of the DotDot ++ * UnifyScheduleEntryLock - HourTZO attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_hourtzo_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the reported value is defined for the DotDot ++ * UnifyScheduleEntryLock - HourTZO attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_hourtzo_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the desired value is defined for the DotDot ++ * UnifyScheduleEntryLock - HourTZO attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_hourtzo_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Creates a DotDot UnifyScheduleEntryLock - HourTZO attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_create_unify_schedule_entry_lock_hourtzo( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++// UnifyScheduleEntryLock MinuteTZO ++/** ++ * @brief Verifies if the DotDot UnifyScheduleEntryLock - MinuteTZO is supported ++ * under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * ++ * @returns true if MinuteTZO is supported ++ * @returns false if MinuteTZO is not supported ++ */ ++bool dotdot_is_supported_unify_schedule_entry_lock_minutetzo ( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Gets the DotDot UnifyScheduleEntryLock - MinuteTZO attribute value under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to get, ++ * see \ref attribute_store_get_node_attribute_value ++ * ++ * ++ * @returns MinuteTZO attribute ++ */ ++uint8_t dotdot_get_unify_schedule_entry_lock_minutetzo( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state); ++ ++/** ++ * @brief Set the DotDot UnifyScheduleEntryLock - MinuteTZO attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to write for the node, ++ * see \ref attribute_store_set_node_attribute_value ++ * ++ * @param new_minutetzo new value to set ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_set_unify_schedule_entry_lock_minutetzo( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_minutetzo ++ ); ++ ++/** ++ * @brief Undefines the Reported value of the the DotDot UnifyScheduleEntryLock - MinuteTZO ++ * attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_minutetzo_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Undefines the Desired value of the DotDot ++ * UnifyScheduleEntryLock - MinuteTZO attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_minutetzo_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the reported value is defined for the DotDot ++ * UnifyScheduleEntryLock - MinuteTZO attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_minutetzo_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the desired value is defined for the DotDot ++ * UnifyScheduleEntryLock - MinuteTZO attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_minutetzo_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Creates a DotDot UnifyScheduleEntryLock - MinuteTZO attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_create_unify_schedule_entry_lock_minutetzo( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++// UnifyScheduleEntryLock DSTOffsetSign ++/** ++ * @brief Verifies if the DotDot UnifyScheduleEntryLock - DSTOffsetSign is supported ++ * under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * ++ * @returns true if DSTOffsetSign is supported ++ * @returns false if DSTOffsetSign is not supported ++ */ ++bool dotdot_is_supported_unify_schedule_entry_lock_dst_offset_sign ( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Gets the DotDot UnifyScheduleEntryLock - DSTOffsetSign attribute value under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to get, ++ * see \ref attribute_store_get_node_attribute_value ++ * ++ * ++ * @returns DSTOffsetSign attribute ++ */ ++uint8_t dotdot_get_unify_schedule_entry_lock_dst_offset_sign( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state); ++ ++/** ++ * @brief Set the DotDot UnifyScheduleEntryLock - DSTOffsetSign attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to write for the node, ++ * see \ref attribute_store_set_node_attribute_value ++ * ++ * @param new_dst_offset_sign new value to set ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_set_unify_schedule_entry_lock_dst_offset_sign( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_dst_offset_sign ++ ); ++ ++/** ++ * @brief Undefines the Reported value of the the DotDot UnifyScheduleEntryLock - DSTOffsetSign ++ * attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_dst_offset_sign_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Undefines the Desired value of the DotDot ++ * UnifyScheduleEntryLock - DSTOffsetSign attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_dst_offset_sign_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the reported value is defined for the DotDot ++ * UnifyScheduleEntryLock - DSTOffsetSign attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_dst_offset_sign_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the desired value is defined for the DotDot ++ * UnifyScheduleEntryLock - DSTOffsetSign attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_dst_offset_sign_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Creates a DotDot UnifyScheduleEntryLock - DSTOffsetSign attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_create_unify_schedule_entry_lock_dst_offset_sign( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++// UnifyScheduleEntryLock DSTOffsetMinute ++/** ++ * @brief Verifies if the DotDot UnifyScheduleEntryLock - DSTOffsetMinute is supported ++ * under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * ++ * @returns true if DSTOffsetMinute is supported ++ * @returns false if DSTOffsetMinute is not supported ++ */ ++bool dotdot_is_supported_unify_schedule_entry_lock_dst_offset_minute ( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Gets the DotDot UnifyScheduleEntryLock - DSTOffsetMinute attribute value under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to get, ++ * see \ref attribute_store_get_node_attribute_value ++ * ++ * ++ * @returns DSTOffsetMinute attribute ++ */ ++uint8_t dotdot_get_unify_schedule_entry_lock_dst_offset_minute( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state); ++ ++/** ++ * @brief Set the DotDot UnifyScheduleEntryLock - DSTOffsetMinute attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to write for the node, ++ * see \ref attribute_store_set_node_attribute_value ++ * ++ * @param new_dst_offset_minute new value to set ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_set_unify_schedule_entry_lock_dst_offset_minute( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_dst_offset_minute ++ ); ++ ++/** ++ * @brief Undefines the Reported value of the the DotDot UnifyScheduleEntryLock - DSTOffsetMinute ++ * attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_dst_offset_minute_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Undefines the Desired value of the DotDot ++ * UnifyScheduleEntryLock - DSTOffsetMinute attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_dst_offset_minute_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the reported value is defined for the DotDot ++ * UnifyScheduleEntryLock - DSTOffsetMinute attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_dst_offset_minute_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the desired value is defined for the DotDot ++ * UnifyScheduleEntryLock - DSTOffsetMinute attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_dst_offset_minute_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Creates a DotDot UnifyScheduleEntryLock - DSTOffsetMinute attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_create_unify_schedule_entry_lock_dst_offset_minute( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++// UnifyScheduleEntryLock NumberOfSlotsDailyRepeating ++/** ++ * @brief Verifies if the DotDot UnifyScheduleEntryLock - NumberOfSlotsDailyRepeating is supported ++ * under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * ++ * @returns true if NumberOfSlotsDailyRepeating is supported ++ * @returns false if NumberOfSlotsDailyRepeating is not supported ++ */ ++bool dotdot_is_supported_unify_schedule_entry_lock_number_of_slots_daily_repeating ( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Gets the DotDot UnifyScheduleEntryLock - NumberOfSlotsDailyRepeating attribute value under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to get, ++ * see \ref attribute_store_get_node_attribute_value ++ * ++ * ++ * @returns NumberOfSlotsDailyRepeating attribute ++ */ ++uint8_t dotdot_get_unify_schedule_entry_lock_number_of_slots_daily_repeating( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state); ++ ++/** ++ * @brief Set the DotDot UnifyScheduleEntryLock - NumberOfSlotsDailyRepeating attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @param value_state value state to write for the node, ++ * see \ref attribute_store_set_node_attribute_value ++ * ++ * @param new_number_of_slots_daily_repeating new value to set ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_set_unify_schedule_entry_lock_number_of_slots_daily_repeating( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_number_of_slots_daily_repeating ++ ); ++ ++/** ++ * @brief Undefines the Reported value of the the DotDot UnifyScheduleEntryLock - NumberOfSlotsDailyRepeating ++ * attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Undefines the Desired value of the DotDot ++ * UnifyScheduleEntryLock - NumberOfSlotsDailyRepeating attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the reported value is defined for the DotDot ++ * UnifyScheduleEntryLock - NumberOfSlotsDailyRepeating attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if the desired value is defined for the DotDot ++ * UnifyScheduleEntryLock - NumberOfSlotsDailyRepeating attribute under a UNID/EndpointID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if defined, false is undefined or non-existent ++ */ ++bool dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Creates a DotDot UnifyScheduleEntryLock - NumberOfSlotsDailyRepeating attribute under a UNID/EndpoinID ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns sl_status_t SL_STATUS_OK on success ++ */ ++sl_status_t dotdot_create_unify_schedule_entry_lock_number_of_slots_daily_repeating( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if a UNID/Endpoint supports any attribute for the UnifyScheduleEntryLock ++ * Cluster ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if at least 1 attribute in the Attribute Store, false otherwise ++ */ ++bool dotdot_is_any_unify_schedule_entry_lock_attribute_supported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ ++/** ++ * @brief Checks if a UNID/Endpoint supports any writable attribute for the ++ * UnifyScheduleEntryLock Cluster ++ * ++ * @param unid Node's UNID ++ * @param endpoint_id Endpoint ID ++ * @returns true if at least 1 writable attribute in the Attribute Store, false otherwise ++ */ ++bool dotdot_is_any_unify_schedule_entry_lock_writable_attribute_supported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id); ++ + //////////////////////////////////////////////////////////////////////////////// + // Start of cluster UnifyHumidityControl + //////////////////////////////////////////////////////////////////////////////// +diff --git a/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_defined_attribute_types.h b/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_defined_attribute_types.h +index 6150a9ae87..75ec8aaada 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_defined_attribute_types.h ++++ b/components/unify_dotdot_attribute_store/zap-generated/include/unify_dotdot_defined_attribute_types.h +@@ -784,6 +784,15 @@ DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_FAN_CONTROL_Z_WAVE_FAN_STATE , 0xfd14 + DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_THERMOSTAT_THERMOSTAT_MODE , 0xfd150001) + DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_THERMOSTAT_SUPPORTED_THERMOSTAT_MODE , 0xfd150002) + DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_THERMOSTAT_OPERATING_STATE , 0xfd150003) ++// Attribute Defines for UnifyScheduleEntryLock ++DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY , 0xfd210001) ++DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY , 0xfd210002) ++DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO , 0xfd210003) ++DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO , 0xfd210004) ++DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO , 0xfd210005) ++DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN , 0xfd210006) ++DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE , 0xfd210007) ++DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING , 0xfd210008) + // Attribute Defines for UnifyHumidityControl + DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_HUMIDITY_CONTROL_REPORTING_MODE , 0xfda00001) + DEFINE_ATTRIBUTE(DOTDOT_ATTRIBUTE_ID_UNIFY_HUMIDITY_CONTROL_SUPPORTED_REPORTING_MODE , 0xfda00002) +diff --git a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_attribute_publisher.cpp b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_attribute_publisher.cpp +index d208971476..5b2324063c 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_attribute_publisher.cpp ++++ b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_attribute_publisher.cpp +@@ -25624,6 +25624,375 @@ static void unify_thermostat_cluster_cluster_revision_callback( + } + + ++/** ++ * @brief Publishes the desired value of an updated attribute store node for ++ * the UnifyScheduleEntryLock cluster. ++ * @param updated_node Updated attribute store node ++ * @param change Type of change applied ++ */ ++static void unify_schedule_entry_lock_cluster_publish_desired_value_callback( ++ attribute_store_node_t updated_node, attribute_store_change_t change) ++{ ++ // clang-format on ++ if (false == is_publish_desired_attribute_values_to_mqtt_enabled()) { ++ return; ++ } ++ if (change == ATTRIBUTE_DELETED || change == ATTRIBUTE_CREATED) { ++ return; ++ } ++ // Scene exception: check that the attribute is not under the Scene Table extension, which is a config and not the node's state. ++ if (ATTRIBUTE_STORE_INVALID_NODE ++ != attribute_store_get_first_parent_with_type( ++ updated_node, ++ DOTDOT_ATTRIBUTE_ID_SCENES_SCENE_TABLE)) { ++ return; ++ } ++ ++ // Get the UNID and EndPoint, and prepare the basic topic ++ char unid[MAXIMUM_UNID_SIZE] = {}; ++ // clang-format off ++ // clang-format on ++ dotdot_endpoint_id_t endpoint_id = 0; ++ if (SL_STATUS_OK ++ != unify_dotdot_attributes_get_unid_endpoint()(updated_node, ++ unid, ++ &endpoint_id)) { ++ return; ++ } ++ // clang-format off ++ // clang-format on ++ ++ std::string base_topic = "ucl/by-unid/" + std::string(unid); ++ // clang-format off ++ base_topic += "/ep" + std::to_string(endpoint_id); ++ // clang-format on ++ ++ attribute_store_type_t type = attribute_store_get_node_type(updated_node); ++ if (type == ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE) { ++ sl_log_debug(LOG_TAG, ++ "Warning: Invalid type for Attribute ID %d, " ++ "this should not happen.", ++ updated_node); ++ return; ++ } ++ ++ // If the value got updated but both Reported and Desired undefined, we skip publication ++ if (false == attribute_store_is_reported_defined(updated_node) ++ && false == attribute_store_is_desired_defined(updated_node)) { ++ sl_log_debug(LOG_TAG, ++ "Reported/Desired values are undefined. " ++ "Skipping publication"); ++ return; ++ } ++ ++ // clang-format off ++ try { ++ attribute_store::attribute attr(updated_node); ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_slots_week_day_publish( ++ base_topic.c_str(), ++ static_cast(attr.desired_or_reported()), ++ UCL_MQTT_PUBLISH_TYPE_DESIRED); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_slots_year_day_publish( ++ base_topic.c_str(), ++ static_cast(attr.desired_or_reported()), ++ UCL_MQTT_PUBLISH_TYPE_DESIRED); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_signtzo_publish( ++ base_topic.c_str(), ++ static_cast(attr.desired_or_reported()), ++ UCL_MQTT_PUBLISH_TYPE_DESIRED); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_hourtzo_publish( ++ base_topic.c_str(), ++ static_cast(attr.desired_or_reported()), ++ UCL_MQTT_PUBLISH_TYPE_DESIRED); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_minutetzo_publish( ++ base_topic.c_str(), ++ static_cast(attr.desired_or_reported()), ++ UCL_MQTT_PUBLISH_TYPE_DESIRED); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_dst_offset_sign_publish( ++ base_topic.c_str(), ++ static_cast(attr.desired_or_reported()), ++ UCL_MQTT_PUBLISH_TYPE_DESIRED); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_dst_offset_minute_publish( ++ base_topic.c_str(), ++ static_cast(attr.desired_or_reported()), ++ UCL_MQTT_PUBLISH_TYPE_DESIRED); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_publish( ++ base_topic.c_str(), ++ static_cast(attr.desired_or_reported()), ++ UCL_MQTT_PUBLISH_TYPE_DESIRED); ++ return; ++ } ++ } catch (std::exception &ex) { ++ sl_log_warning(LOG_TAG, "Failed to publish the Desired attribute value: %s", ex.what()); ++ } ++} ++ ++/** ++ * @brief Publishes the reported value of an updated attribute store node for ++ * the UnifyScheduleEntryLock cluster. ++ * @param updated_node Updated attribute store node ++ * @param change Type of change applied ++ */ ++static void unify_schedule_entry_lock_cluster_publish_reported_value_callback( ++ attribute_store_node_t updated_node, attribute_store_change_t change) ++{ ++ // clang-format on ++ if (false == is_publish_reported_attribute_values_to_mqtt_enabled()) { ++ return; ++ } ++ if (change == ATTRIBUTE_CREATED) { ++ return; ++ } ++ // Scene exception: check that the attribute is not under the Scene Table extension, which is a config and not the node's state. ++ if (ATTRIBUTE_STORE_INVALID_NODE ++ != attribute_store_get_first_parent_with_type( ++ updated_node, ++ DOTDOT_ATTRIBUTE_ID_SCENES_SCENE_TABLE)) { ++ return; ++ } ++ ++ // Get the UNID and EndPoint, and prepare the basic topic ++ char unid[MAXIMUM_UNID_SIZE] = {}; ++ // clang-format off ++ // clang-format on ++ dotdot_endpoint_id_t endpoint_id = 0; ++ if (SL_STATUS_OK ++ != unify_dotdot_attributes_get_unid_endpoint()(updated_node, ++ unid, ++ &endpoint_id)) { ++ return; ++ } ++ // clang-format off ++ // clang-format on ++ ++ std::string base_topic = "ucl/by-unid/" + std::string(unid); ++ // clang-format off ++ base_topic += "/ep" + std::to_string(endpoint_id); ++ // clang-format on ++ ++ attribute_store_type_t type = attribute_store_get_node_type(updated_node); ++ if (type == ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE) { ++ sl_log_debug(LOG_TAG, ++ "Warning: Invalid type for Attribute ID %d, " ++ "this should not happen.", ++ updated_node); ++ return; ++ } ++ ++ // Deletion case: ++ if (change == ATTRIBUTE_DELETED) { ++ // clang-format off ++ switch(type) { ++ case DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY: ++ // clang-format on ++ sl_log_debug(LOG_TAG, ++ "Unretaining UnifyScheduleEntryLock::SlotsWeekDay under topic %s", ++ base_topic.c_str()); ++ // clang-format off ++ uic_mqtt_dotdot_unify_schedule_entry_lock_slots_week_day_unretain(base_topic.c_str(), UCL_MQTT_PUBLISH_TYPE_ALL); ++ break; ++ case DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY: ++ // clang-format on ++ sl_log_debug(LOG_TAG, ++ "Unretaining UnifyScheduleEntryLock::SlotsYearDay under topic %s", ++ base_topic.c_str()); ++ // clang-format off ++ uic_mqtt_dotdot_unify_schedule_entry_lock_slots_year_day_unretain(base_topic.c_str(), UCL_MQTT_PUBLISH_TYPE_ALL); ++ break; ++ case DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO: ++ // clang-format on ++ sl_log_debug(LOG_TAG, ++ "Unretaining UnifyScheduleEntryLock::SignTZO under topic %s", ++ base_topic.c_str()); ++ // clang-format off ++ uic_mqtt_dotdot_unify_schedule_entry_lock_signtzo_unretain(base_topic.c_str(), UCL_MQTT_PUBLISH_TYPE_ALL); ++ break; ++ case DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO: ++ // clang-format on ++ sl_log_debug(LOG_TAG, ++ "Unretaining UnifyScheduleEntryLock::HourTZO under topic %s", ++ base_topic.c_str()); ++ // clang-format off ++ uic_mqtt_dotdot_unify_schedule_entry_lock_hourtzo_unretain(base_topic.c_str(), UCL_MQTT_PUBLISH_TYPE_ALL); ++ break; ++ case DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO: ++ // clang-format on ++ sl_log_debug(LOG_TAG, ++ "Unretaining UnifyScheduleEntryLock::MinuteTZO under topic %s", ++ base_topic.c_str()); ++ // clang-format off ++ uic_mqtt_dotdot_unify_schedule_entry_lock_minutetzo_unretain(base_topic.c_str(), UCL_MQTT_PUBLISH_TYPE_ALL); ++ break; ++ case DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN: ++ // clang-format on ++ sl_log_debug(LOG_TAG, ++ "Unretaining UnifyScheduleEntryLock::DSTOffsetSign under topic %s", ++ base_topic.c_str()); ++ // clang-format off ++ uic_mqtt_dotdot_unify_schedule_entry_lock_dst_offset_sign_unretain(base_topic.c_str(), UCL_MQTT_PUBLISH_TYPE_ALL); ++ break; ++ case DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE: ++ // clang-format on ++ sl_log_debug(LOG_TAG, ++ "Unretaining UnifyScheduleEntryLock::DSTOffsetMinute under topic %s", ++ base_topic.c_str()); ++ // clang-format off ++ uic_mqtt_dotdot_unify_schedule_entry_lock_dst_offset_minute_unretain(base_topic.c_str(), UCL_MQTT_PUBLISH_TYPE_ALL); ++ break; ++ case DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING: ++ // clang-format on ++ sl_log_debug(LOG_TAG, ++ "Unretaining UnifyScheduleEntryLock::NumberOfSlotsDailyRepeating under topic %s", ++ base_topic.c_str()); ++ // clang-format off ++ uic_mqtt_dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_unretain(base_topic.c_str(), UCL_MQTT_PUBLISH_TYPE_ALL); ++ break; ++ default: ++ break; ++ } ++ // clang-format on ++ return; ++ } ++ ++ // If the value got updated but undefined, we skip publication ++ if (false == attribute_store_is_reported_defined(updated_node)) { ++ sl_log_debug(LOG_TAG, "Reported value is undefined. Skipping publication"); ++ return; ++ } ++ ++ // Else we assume update case: ++ // clang-format off ++ try { ++ attribute_store::attribute attr(updated_node); ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_slots_week_day_publish( ++ base_topic.c_str(), ++ static_cast(attr.reported()), ++ (attr.desired_exists() && !attribute_store_is_value_matched(updated_node)) ? UCL_MQTT_PUBLISH_TYPE_REPORTED : UCL_MQTT_PUBLISH_TYPE_ALL); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_slots_year_day_publish( ++ base_topic.c_str(), ++ static_cast(attr.reported()), ++ (attr.desired_exists() && !attribute_store_is_value_matched(updated_node)) ? UCL_MQTT_PUBLISH_TYPE_REPORTED : UCL_MQTT_PUBLISH_TYPE_ALL); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_signtzo_publish( ++ base_topic.c_str(), ++ static_cast(attr.reported()), ++ (attr.desired_exists() && !attribute_store_is_value_matched(updated_node)) ? UCL_MQTT_PUBLISH_TYPE_REPORTED : UCL_MQTT_PUBLISH_TYPE_ALL); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_hourtzo_publish( ++ base_topic.c_str(), ++ static_cast(attr.reported()), ++ (attr.desired_exists() && !attribute_store_is_value_matched(updated_node)) ? UCL_MQTT_PUBLISH_TYPE_REPORTED : UCL_MQTT_PUBLISH_TYPE_ALL); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_minutetzo_publish( ++ base_topic.c_str(), ++ static_cast(attr.reported()), ++ (attr.desired_exists() && !attribute_store_is_value_matched(updated_node)) ? UCL_MQTT_PUBLISH_TYPE_REPORTED : UCL_MQTT_PUBLISH_TYPE_ALL); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_dst_offset_sign_publish( ++ base_topic.c_str(), ++ static_cast(attr.reported()), ++ (attr.desired_exists() && !attribute_store_is_value_matched(updated_node)) ? UCL_MQTT_PUBLISH_TYPE_REPORTED : UCL_MQTT_PUBLISH_TYPE_ALL); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_dst_offset_minute_publish( ++ base_topic.c_str(), ++ static_cast(attr.reported()), ++ (attr.desired_exists() && !attribute_store_is_value_matched(updated_node)) ? UCL_MQTT_PUBLISH_TYPE_REPORTED : UCL_MQTT_PUBLISH_TYPE_ALL); ++ return; ++ } ++ if (type == DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_publish( ++ base_topic.c_str(), ++ static_cast(attr.reported()), ++ (attr.desired_exists() && !attribute_store_is_value_matched(updated_node)) ? UCL_MQTT_PUBLISH_TYPE_REPORTED : UCL_MQTT_PUBLISH_TYPE_ALL); ++ return; ++ } ++ } catch (std::exception &ex) { ++ sl_log_warning(LOG_TAG, "Failed to publish the Reported attribute value: %s", ex.what()); ++ } ++} ++ ++static void unify_schedule_entry_lock_cluster_cluster_revision_callback( ++ attribute_store_node_t updated_node, attribute_store_change_t change) ++{ ++ // clang-format on ++ if (false == is_publish_reported_attribute_values_to_mqtt_enabled()) { ++ return; ++ } ++ ++ // Get the UNID and EndPoint, and prepare the basic topic ++ char unid[MAXIMUM_UNID_SIZE] = {}; ++ dotdot_endpoint_id_t endpoint_id = 0; ++ // clang-format off ++ // clang-format on ++ if (SL_STATUS_OK ++ != unify_dotdot_attributes_get_unid_endpoint()(updated_node, ++ unid, ++ &endpoint_id)) { ++ return; ++ } ++ // clang-format off ++ // clang-format on ++ ++ std::string base_topic = "ucl/by-unid/" + std::string(unid); ++ // clang-format off ++ base_topic += "/ep" + std::to_string(endpoint_id); ++ ++ if ((change == ATTRIBUTE_CREATED) || (change == ATTRIBUTE_UPDATED)) { ++ // On attribute creation, make sure to publish the attribute revision for the first time ++ std::string cluster_revision_topic = base_topic + "/UnifyScheduleEntryLock/Attributes/ClusterRevision"; ++ if (uic_mqtt_count_topics(cluster_revision_topic.c_str()) == 0) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_publish_cluster_revision(base_topic.c_str(), 1); ++ } ++ } ++ ++ if (change == ATTRIBUTE_DELETED) { ++ // Check if we just erased the last attribute under a cluster, if yes, unretain ++ // the Cluster revision too. ++ if (false == dotdot_is_any_unify_schedule_entry_lock_attribute_supported(unid, endpoint_id)) { ++ base_topic += "/UnifyScheduleEntryLock"; ++ sl_log_debug(LOG_TAG, "No more attributes supported for UnifyScheduleEntryLock cluster for UNID %s Endpoint %d. Unretaining leftover topics at %s",unid, endpoint_id, base_topic.c_str()); ++ uic_mqtt_unretain(base_topic.c_str()); ++ } ++ } ++} ++ ++ + /** + * @brief Publishes the desired value of an updated attribute store node for + * the UnifyHumidityControl cluster. +@@ -36124,6 +36493,118 @@ sl_status_t unify_dotdot_attribute_store_attribute_publisher_init() + unify_thermostat_cluster_cluster_revision_callback, + DOTDOT_ATTRIBUTE_ID_UNIFY_THERMOSTAT_OPERATING_STATE); + //Desired attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_desired_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY, ++ DESIRED_ATTRIBUTE); ++ //Reported attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_reported_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY, ++ REPORTED_ATTRIBUTE); ++ //registering a callback when an attribute is created for publishing cluster revision ++ attribute_store_register_callback_by_type( ++ unify_schedule_entry_lock_cluster_cluster_revision_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY); ++ //Desired attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_desired_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY, ++ DESIRED_ATTRIBUTE); ++ //Reported attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_reported_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY, ++ REPORTED_ATTRIBUTE); ++ //registering a callback when an attribute is created for publishing cluster revision ++ attribute_store_register_callback_by_type( ++ unify_schedule_entry_lock_cluster_cluster_revision_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY); ++ //Desired attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_desired_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO, ++ DESIRED_ATTRIBUTE); ++ //Reported attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_reported_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO, ++ REPORTED_ATTRIBUTE); ++ //registering a callback when an attribute is created for publishing cluster revision ++ attribute_store_register_callback_by_type( ++ unify_schedule_entry_lock_cluster_cluster_revision_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO); ++ //Desired attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_desired_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO, ++ DESIRED_ATTRIBUTE); ++ //Reported attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_reported_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO, ++ REPORTED_ATTRIBUTE); ++ //registering a callback when an attribute is created for publishing cluster revision ++ attribute_store_register_callback_by_type( ++ unify_schedule_entry_lock_cluster_cluster_revision_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO); ++ //Desired attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_desired_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO, ++ DESIRED_ATTRIBUTE); ++ //Reported attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_reported_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO, ++ REPORTED_ATTRIBUTE); ++ //registering a callback when an attribute is created for publishing cluster revision ++ attribute_store_register_callback_by_type( ++ unify_schedule_entry_lock_cluster_cluster_revision_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO); ++ //Desired attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_desired_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN, ++ DESIRED_ATTRIBUTE); ++ //Reported attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_reported_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN, ++ REPORTED_ATTRIBUTE); ++ //registering a callback when an attribute is created for publishing cluster revision ++ attribute_store_register_callback_by_type( ++ unify_schedule_entry_lock_cluster_cluster_revision_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN); ++ //Desired attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_desired_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE, ++ DESIRED_ATTRIBUTE); ++ //Reported attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_reported_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE, ++ REPORTED_ATTRIBUTE); ++ //registering a callback when an attribute is created for publishing cluster revision ++ attribute_store_register_callback_by_type( ++ unify_schedule_entry_lock_cluster_cluster_revision_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE); ++ //Desired attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_desired_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING, ++ DESIRED_ATTRIBUTE); ++ //Reported attribute state ++ attribute_store_register_callback_by_type_and_state( ++ unify_schedule_entry_lock_cluster_publish_reported_value_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING, ++ REPORTED_ATTRIBUTE); ++ //registering a callback when an attribute is created for publishing cluster revision ++ attribute_store_register_callback_by_type( ++ unify_schedule_entry_lock_cluster_cluster_revision_callback, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING); ++ //Desired attribute state + attribute_store_register_callback_by_type_and_state( + unify_humidity_control_cluster_publish_desired_value_callback, + DOTDOT_ATTRIBUTE_ID_UNIFY_HUMIDITY_CONTROL_REPORTING_MODE, +diff --git a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_force_read_attributes_command_callbacks.c b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_force_read_attributes_command_callbacks.c +index 9774152fb6..a114ce59bd 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_force_read_attributes_command_callbacks.c ++++ b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_force_read_attributes_command_callbacks.c +@@ -4470,6 +4470,71 @@ static sl_status_t uic_mqtt_dotdot_unify_thermostat_force_read_attributes_callba + return SL_STATUS_OK; + } + //////////////////////////////////////////////////////////////////////////////// ++// Start of cluster UnifyScheduleEntryLock ++//////////////////////////////////////////////////////////////////////////////// ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback ( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t attribute_list) { ++ ++ if (false == is_force_read_attributes_enabled()){ ++ return SL_STATUS_FAIL; ++ } ++ ++ if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { ++ if (is_automatic_deduction_of_supported_commands_enabled()) { ++ return dotdot_is_any_unify_schedule_entry_lock_attribute_supported(unid, endpoint_id) ? ++ SL_STATUS_OK : SL_STATUS_FAIL; ++ } else { ++ return SL_STATUS_FAIL; ++ } ++ } ++ ++ // Go and undefine everything that needs to be read again: ++ if (true == attribute_list.slots_week_day) { ++ if (SL_STATUS_OK == dotdot_unify_schedule_entry_lock_slots_week_day_undefine_reported(unid, endpoint_id)) { ++ sl_log_debug(LOG_TAG, "Undefined Reported value of UnifyScheduleEntryLock::SlotsWeekDay under %s - Endpoint %d", unid, endpoint_id); ++ } ++ } ++ if (true == attribute_list.slots_year_day) { ++ if (SL_STATUS_OK == dotdot_unify_schedule_entry_lock_slots_year_day_undefine_reported(unid, endpoint_id)) { ++ sl_log_debug(LOG_TAG, "Undefined Reported value of UnifyScheduleEntryLock::SlotsYearDay under %s - Endpoint %d", unid, endpoint_id); ++ } ++ } ++ if (true == attribute_list.signtzo) { ++ if (SL_STATUS_OK == dotdot_unify_schedule_entry_lock_signtzo_undefine_reported(unid, endpoint_id)) { ++ sl_log_debug(LOG_TAG, "Undefined Reported value of UnifyScheduleEntryLock::SignTZO under %s - Endpoint %d", unid, endpoint_id); ++ } ++ } ++ if (true == attribute_list.hourtzo) { ++ if (SL_STATUS_OK == dotdot_unify_schedule_entry_lock_hourtzo_undefine_reported(unid, endpoint_id)) { ++ sl_log_debug(LOG_TAG, "Undefined Reported value of UnifyScheduleEntryLock::HourTZO under %s - Endpoint %d", unid, endpoint_id); ++ } ++ } ++ if (true == attribute_list.minutetzo) { ++ if (SL_STATUS_OK == dotdot_unify_schedule_entry_lock_minutetzo_undefine_reported(unid, endpoint_id)) { ++ sl_log_debug(LOG_TAG, "Undefined Reported value of UnifyScheduleEntryLock::MinuteTZO under %s - Endpoint %d", unid, endpoint_id); ++ } ++ } ++ if (true == attribute_list.dst_offset_sign) { ++ if (SL_STATUS_OK == dotdot_unify_schedule_entry_lock_dst_offset_sign_undefine_reported(unid, endpoint_id)) { ++ sl_log_debug(LOG_TAG, "Undefined Reported value of UnifyScheduleEntryLock::DSTOffsetSign under %s - Endpoint %d", unid, endpoint_id); ++ } ++ } ++ if (true == attribute_list.dst_offset_minute) { ++ if (SL_STATUS_OK == dotdot_unify_schedule_entry_lock_dst_offset_minute_undefine_reported(unid, endpoint_id)) { ++ sl_log_debug(LOG_TAG, "Undefined Reported value of UnifyScheduleEntryLock::DSTOffsetMinute under %s - Endpoint %d", unid, endpoint_id); ++ } ++ } ++ if (true == attribute_list.number_of_slots_daily_repeating) { ++ if (SL_STATUS_OK == dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_undefine_reported(unid, endpoint_id)) { ++ sl_log_debug(LOG_TAG, "Undefined Reported value of UnifyScheduleEntryLock::NumberOfSlotsDailyRepeating under %s - Endpoint %d", unid, endpoint_id); ++ } ++ } ++ return SL_STATUS_OK; ++} ++//////////////////////////////////////////////////////////////////////////////// + // Start of cluster UnifyHumidityControl + //////////////////////////////////////////////////////////////////////////////// + static sl_status_t uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback ( +@@ -4701,6 +4766,8 @@ sl_status_t + + uic_mqtt_dotdot_set_unify_thermostat_force_read_attributes_callback(&uic_mqtt_dotdot_unify_thermostat_force_read_attributes_callback); + ++ uic_mqtt_dotdot_set_unify_schedule_entry_lock_force_read_attributes_callback(&uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback); ++ + uic_mqtt_dotdot_set_unify_humidity_control_force_read_attributes_callback(&uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback); + + // clang-format on +diff --git a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_helpers.cpp b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_helpers.cpp +index 95fffa41fc..13bc62892f 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_helpers.cpp ++++ b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_helpers.cpp +@@ -82302,6 +82302,961 @@ bool dotdot_is_any_unify_thermostat_writable_attribute_supported( + return false; + } + //////////////////////////////////////////////////////////////////////////////// ++// Start of cluster UnifyScheduleEntryLock ++//////////////////////////////////////////////////////////////////////////////// ++bool dotdot_is_supported_unify_schedule_entry_lock_slots_week_day( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY); ++ return attribute_store_node_exists(node); ++} ++ ++uint8_t dotdot_get_unify_schedule_entry_lock_slots_week_day( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY); ++ ++ uint8_t result = {}; ++ attribute_store_read_value(node, ++ value_state, ++ (uint8_t *)&result, ++ sizeof(result)); ++ return result; ++} ++ ++sl_status_t dotdot_set_unify_schedule_entry_lock_slots_week_day( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_slots_week_day ++ ) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY); ++ ++ return attribute_store_set_node_attribute_value(node, ++ value_state, ++ (uint8_t *)&new_slots_week_day, ++ sizeof(uint8_t)); ++ } ++ ++sl_status_t dotdot_unify_schedule_entry_lock_slots_week_day_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY); ++ attribute_store_undefine_reported(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++sl_status_t dotdot_unify_schedule_entry_lock_slots_week_day_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY); ++ attribute_store_undefine_desired(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++ ++bool dotdot_unify_schedule_entry_lock_slots_week_day_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY); ++ return attribute_store_is_reported_defined(node); ++} ++ ++bool dotdot_unify_schedule_entry_lock_slots_week_day_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY); ++ return attribute_store_is_desired_defined(node); ++} ++ ++sl_status_t dotdot_create_unify_schedule_entry_lock_slots_week_day( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node = ++ attribute_store_create_child_if_missing(endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY); ++ ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++bool dotdot_is_supported_unify_schedule_entry_lock_slots_year_day( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY); ++ return attribute_store_node_exists(node); ++} ++ ++uint8_t dotdot_get_unify_schedule_entry_lock_slots_year_day( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY); ++ ++ uint8_t result = {}; ++ attribute_store_read_value(node, ++ value_state, ++ (uint8_t *)&result, ++ sizeof(result)); ++ return result; ++} ++ ++sl_status_t dotdot_set_unify_schedule_entry_lock_slots_year_day( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_slots_year_day ++ ) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY); ++ ++ return attribute_store_set_node_attribute_value(node, ++ value_state, ++ (uint8_t *)&new_slots_year_day, ++ sizeof(uint8_t)); ++ } ++ ++sl_status_t dotdot_unify_schedule_entry_lock_slots_year_day_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY); ++ attribute_store_undefine_reported(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++sl_status_t dotdot_unify_schedule_entry_lock_slots_year_day_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY); ++ attribute_store_undefine_desired(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++ ++bool dotdot_unify_schedule_entry_lock_slots_year_day_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY); ++ return attribute_store_is_reported_defined(node); ++} ++ ++bool dotdot_unify_schedule_entry_lock_slots_year_day_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY); ++ return attribute_store_is_desired_defined(node); ++} ++ ++sl_status_t dotdot_create_unify_schedule_entry_lock_slots_year_day( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node = ++ attribute_store_create_child_if_missing(endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY); ++ ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++bool dotdot_is_supported_unify_schedule_entry_lock_signtzo( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO); ++ return attribute_store_node_exists(node); ++} ++ ++uint8_t dotdot_get_unify_schedule_entry_lock_signtzo( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO); ++ ++ uint8_t result = {}; ++ attribute_store_read_value(node, ++ value_state, ++ (uint8_t *)&result, ++ sizeof(result)); ++ return result; ++} ++ ++sl_status_t dotdot_set_unify_schedule_entry_lock_signtzo( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_signtzo ++ ) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO); ++ ++ return attribute_store_set_node_attribute_value(node, ++ value_state, ++ (uint8_t *)&new_signtzo, ++ sizeof(uint8_t)); ++ } ++ ++sl_status_t dotdot_unify_schedule_entry_lock_signtzo_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO); ++ attribute_store_undefine_reported(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++sl_status_t dotdot_unify_schedule_entry_lock_signtzo_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO); ++ attribute_store_undefine_desired(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++ ++bool dotdot_unify_schedule_entry_lock_signtzo_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO); ++ return attribute_store_is_reported_defined(node); ++} ++ ++bool dotdot_unify_schedule_entry_lock_signtzo_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO); ++ return attribute_store_is_desired_defined(node); ++} ++ ++sl_status_t dotdot_create_unify_schedule_entry_lock_signtzo( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node = ++ attribute_store_create_child_if_missing(endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO); ++ ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++bool dotdot_is_supported_unify_schedule_entry_lock_hourtzo( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO); ++ return attribute_store_node_exists(node); ++} ++ ++uint8_t dotdot_get_unify_schedule_entry_lock_hourtzo( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO); ++ ++ uint8_t result = {}; ++ attribute_store_read_value(node, ++ value_state, ++ (uint8_t *)&result, ++ sizeof(result)); ++ return result; ++} ++ ++sl_status_t dotdot_set_unify_schedule_entry_lock_hourtzo( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_hourtzo ++ ) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO); ++ ++ return attribute_store_set_node_attribute_value(node, ++ value_state, ++ (uint8_t *)&new_hourtzo, ++ sizeof(uint8_t)); ++ } ++ ++sl_status_t dotdot_unify_schedule_entry_lock_hourtzo_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO); ++ attribute_store_undefine_reported(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++sl_status_t dotdot_unify_schedule_entry_lock_hourtzo_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO); ++ attribute_store_undefine_desired(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++ ++bool dotdot_unify_schedule_entry_lock_hourtzo_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO); ++ return attribute_store_is_reported_defined(node); ++} ++ ++bool dotdot_unify_schedule_entry_lock_hourtzo_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO); ++ return attribute_store_is_desired_defined(node); ++} ++ ++sl_status_t dotdot_create_unify_schedule_entry_lock_hourtzo( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node = ++ attribute_store_create_child_if_missing(endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO); ++ ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++bool dotdot_is_supported_unify_schedule_entry_lock_minutetzo( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO); ++ return attribute_store_node_exists(node); ++} ++ ++uint8_t dotdot_get_unify_schedule_entry_lock_minutetzo( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO); ++ ++ uint8_t result = {}; ++ attribute_store_read_value(node, ++ value_state, ++ (uint8_t *)&result, ++ sizeof(result)); ++ return result; ++} ++ ++sl_status_t dotdot_set_unify_schedule_entry_lock_minutetzo( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_minutetzo ++ ) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO); ++ ++ return attribute_store_set_node_attribute_value(node, ++ value_state, ++ (uint8_t *)&new_minutetzo, ++ sizeof(uint8_t)); ++ } ++ ++sl_status_t dotdot_unify_schedule_entry_lock_minutetzo_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO); ++ attribute_store_undefine_reported(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++sl_status_t dotdot_unify_schedule_entry_lock_minutetzo_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO); ++ attribute_store_undefine_desired(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++ ++bool dotdot_unify_schedule_entry_lock_minutetzo_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO); ++ return attribute_store_is_reported_defined(node); ++} ++ ++bool dotdot_unify_schedule_entry_lock_minutetzo_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO); ++ return attribute_store_is_desired_defined(node); ++} ++ ++sl_status_t dotdot_create_unify_schedule_entry_lock_minutetzo( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node = ++ attribute_store_create_child_if_missing(endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO); ++ ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++bool dotdot_is_supported_unify_schedule_entry_lock_dst_offset_sign( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN); ++ return attribute_store_node_exists(node); ++} ++ ++uint8_t dotdot_get_unify_schedule_entry_lock_dst_offset_sign( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN); ++ ++ uint8_t result = {}; ++ attribute_store_read_value(node, ++ value_state, ++ (uint8_t *)&result, ++ sizeof(result)); ++ return result; ++} ++ ++sl_status_t dotdot_set_unify_schedule_entry_lock_dst_offset_sign( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_dst_offset_sign ++ ) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN); ++ ++ return attribute_store_set_node_attribute_value(node, ++ value_state, ++ (uint8_t *)&new_dst_offset_sign, ++ sizeof(uint8_t)); ++ } ++ ++sl_status_t dotdot_unify_schedule_entry_lock_dst_offset_sign_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN); ++ attribute_store_undefine_reported(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++sl_status_t dotdot_unify_schedule_entry_lock_dst_offset_sign_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN); ++ attribute_store_undefine_desired(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++ ++bool dotdot_unify_schedule_entry_lock_dst_offset_sign_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN); ++ return attribute_store_is_reported_defined(node); ++} ++ ++bool dotdot_unify_schedule_entry_lock_dst_offset_sign_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN); ++ return attribute_store_is_desired_defined(node); ++} ++ ++sl_status_t dotdot_create_unify_schedule_entry_lock_dst_offset_sign( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node = ++ attribute_store_create_child_if_missing(endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN); ++ ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++bool dotdot_is_supported_unify_schedule_entry_lock_dst_offset_minute( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE); ++ return attribute_store_node_exists(node); ++} ++ ++uint8_t dotdot_get_unify_schedule_entry_lock_dst_offset_minute( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE); ++ ++ uint8_t result = {}; ++ attribute_store_read_value(node, ++ value_state, ++ (uint8_t *)&result, ++ sizeof(result)); ++ return result; ++} ++ ++sl_status_t dotdot_set_unify_schedule_entry_lock_dst_offset_minute( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_dst_offset_minute ++ ) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE); ++ ++ return attribute_store_set_node_attribute_value(node, ++ value_state, ++ (uint8_t *)&new_dst_offset_minute, ++ sizeof(uint8_t)); ++ } ++ ++sl_status_t dotdot_unify_schedule_entry_lock_dst_offset_minute_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE); ++ attribute_store_undefine_reported(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++sl_status_t dotdot_unify_schedule_entry_lock_dst_offset_minute_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE); ++ attribute_store_undefine_desired(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++ ++bool dotdot_unify_schedule_entry_lock_dst_offset_minute_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE); ++ return attribute_store_is_reported_defined(node); ++} ++ ++bool dotdot_unify_schedule_entry_lock_dst_offset_minute_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE); ++ return attribute_store_is_desired_defined(node); ++} ++ ++sl_status_t dotdot_create_unify_schedule_entry_lock_dst_offset_minute( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node = ++ attribute_store_create_child_if_missing(endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE); ++ ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++bool dotdot_is_supported_unify_schedule_entry_lock_number_of_slots_daily_repeating( ++ const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING); ++ return attribute_store_node_exists(node); ++} ++ ++uint8_t dotdot_get_unify_schedule_entry_lock_number_of_slots_daily_repeating( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING); ++ ++ uint8_t result = {}; ++ attribute_store_read_value(node, ++ value_state, ++ (uint8_t *)&result, ++ sizeof(result)); ++ return result; ++} ++ ++sl_status_t dotdot_set_unify_schedule_entry_lock_number_of_slots_daily_repeating( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ attribute_store_node_value_state_t value_state, ++ uint8_t new_number_of_slots_daily_repeating ++ ) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING); ++ ++ return attribute_store_set_node_attribute_value(node, ++ value_state, ++ (uint8_t *)&new_number_of_slots_daily_repeating, ++ sizeof(uint8_t)); ++ } ++ ++sl_status_t dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_undefine_reported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING); ++ attribute_store_undefine_reported(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++sl_status_t dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_undefine_desired( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING); ++ attribute_store_undefine_desired(node); ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++ ++bool dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_is_reported_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING); ++ return attribute_store_is_reported_defined(node); ++} ++ ++bool dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_is_desired_defined( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) ++{ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node ++ = attribute_store_get_first_child_by_type( ++ endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING); ++ return attribute_store_is_desired_defined(node); ++} ++ ++sl_status_t dotdot_create_unify_schedule_entry_lock_number_of_slots_daily_repeating( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ attribute_store_node_t endpoint_node = unify_dotdot_attributes_get_endpoint_node()(unid, endpoint_id); ++ attribute_store_node_t node = ++ attribute_store_create_child_if_missing(endpoint_node, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING); ++ ++ return (node != ATTRIBUTE_STORE_INVALID_NODE) ? SL_STATUS_OK : SL_STATUS_FAIL; ++} ++ ++bool dotdot_is_any_unify_schedule_entry_lock_attribute_supported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_slots_week_day(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_slots_year_day(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_signtzo(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_hourtzo(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_minutetzo(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_dst_offset_sign(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_dst_offset_minute(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_number_of_slots_daily_repeating(unid, endpoint_id)) { ++ return true; ++ } ++ ++ return false; ++} ++ ++bool dotdot_is_any_unify_schedule_entry_lock_writable_attribute_supported( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint_id) { ++ ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_slots_week_day(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_slots_year_day(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_signtzo(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_hourtzo(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_minutetzo(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_dst_offset_sign(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_dst_offset_minute(unid, endpoint_id)) { ++ return true; ++ } ++ if (true == dotdot_is_supported_unify_schedule_entry_lock_number_of_slots_daily_repeating(unid, endpoint_id)) { ++ return true; ++ } ++ ++ return false; ++} ++//////////////////////////////////////////////////////////////////////////////// + // Start of cluster UnifyHumidityControl + //////////////////////////////////////////////////////////////////////////////// + bool dotdot_is_supported_unify_humidity_control_reporting_mode( +diff --git a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_registration.cpp b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_registration.cpp +index bbc56dd97a..9a62d6f406 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_registration.cpp ++++ b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_registration.cpp +@@ -17047,6 +17047,198 @@ sl_status_t unify_dotdot_attribute_store_registration_init() + // clang-format off + // clang-format on + ++ { ++ // uint8 // uint8 // uint8_t ++ std::string attribute_type_string = "uint8_t"; ++ attribute_store_storage_type_t storage_type = UNKNOWN_STORAGE_TYPE; ++ ++ // clang-format off ++ storage_type = attribute_storage_type_conversion(attribute_type_string); ++ ++ if (storage_type == UNKNOWN_STORAGE_TYPE) { ++ sl_log_warning(LOG_TAG, ++ "Unkown storage type for ZCL UnifyScheduleEntryLock SlotsWeekDay, " ++ "type: uint8 // uint8_t"); ++ } ++ ++ status |= attribute_store_register_type( ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY, ++ "ZCL UnifyScheduleEntryLock SlotsWeekDay", ++ ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE, ++ storage_type); ++ } ++ ++ // clang-format off ++ // clang-format on ++ ++ { ++ // uint8 // uint8 // uint8_t ++ std::string attribute_type_string = "uint8_t"; ++ attribute_store_storage_type_t storage_type = UNKNOWN_STORAGE_TYPE; ++ ++ // clang-format off ++ storage_type = attribute_storage_type_conversion(attribute_type_string); ++ ++ if (storage_type == UNKNOWN_STORAGE_TYPE) { ++ sl_log_warning(LOG_TAG, ++ "Unkown storage type for ZCL UnifyScheduleEntryLock SlotsYearDay, " ++ "type: uint8 // uint8_t"); ++ } ++ ++ status |= attribute_store_register_type( ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY, ++ "ZCL UnifyScheduleEntryLock SlotsYearDay", ++ ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE, ++ storage_type); ++ } ++ ++ // clang-format off ++ // clang-format on ++ ++ { ++ // uint8 // uint8 // uint8_t ++ std::string attribute_type_string = "uint8_t"; ++ attribute_store_storage_type_t storage_type = UNKNOWN_STORAGE_TYPE; ++ ++ // clang-format off ++ storage_type = attribute_storage_type_conversion(attribute_type_string); ++ ++ if (storage_type == UNKNOWN_STORAGE_TYPE) { ++ sl_log_warning(LOG_TAG, ++ "Unkown storage type for ZCL UnifyScheduleEntryLock SignTZO, " ++ "type: uint8 // uint8_t"); ++ } ++ ++ status |= attribute_store_register_type( ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO, ++ "ZCL UnifyScheduleEntryLock SignTZO", ++ ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE, ++ storage_type); ++ } ++ ++ // clang-format off ++ // clang-format on ++ ++ { ++ // uint8 // uint8 // uint8_t ++ std::string attribute_type_string = "uint8_t"; ++ attribute_store_storage_type_t storage_type = UNKNOWN_STORAGE_TYPE; ++ ++ // clang-format off ++ storage_type = attribute_storage_type_conversion(attribute_type_string); ++ ++ if (storage_type == UNKNOWN_STORAGE_TYPE) { ++ sl_log_warning(LOG_TAG, ++ "Unkown storage type for ZCL UnifyScheduleEntryLock HourTZO, " ++ "type: uint8 // uint8_t"); ++ } ++ ++ status |= attribute_store_register_type( ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO, ++ "ZCL UnifyScheduleEntryLock HourTZO", ++ ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE, ++ storage_type); ++ } ++ ++ // clang-format off ++ // clang-format on ++ ++ { ++ // uint8 // uint8 // uint8_t ++ std::string attribute_type_string = "uint8_t"; ++ attribute_store_storage_type_t storage_type = UNKNOWN_STORAGE_TYPE; ++ ++ // clang-format off ++ storage_type = attribute_storage_type_conversion(attribute_type_string); ++ ++ if (storage_type == UNKNOWN_STORAGE_TYPE) { ++ sl_log_warning(LOG_TAG, ++ "Unkown storage type for ZCL UnifyScheduleEntryLock MinuteTZO, " ++ "type: uint8 // uint8_t"); ++ } ++ ++ status |= attribute_store_register_type( ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO, ++ "ZCL UnifyScheduleEntryLock MinuteTZO", ++ ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE, ++ storage_type); ++ } ++ ++ // clang-format off ++ // clang-format on ++ ++ { ++ // uint8 // uint8 // uint8_t ++ std::string attribute_type_string = "uint8_t"; ++ attribute_store_storage_type_t storage_type = UNKNOWN_STORAGE_TYPE; ++ ++ // clang-format off ++ storage_type = attribute_storage_type_conversion(attribute_type_string); ++ ++ if (storage_type == UNKNOWN_STORAGE_TYPE) { ++ sl_log_warning(LOG_TAG, ++ "Unkown storage type for ZCL UnifyScheduleEntryLock DSTOffsetSign, " ++ "type: uint8 // uint8_t"); ++ } ++ ++ status |= attribute_store_register_type( ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN, ++ "ZCL UnifyScheduleEntryLock DSTOffsetSign", ++ ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE, ++ storage_type); ++ } ++ ++ // clang-format off ++ // clang-format on ++ ++ { ++ // uint8 // uint8 // uint8_t ++ std::string attribute_type_string = "uint8_t"; ++ attribute_store_storage_type_t storage_type = UNKNOWN_STORAGE_TYPE; ++ ++ // clang-format off ++ storage_type = attribute_storage_type_conversion(attribute_type_string); ++ ++ if (storage_type == UNKNOWN_STORAGE_TYPE) { ++ sl_log_warning(LOG_TAG, ++ "Unkown storage type for ZCL UnifyScheduleEntryLock DSTOffsetMinute, " ++ "type: uint8 // uint8_t"); ++ } ++ ++ status |= attribute_store_register_type( ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE, ++ "ZCL UnifyScheduleEntryLock DSTOffsetMinute", ++ ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE, ++ storage_type); ++ } ++ ++ // clang-format off ++ // clang-format on ++ ++ { ++ // uint8 // uint8 // uint8_t ++ std::string attribute_type_string = "uint8_t"; ++ attribute_store_storage_type_t storage_type = UNKNOWN_STORAGE_TYPE; ++ ++ // clang-format off ++ storage_type = attribute_storage_type_conversion(attribute_type_string); ++ ++ if (storage_type == UNKNOWN_STORAGE_TYPE) { ++ sl_log_warning(LOG_TAG, ++ "Unkown storage type for ZCL UnifyScheduleEntryLock NumberOfSlotsDailyRepeating, " ++ "type: uint8 // uint8_t"); ++ } ++ ++ status |= attribute_store_register_type( ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING, ++ "ZCL UnifyScheduleEntryLock NumberOfSlotsDailyRepeating", ++ ATTRIBUTE_STORE_INVALID_ATTRIBUTE_TYPE, ++ storage_type); ++ } ++ ++ // clang-format off ++ // clang-format on ++ + { + // ModeType // ModeType // ModeType + std::string attribute_type_string = "ModeType"; +diff --git a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_write_attributes_command_callbacks.c b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_write_attributes_command_callbacks.c +index 0eb24791b3..a3b12da1ea 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_write_attributes_command_callbacks.c ++++ b/components/unify_dotdot_attribute_store/zap-generated/src/unify_dotdot_attribute_store_write_attributes_command_callbacks.c +@@ -2556,6 +2556,68 @@ static sl_status_t unify_thermostat_cluster_write_attributes_callback( + return SL_STATUS_OK; + } + //////////////////////////////////////////////////////////////////////////////// ++// Start of cluster UnifyScheduleEntryLock ++//////////////////////////////////////////////////////////////////////////////// ++// WriteAttribute Callbacks unify_schedule_entry_lock ++static sl_status_t unify_schedule_entry_lock_cluster_write_attributes_callback( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_state_t attributes, ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t updated_attributes) ++{ ++ if (false == is_write_attributes_enabled()) { ++ return SL_STATUS_FAIL; ++ } ++ ++ if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { ++ if (is_automatic_deduction_of_supported_commands_enabled()) { ++ return dotdot_is_any_unify_schedule_entry_lock_writable_attribute_supported(unid, endpoint_id) ? ++ SL_STATUS_OK : SL_STATUS_FAIL; ++ } else { ++ return SL_STATUS_FAIL; ++ } ++ } ++ ++ sl_log_debug(LOG_TAG, ++ "unify_schedule_entry_lock: Incoming WriteAttributes command for %s, endpoint %d.\n", ++ unid, ++ endpoint_id); ++ if (true == updated_attributes.slots_week_day) { ++ sl_log_debug(LOG_TAG, "Updating desired value for SlotsWeekDay attribute"); ++ dotdot_set_unify_schedule_entry_lock_slots_week_day(unid, endpoint_id, DESIRED_ATTRIBUTE, attributes.slots_week_day); ++ } ++ if (true == updated_attributes.slots_year_day) { ++ sl_log_debug(LOG_TAG, "Updating desired value for SlotsYearDay attribute"); ++ dotdot_set_unify_schedule_entry_lock_slots_year_day(unid, endpoint_id, DESIRED_ATTRIBUTE, attributes.slots_year_day); ++ } ++ if (true == updated_attributes.signtzo) { ++ sl_log_debug(LOG_TAG, "Updating desired value for SignTZO attribute"); ++ dotdot_set_unify_schedule_entry_lock_signtzo(unid, endpoint_id, DESIRED_ATTRIBUTE, attributes.signtzo); ++ } ++ if (true == updated_attributes.hourtzo) { ++ sl_log_debug(LOG_TAG, "Updating desired value for HourTZO attribute"); ++ dotdot_set_unify_schedule_entry_lock_hourtzo(unid, endpoint_id, DESIRED_ATTRIBUTE, attributes.hourtzo); ++ } ++ if (true == updated_attributes.minutetzo) { ++ sl_log_debug(LOG_TAG, "Updating desired value for MinuteTZO attribute"); ++ dotdot_set_unify_schedule_entry_lock_minutetzo(unid, endpoint_id, DESIRED_ATTRIBUTE, attributes.minutetzo); ++ } ++ if (true == updated_attributes.dst_offset_sign) { ++ sl_log_debug(LOG_TAG, "Updating desired value for DSTOffsetSign attribute"); ++ dotdot_set_unify_schedule_entry_lock_dst_offset_sign(unid, endpoint_id, DESIRED_ATTRIBUTE, attributes.dst_offset_sign); ++ } ++ if (true == updated_attributes.dst_offset_minute) { ++ sl_log_debug(LOG_TAG, "Updating desired value for DSTOffsetMinute attribute"); ++ dotdot_set_unify_schedule_entry_lock_dst_offset_minute(unid, endpoint_id, DESIRED_ATTRIBUTE, attributes.dst_offset_minute); ++ } ++ if (true == updated_attributes.number_of_slots_daily_repeating) { ++ sl_log_debug(LOG_TAG, "Updating desired value for NumberOfSlotsDailyRepeating attribute"); ++ dotdot_set_unify_schedule_entry_lock_number_of_slots_daily_repeating(unid, endpoint_id, DESIRED_ATTRIBUTE, attributes.number_of_slots_daily_repeating); ++ } ++ return SL_STATUS_OK; ++} ++//////////////////////////////////////////////////////////////////////////////// + // Start of cluster UnifyHumidityControl + //////////////////////////////////////////////////////////////////////////////// + // WriteAttribute Callbacks unify_humidity_control +@@ -2755,6 +2817,9 @@ sl_status_t + uic_mqtt_dotdot_set_unify_thermostat_write_attributes_callback( + &unify_thermostat_cluster_write_attributes_callback); + ++ uic_mqtt_dotdot_set_unify_schedule_entry_lock_write_attributes_callback( ++ &unify_schedule_entry_lock_cluster_write_attributes_callback); ++ + uic_mqtt_dotdot_set_unify_humidity_control_write_attributes_callback( + &unify_humidity_control_cluster_write_attributes_callback); + +diff --git a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c +index a5dd3ae27f..d47ecc8e11 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c ++++ b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c +@@ -1322,6 +1322,28 @@ uic_mqtt_dotdot_unify_thermostat_write_attributes_callback_t get_uic_mqtt_dotdot + return test_uic_mqtt_dotdot_unify_thermostat_write_attributes_callback; + } + ++static uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback = NULL; ++static uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback = NULL; ++ ++uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback; ++} ++uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback; ++} ++ ++static uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback; ++} ++static uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback; ++} ++static uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback; ++} + static uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_t test_uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback = NULL; + static uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback_t test_uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback = NULL; + +@@ -2931,6 +2953,31 @@ void set_uic_mqtt_dotdot_unify_thermostat_write_attributes_callback_stub( + { + test_uic_mqtt_dotdot_unify_thermostat_write_attributes_callback = callback; + } ++void set_uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback = callback; ++} ++void set_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback = callback; ++} + void set_uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_stub( + const uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_t callback, int cmock_num_calls) + { +@@ -3877,6 +3924,21 @@ void setUp() + test_uic_mqtt_dotdot_unify_thermostat_write_attributes_callback = NULL; + uic_mqtt_dotdot_set_unify_thermostat_write_attributes_callback_Stub( + &set_uic_mqtt_dotdot_unify_thermostat_write_attributes_callback_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback = NULL; ++ uic_mqtt_dotdot_set_unify_schedule_entry_lock_force_read_attributes_callback_Stub( ++ &set_uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback = NULL; ++ uic_mqtt_dotdot_set_unify_schedule_entry_lock_write_attributes_callback_Stub( ++ &set_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set_stub); + test_uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback = NULL; + uic_mqtt_dotdot_set_unify_humidity_control_force_read_attributes_callback_Stub( + &set_uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_stub); +@@ -4640,6 +4702,14 @@ void test_automatic_deduction_of_supported_commands() + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_thermostat_thermostat_mode(expected_unid,expected_endpoint_id) ); + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_thermostat_supported_thermostat_mode(expected_unid,expected_endpoint_id) ); + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_thermostat_operating_state(expected_unid,expected_endpoint_id) ); ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_schedule_entry_lock_slots_week_day(expected_unid,expected_endpoint_id) ); ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_schedule_entry_lock_slots_year_day(expected_unid,expected_endpoint_id) ); ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_schedule_entry_lock_signtzo(expected_unid,expected_endpoint_id) ); ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_schedule_entry_lock_hourtzo(expected_unid,expected_endpoint_id) ); ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_schedule_entry_lock_minutetzo(expected_unid,expected_endpoint_id) ); ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_schedule_entry_lock_dst_offset_sign(expected_unid,expected_endpoint_id) ); ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_schedule_entry_lock_dst_offset_minute(expected_unid,expected_endpoint_id) ); ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_schedule_entry_lock_number_of_slots_daily_repeating(expected_unid,expected_endpoint_id) ); + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_humidity_control_reporting_mode(expected_unid,expected_endpoint_id) ); + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_humidity_control_supported_reporting_mode(expected_unid,expected_endpoint_id) ); + TEST_ASSERT_EQUAL(SL_STATUS_OK, dotdot_create_unify_humidity_control_current_state(expected_unid,expected_endpoint_id) ); +@@ -7748,6 +7818,131 @@ void test_automatic_deduction_of_supported_commands() + + )); + } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t day_of_week_value; ++ memset(&day_of_week_value, 0x00, sizeof(day_of_week_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ day_of_week_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback) { ++ // Dummy command parameters ++ uint8_t set_action_value; ++ memset(&set_action_value, 0x00, sizeof(set_action_value)); ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t start_year_value; ++ memset(&start_year_value, 0x00, sizeof(start_year_value)); ++ uint8_t start_day_value; ++ memset(&start_day_value, 0x00, sizeof(start_day_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_year_value; ++ memset(&stop_year_value, 0x00, sizeof(stop_year_value)); ++ uint8_t stop_day_value; ++ memset(&stop_day_value, 0x00, sizeof(stop_day_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ set_action_value, ++ ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ start_year_value, ++ ++ start_day_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ stop_year_value, ++ ++ stop_day_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback) { ++ // Dummy command parameters ++ uint8_t set_action_value; ++ memset(&set_action_value, 0x00, sizeof(set_action_value)); ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t week_day_bitmask_value; ++ memset(&week_day_bitmask_value, 0x00, sizeof(week_day_bitmask_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t duration_hour_value; ++ memset(&duration_hour_value, 0x00, sizeof(duration_hour_value)); ++ uint8_t duration_minute_value; ++ memset(&duration_minute_value, 0x00, sizeof(duration_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ set_action_value, ++ ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ week_day_bitmask_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ duration_hour_value, ++ ++ duration_minute_value ++ ++ )); ++ } + if (NULL != test_uic_mqtt_dotdot_unify_humidity_control_mode_set_callback) { + // Dummy command parameters + ModeType mode_value; +@@ -10863,6 +11058,131 @@ void test_automatic_deduction_of_supported_commands() + + )); + } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t day_of_week_value; ++ memset(&day_of_week_value, 0x00, sizeof(day_of_week_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ day_of_week_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback) { ++ // Dummy command parameters ++ uint8_t set_action_value; ++ memset(&set_action_value, 0x00, sizeof(set_action_value)); ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t start_year_value; ++ memset(&start_year_value, 0x00, sizeof(start_year_value)); ++ uint8_t start_day_value; ++ memset(&start_day_value, 0x00, sizeof(start_day_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_year_value; ++ memset(&stop_year_value, 0x00, sizeof(stop_year_value)); ++ uint8_t stop_day_value; ++ memset(&stop_day_value, 0x00, sizeof(stop_day_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ set_action_value, ++ ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ start_year_value, ++ ++ start_day_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ stop_year_value, ++ ++ stop_day_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback) { ++ // Dummy command parameters ++ uint8_t set_action_value; ++ memset(&set_action_value, 0x00, sizeof(set_action_value)); ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t week_day_bitmask_value; ++ memset(&week_day_bitmask_value, 0x00, sizeof(week_day_bitmask_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t duration_hour_value; ++ memset(&duration_hour_value, 0x00, sizeof(duration_hour_value)); ++ uint8_t duration_minute_value; ++ memset(&duration_minute_value, 0x00, sizeof(duration_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ set_action_value, ++ ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ week_day_bitmask_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ duration_hour_value, ++ ++ duration_minute_value ++ ++ )); ++ } + if (NULL != test_uic_mqtt_dotdot_unify_humidity_control_mode_set_callback) { + // Dummy command parameters + ModeType mode_value; +diff --git a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h +index 35ada30800..cf53259d15 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h ++++ b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h +@@ -798,6 +798,19 @@ + uic_mqtt_dotdot_unify_thermostat_write_attributes_callback_t get_uic_mqtt_dotdot_unify_thermostat_write_attributes_callback(); + + ++ uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback(); ++ ++ + uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_t get_uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback(); + uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback_t get_uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback(); + +-- +2.39.5 + diff --git a/patches/UnifySDK/0013-UIC-3437-Report-callback-Schedule-Entry-Lock-CC.patch b/patches/UnifySDK/0013-UIC-3437-Report-callback-Schedule-Entry-Lock-CC.patch new file mode 100644 index 000000000..97617971a --- /dev/null +++ b/patches/UnifySDK/0013-UIC-3437-Report-callback-Schedule-Entry-Lock-CC.patch @@ -0,0 +1,521 @@ +From d9995303578bf30c27a13f6778590c49475c0975 Mon Sep 17 00:00:00 2001 +From: Thirupathi S +Date: Sat, 28 Sep 2024 04:18:17 +0000 +Subject: [PATCH] UIC-3437: Report callback Schedule Entry Lock CC + +Merge in UIC/uic from feature/UIC-3437-Report-callback-Schedule-Entry-Lock-CC to feature/UIC-3271-Schedule-Entry-Lock-CC +--- + .../cluster-types/cluster-type-attributes.ts | 15 ++++++++ + .../dotdot-xml/Unify_ScheduleEntryLock.xml | 20 +++++++++++ + .../zap-generated/include/dotdot_mqtt.h | 8 +++++ + .../zap-generated/src/dotdot_mqtt.cpp | 28 +++++++++++++++ + .../src/dotdot_mqtt_command_helpers.cpp | 34 +++++++++++++++++++ + .../src/dotdot_mqtt_command_helpers.hpp | 4 +++ + .../src/dotdot_mqtt_group_commands.cpp | 4 +++ + .../test/dotdot_mqtt_test.include | 4 +++ + .../test/unify_dotdot_attribute_store_test.c | 16 +++++++++ + 9 files changed, 133 insertions(+) + +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 c8f421a395..d76522387d 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 +@@ -15510,6 +15510,11 @@ export let ClusterTypeAttrs: any = { + type: "number", + isArray: false, + }, ++ { ++ name: "StartMonth", ++ type: "number", ++ isArray: false, ++ }, + { + name: "StartDay", + type: "number", +@@ -15530,6 +15535,11 @@ export let ClusterTypeAttrs: any = { + type: "number", + isArray: false, + }, ++ { ++ name: "StopMonth", ++ type: "number", ++ isArray: false, ++ }, + { + name: "StopDay", + type: "number", +@@ -15577,6 +15587,11 @@ export let ClusterTypeAttrs: any = { + type: "number", + isArray: false, + }, ++ { ++ name: "StartMonth", ++ type: "number", ++ isArray: false, ++ }, + { + name: "StartMinute", + type: "number", +diff --git a/components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml b/components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml +index 8b9f0685d6..390ee807b3 100644 +--- a/components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml ++++ b/components/uic_dotdot/dotdot-xml/Unify_ScheduleEntryLock.xml +@@ -88,6 +88,11 @@ + + + ++ ++ ++ ++ ++ + + + +@@ -98,6 +103,11 @@ + + + ++ ++ ++ ++ ++ + + + +@@ -204,6 +214,11 @@ + + + ++ ++ ++ ++ ++ + + + +@@ -224,6 +239,11 @@ + + + ++ ++ ++ ++ ++ + + + +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 0a57bcf5ad..f0fdd07d2b 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h ++++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h +@@ -40171,6 +40171,8 @@ typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_l + + uint8_t start_year, + ++ uint8_t start_month, ++ + uint8_t start_day, + + uint8_t start_hour, +@@ -40179,6 +40181,8 @@ typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_l + + uint8_t stop_year, + ++ uint8_t stop_month, ++ + uint8_t stop_day, + + uint8_t stop_hour, +@@ -40277,6 +40281,8 @@ typedef struct { + + uint8_t start_year; + ++ uint8_t start_month; ++ + uint8_t start_day; + + uint8_t start_hour; +@@ -40285,6 +40291,8 @@ typedef struct { + + uint8_t stop_year; + ++ uint8_t stop_month; ++ + uint8_t stop_day; + + uint8_t stop_hour; +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 02a9105975..a9ce13461d 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp +@@ -94313,10 +94313,12 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_r + uint8_t user_identifier = {}; + uint8_t schedule_slotid = {}; + uint8_t start_year = {}; ++ uint8_t start_month = {}; + uint8_t start_day = {}; + uint8_t start_hour = {}; + uint8_t start_minute = {}; + uint8_t stop_year = {}; ++ uint8_t stop_month = {}; + uint8_t stop_day = {}; + uint8_t stop_hour = {}; + uint8_t stop_minute = {}; +@@ -94337,6 +94339,8 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_r + + start_year, + ++ start_month, ++ + start_day, + + start_hour, +@@ -94345,6 +94349,8 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_r + + stop_year, + ++ stop_month, ++ + stop_day, + + stop_hour, +@@ -94380,6 +94386,8 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_r + + start_year, + ++ start_month, ++ + start_day, + + start_hour, +@@ -94388,6 +94396,8 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_r + + stop_year, + ++ stop_month, ++ + stop_day, + + stop_hour, +@@ -94422,10 +94432,12 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + uint8_t user_identifier = {}; + uint8_t schedule_slotid = {}; + uint8_t start_year = {}; ++ uint8_t start_month = {}; + uint8_t start_day = {}; + uint8_t start_hour = {}; + uint8_t start_minute = {}; + uint8_t stop_year = {}; ++ uint8_t stop_month = {}; + uint8_t stop_day = {}; + uint8_t stop_hour = {}; + uint8_t stop_minute = {}; +@@ -94446,6 +94458,8 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + + start_year, + ++ start_month, ++ + start_day, + + start_hour, +@@ -94454,6 +94468,8 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + + stop_year, + ++ stop_month, ++ + stop_day, + + stop_hour, +@@ -94490,6 +94506,8 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + + start_year, + ++ start_month, ++ + start_day, + + start_hour, +@@ -94498,6 +94516,8 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + + stop_year, + ++ stop_month, ++ + stop_day, + + stop_hour, +@@ -111368,6 +111388,8 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); + uint8_t start_year_value; + memset(&start_year_value, 0x00, sizeof(start_year_value)); ++ uint8_t start_month_value; ++ memset(&start_month_value, 0x00, sizeof(start_month_value)); + uint8_t start_day_value; + memset(&start_day_value, 0x00, sizeof(start_day_value)); + uint8_t start_hour_value; +@@ -111376,6 +111398,8 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + memset(&start_minute_value, 0x00, sizeof(start_minute_value)); + uint8_t stop_year_value; + memset(&stop_year_value, 0x00, sizeof(stop_year_value)); ++ uint8_t stop_month_value; ++ memset(&stop_month_value, 0x00, sizeof(stop_month_value)); + uint8_t stop_day_value; + memset(&stop_day_value, 0x00, sizeof(stop_day_value)); + uint8_t stop_hour_value; +@@ -111393,6 +111417,8 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + + start_year_value, + ++ start_month_value, ++ + start_day_value, + + start_hour_value, +@@ -111401,6 +111427,8 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + + stop_year_value, + ++ stop_month_value, ++ + stop_day_value, + + stop_hour_value, +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 0c1e90c9d9..9d5eb3d4a7 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 +@@ -14661,6 +14661,10 @@ std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_y + command_with_no_fields = false; + // Single Value + // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartMonth"] = nlohmann::json(fields->start_month); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) + json_payload["StartDay"] = nlohmann::json(fields->start_day); + command_with_no_fields = false; + // Single Value +@@ -14677,6 +14681,10 @@ std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_y + command_with_no_fields = false; + // Single Value + // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopMonth"] = nlohmann::json(fields->stop_month); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) + json_payload["StopDay"] = nlohmann::json(fields->stop_day); + command_with_no_fields = false; + // Single Value +@@ -14706,6 +14714,8 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_da + + uint8_t &start_year, + ++ uint8_t &start_month, ++ + uint8_t &start_day, + + uint8_t &start_hour, +@@ -14714,6 +14724,8 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_da + + uint8_t &stop_year, + ++ uint8_t &stop_month, ++ + uint8_t &stop_day, + + uint8_t &stop_hour, +@@ -14746,6 +14758,12 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_da + } + + start_year = jsn.at("StartYear").get< uint8_t >(); ++ if (jsn.at("StartMonth").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_month = jsn.at("StartMonth").get< uint8_t >(); + if (jsn.at("StartDay").is_null()) { + sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); + return; +@@ -14770,6 +14788,12 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_da + } + + stop_year = jsn.at("StopYear").get< uint8_t >(); ++ if (jsn.at("StopMonth").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_month = jsn.at("StopMonth").get< uint8_t >(); + if (jsn.at("StopDay").is_null()) { + sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); + return; +@@ -14823,6 +14847,10 @@ std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_d + command_with_no_fields = false; + // Single Value + // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartMonth"] = nlohmann::json(fields->start_month); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) + json_payload["StartMinute"] = nlohmann::json(fields->start_minute); + command_with_no_fields = false; + // Single Value +@@ -14892,6 +14920,12 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_r + } + + start_hour = jsn.at("StartHour").get< uint8_t >(); ++ if (jsn.at("StartMonth").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_month = jsn.at("StartMonth").get< uint8_t >(); + if (jsn.at("StartMinute").is_null()) { + sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); + return; +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 1082c43494..31a79e1ade 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 +@@ -6099,6 +6099,8 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_da + + uint8_t &start_year, + ++ uint8_t &start_month, ++ + uint8_t &start_day, + + uint8_t &start_hour, +@@ -6107,6 +6109,8 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_da + + uint8_t &stop_year, + ++ uint8_t &stop_month, ++ + uint8_t &stop_day, + + uint8_t &stop_hour, +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 c63dd2a685..76008f3cbf 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 +@@ -23625,6 +23625,8 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + + fields.start_year, + ++ fields.start_month, ++ + fields.start_day, + + fields.start_hour, +@@ -23633,6 +23635,8 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + + fields.stop_year, + ++ fields.stop_month, ++ + fields.stop_day, + + fields.stop_hour, +diff --git a/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include b/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include +index 64c6d7fe29..c047606bb6 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include ++++ b/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include +@@ -3033,6 +3033,8 @@ static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + + uint8_t start_year, + ++ uint8_t start_month, ++ + uint8_t start_day, + + uint8_t start_hour, +@@ -3041,6 +3043,8 @@ static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + + uint8_t stop_year, + ++ uint8_t stop_month, ++ + uint8_t stop_day, + + uint8_t stop_hour, +diff --git a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c +index d47ecc8e11..b4559eb2d0 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c ++++ b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c +@@ -7863,6 +7863,8 @@ void test_automatic_deduction_of_supported_commands() + memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); + uint8_t start_year_value; + memset(&start_year_value, 0x00, sizeof(start_year_value)); ++ uint8_t start_month_value; ++ memset(&start_month_value, 0x00, sizeof(start_month_value)); + uint8_t start_day_value; + memset(&start_day_value, 0x00, sizeof(start_day_value)); + uint8_t start_hour_value; +@@ -7871,6 +7873,8 @@ void test_automatic_deduction_of_supported_commands() + memset(&start_minute_value, 0x00, sizeof(start_minute_value)); + uint8_t stop_year_value; + memset(&stop_year_value, 0x00, sizeof(stop_year_value)); ++ uint8_t stop_month_value; ++ memset(&stop_month_value, 0x00, sizeof(stop_month_value)); + uint8_t stop_day_value; + memset(&stop_day_value, 0x00, sizeof(stop_day_value)); + uint8_t stop_hour_value; +@@ -7888,6 +7892,8 @@ void test_automatic_deduction_of_supported_commands() + + start_year_value, + ++ start_month_value, ++ + start_day_value, + + start_hour_value, +@@ -7896,6 +7902,8 @@ void test_automatic_deduction_of_supported_commands() + + stop_year_value, + ++ stop_month_value, ++ + stop_day_value, + + stop_hour_value, +@@ -11107,10 +11115,14 @@ void test_automatic_deduction_of_supported_commands() + memset(&start_day_value, 0x00, sizeof(start_day_value)); + uint8_t start_hour_value; + memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_month_value; ++ memset(&start_month_value, 0x00, sizeof(start_month_value)); + uint8_t start_minute_value; + memset(&start_minute_value, 0x00, sizeof(start_minute_value)); + uint8_t stop_year_value; + memset(&stop_year_value, 0x00, sizeof(stop_year_value)); ++ uint8_t stop_month_value; ++ memset(&stop_month_value, 0x00, sizeof(stop_month_value)); + uint8_t stop_day_value; + memset(&stop_day_value, 0x00, sizeof(stop_day_value)); + uint8_t stop_hour_value; +@@ -11132,10 +11144,14 @@ void test_automatic_deduction_of_supported_commands() + + start_hour_value, + ++ start_month_value, ++ + start_minute_value, + + stop_year_value, + ++ stop_month_value, ++ + stop_day_value, + + stop_hour_value, +-- +2.39.5 + diff --git a/patches/UnifySDK/0014-UIC-3437-Generated-files-for-ScheduleEntryLock-using.patch b/patches/UnifySDK/0014-UIC-3437-Generated-files-for-ScheduleEntryLock-using.patch new file mode 100644 index 000000000..8d3783324 --- /dev/null +++ b/patches/UnifySDK/0014-UIC-3437-Generated-files-for-ScheduleEntryLock-using.patch @@ -0,0 +1,12466 @@ +From d4c8c5dc7793c0733b0f2c1989e416571ab489e9 Mon Sep 17 00:00:00 2001 +From: Philippe Coval +Date: Tue, 16 Sep 2025 14:47:10 +0200 +Subject: [PATCH] UIC-3437: Generated files for ScheduleEntryLock using latest + zap + +Relate-to: https://github.com/project-chip/zap/releases/download/v2025.07.24/zap-linux-x64.deb +Signed-off-by: Philippe Coval +--- + .../src/eed_attribute_store_clusters.c | 32 + + .../src/eed_dotdot_create_clusters.cpp | 87 + + .../include/dotdot_attribute_id_definitions.h | 9 + + .../dotdot_cluster_command_id_definitions.h | 13 + + .../include/dotdot_cluster_id_definitions.h | 4 + + .../readme_ucl_mqtt_reference.md | 1301 ++++++++ + .../src/dotdot_attribute_id_definitions.c | 79 + + .../src/dotdot_cluster_id_definitions.c | 5 + + .../zap-generated/include/dotdot_mqtt.h | 638 +++- + .../include/dotdot_mqtt_generated_commands.h | 192 +- + .../include/dotdot_mqtt_group_commands.h | 158 +- + .../include/dotdot_mqtt_send_commands.h | 360 +- + ...dotdot_mqtt_supported_generated_commands.h | 14 +- + .../zap-generated/src/dotdot_mqtt.cpp | 2964 ++++++++++++++--- + .../zap-generated/src/dotdot_mqtt.hpp | 192 +- + .../src/dotdot_mqtt_command_helpers.cpp | 696 +++- + .../src/dotdot_mqtt_command_helpers.hpp | 312 +- + .../src/dotdot_mqtt_generated_commands.cpp | 324 +- + .../src/dotdot_mqtt_group_commands.cpp | 1260 ++++++- + .../src/dotdot_mqtt_send_commands.cpp | 664 +++- + ...tdot_mqtt_supported_generated_commands.cpp | 36 +- + .../test/dotdot_mqtt_test.include | 230 +- + .../test/unify_dotdot_attribute_store_test.c | 582 +++- + .../test/unify_dotdot_attribute_store_test.h | 30 +- + 24 files changed, 9339 insertions(+), 843 deletions(-) + +diff --git a/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_attribute_store_clusters.c b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_attribute_store_clusters.c +index 981d5e7ef4..6b5125b658 100644 +--- a/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_attribute_store_clusters.c ++++ b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_attribute_store_clusters.c +@@ -2723,6 +2723,38 @@ sl_status_t eed_attribute_store_clusters_init() + &on_zcl_desired_value_update, + DOTDOT_ATTRIBUTE_ID_UNIFY_THERMOSTAT_OPERATING_STATE, + DESIRED_ATTRIBUTE); ++ attribute_store_register_callback_by_type_and_state( ++ &on_zcl_desired_value_update, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY, ++ DESIRED_ATTRIBUTE); ++ attribute_store_register_callback_by_type_and_state( ++ &on_zcl_desired_value_update, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY, ++ DESIRED_ATTRIBUTE); ++ attribute_store_register_callback_by_type_and_state( ++ &on_zcl_desired_value_update, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO, ++ DESIRED_ATTRIBUTE); ++ attribute_store_register_callback_by_type_and_state( ++ &on_zcl_desired_value_update, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO, ++ DESIRED_ATTRIBUTE); ++ attribute_store_register_callback_by_type_and_state( ++ &on_zcl_desired_value_update, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO, ++ DESIRED_ATTRIBUTE); ++ attribute_store_register_callback_by_type_and_state( ++ &on_zcl_desired_value_update, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN, ++ DESIRED_ATTRIBUTE); ++ attribute_store_register_callback_by_type_and_state( ++ &on_zcl_desired_value_update, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE, ++ DESIRED_ATTRIBUTE); ++ attribute_store_register_callback_by_type_and_state( ++ &on_zcl_desired_value_update, ++ DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING, ++ DESIRED_ATTRIBUTE); + attribute_store_register_callback_by_type_and_state( + &on_zcl_desired_value_update, + DOTDOT_ATTRIBUTE_ID_UNIFY_HUMIDITY_CONTROL_REPORTING_MODE, +diff --git a/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_dotdot_create_clusters.cpp b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_dotdot_create_clusters.cpp +index 0a74dd6e3e..8c320aad1e 100644 +--- a/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_dotdot_create_clusters.cpp ++++ b/applications/examples/applications/emulated_end_device/components/eed_attribute_store/zap-generated/src/eed_dotdot_create_clusters.cpp +@@ -4056,6 +4056,57 @@ void dotdot_create_unify_thermostat_wrapper(const dotdot_unid_t unid, const dotd + + } + ++void dotdot_create_unify_schedule_entry_lock_wrapper(const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id){ ++ // Create and set a default value if undefined. ++ dotdot_create_unify_schedule_entry_lock_slots_week_day(unid,endpoint_id); ++ if (false == dotdot_unify_schedule_entry_lock_slots_week_day_is_reported_defined(unid,endpoint_id)){ ++ dotdot_set_unify_schedule_entry_lock_slots_week_day(unid,endpoint_id,REPORTED_ATTRIBUTE, static_cast(0)); ++ } ++ ++ // Create and set a default value if undefined. ++ dotdot_create_unify_schedule_entry_lock_slots_year_day(unid,endpoint_id); ++ if (false == dotdot_unify_schedule_entry_lock_slots_year_day_is_reported_defined(unid,endpoint_id)){ ++ dotdot_set_unify_schedule_entry_lock_slots_year_day(unid,endpoint_id,REPORTED_ATTRIBUTE, static_cast(0)); ++ } ++ ++ // Create and set a default value if undefined. ++ dotdot_create_unify_schedule_entry_lock_signtzo(unid,endpoint_id); ++ if (false == dotdot_unify_schedule_entry_lock_signtzo_is_reported_defined(unid,endpoint_id)){ ++ dotdot_set_unify_schedule_entry_lock_signtzo(unid,endpoint_id,REPORTED_ATTRIBUTE, static_cast(0)); ++ } ++ ++ // Create and set a default value if undefined. ++ dotdot_create_unify_schedule_entry_lock_hourtzo(unid,endpoint_id); ++ if (false == dotdot_unify_schedule_entry_lock_hourtzo_is_reported_defined(unid,endpoint_id)){ ++ dotdot_set_unify_schedule_entry_lock_hourtzo(unid,endpoint_id,REPORTED_ATTRIBUTE, static_cast(0)); ++ } ++ ++ // Create and set a default value if undefined. ++ dotdot_create_unify_schedule_entry_lock_minutetzo(unid,endpoint_id); ++ if (false == dotdot_unify_schedule_entry_lock_minutetzo_is_reported_defined(unid,endpoint_id)){ ++ dotdot_set_unify_schedule_entry_lock_minutetzo(unid,endpoint_id,REPORTED_ATTRIBUTE, static_cast(0)); ++ } ++ ++ // Create and set a default value if undefined. ++ dotdot_create_unify_schedule_entry_lock_dst_offset_sign(unid,endpoint_id); ++ if (false == dotdot_unify_schedule_entry_lock_dst_offset_sign_is_reported_defined(unid,endpoint_id)){ ++ dotdot_set_unify_schedule_entry_lock_dst_offset_sign(unid,endpoint_id,REPORTED_ATTRIBUTE, static_cast(0)); ++ } ++ ++ // Create and set a default value if undefined. ++ dotdot_create_unify_schedule_entry_lock_dst_offset_minute(unid,endpoint_id); ++ if (false == dotdot_unify_schedule_entry_lock_dst_offset_minute_is_reported_defined(unid,endpoint_id)){ ++ dotdot_set_unify_schedule_entry_lock_dst_offset_minute(unid,endpoint_id,REPORTED_ATTRIBUTE, static_cast(0)); ++ } ++ ++ // Create and set a default value if undefined. ++ dotdot_create_unify_schedule_entry_lock_number_of_slots_daily_repeating(unid,endpoint_id); ++ if (false == dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_is_reported_defined(unid,endpoint_id)){ ++ dotdot_set_unify_schedule_entry_lock_number_of_slots_daily_repeating(unid,endpoint_id,REPORTED_ATTRIBUTE, static_cast(0)); ++ } ++ ++} ++ + void dotdot_create_unify_humidity_control_wrapper(const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id){ + // Create and set a default value if undefined. + dotdot_create_unify_humidity_control_reporting_mode(unid,endpoint_id); +@@ -6598,6 +6649,40 @@ void dotdot_unretain_unify_thermostat_wrapper(const dotdot_unid_t unid, const do + uic_mqtt_dotdot_unify_thermostat_publish_empty_supported_commands(unid, endpoint_id); + } + ++void dotdot_unretain_unify_schedule_entry_lock_wrapper(const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id){ ++ char base_topic[256]; ++ snprintf(base_topic, sizeof(base_topic), "ucl/by-unid/%s/ep%d", unid, endpoint_id); ++ attribute_store::attribute ep_node = eed_attribute_store_get_endpoint_node(unid, endpoint_id); ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_slots_week_day_unretain(base_topic,UCL_MQTT_PUBLISH_TYPE_ALL); ++ ep_node.child_by_type(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY).delete_node(); ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_slots_year_day_unretain(base_topic,UCL_MQTT_PUBLISH_TYPE_ALL); ++ ep_node.child_by_type(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY).delete_node(); ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_signtzo_unretain(base_topic,UCL_MQTT_PUBLISH_TYPE_ALL); ++ ep_node.child_by_type(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO).delete_node(); ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_hourtzo_unretain(base_topic,UCL_MQTT_PUBLISH_TYPE_ALL); ++ ep_node.child_by_type(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO).delete_node(); ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_minutetzo_unretain(base_topic,UCL_MQTT_PUBLISH_TYPE_ALL); ++ ep_node.child_by_type(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO).delete_node(); ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_dst_offset_sign_unretain(base_topic,UCL_MQTT_PUBLISH_TYPE_ALL); ++ ep_node.child_by_type(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN).delete_node(); ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_dst_offset_minute_unretain(base_topic,UCL_MQTT_PUBLISH_TYPE_ALL); ++ ep_node.child_by_type(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE).delete_node(); ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_number_of_slots_daily_repeating_unretain(base_topic,UCL_MQTT_PUBLISH_TYPE_ALL); ++ ep_node.child_by_type(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING).delete_node(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_unretain_cluster_revision(base_topic); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_publish_empty_supported_commands(unid, endpoint_id); ++} ++ + void dotdot_unretain_unify_humidity_control_wrapper(const dotdot_unid_t unid, const dotdot_endpoint_id_t endpoint_id){ + char base_topic[256]; + snprintf(base_topic, sizeof(base_topic), "ucl/by-unid/%s/ep%d", unid, endpoint_id); +@@ -6743,6 +6828,7 @@ std::map CreateClusterMap = { + { "Descriptor", dotdot_create_descriptor_wrapper }, + { "UnifyFanControl", dotdot_create_unify_fan_control_wrapper }, + { "UnifyThermostat", dotdot_create_unify_thermostat_wrapper }, ++{ "UnifyScheduleEntryLock", dotdot_create_unify_schedule_entry_lock_wrapper }, + { "UnifyHumidityControl", dotdot_create_unify_humidity_control_wrapper }, + }; + +@@ -6795,5 +6881,6 @@ std::map CreateUnretainMap = { + { "Descriptor", dotdot_unretain_descriptor_wrapper }, + { "UnifyFanControl", dotdot_unretain_unify_fan_control_wrapper }, + { "UnifyThermostat", dotdot_unretain_unify_thermostat_wrapper }, ++{ "UnifyScheduleEntryLock", dotdot_unretain_unify_schedule_entry_lock_wrapper }, + { "UnifyHumidityControl", dotdot_unretain_unify_humidity_control_wrapper }, + }; +\ No newline at end of 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 52a9683a3b..eca5efe3e4 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 +@@ -867,6 +867,15 @@ typedef enum { + #define DOTDOT_UNIFY_THERMOSTAT_THERMOSTAT_MODE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x1) + #define DOTDOT_UNIFY_THERMOSTAT_SUPPORTED_THERMOSTAT_MODE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x2) + #define DOTDOT_UNIFY_THERMOSTAT_OPERATING_STATE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x3) ++// Definitions for cluster: UnifyScheduleEntryLock ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x1) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x2) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x3) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x4) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x5) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x6) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x7) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING_ATTRIBUTE_ID ((dotdot_attribute_id_t)0x8) + // 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) +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 c63d48c45f..d67925ccb1 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 +@@ -373,6 +373,19 @@ + + // Commands for cluster: UnifyThermostat + ++// Commands for cluster: UnifyScheduleEntryLock ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_ENABLE_SET_COMMAND_ID (0x1) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_WEEK_DAY_REPORT_COMMAND_ID (0x1) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_ENABLE_ALL_SET_COMMAND_ID (0x2) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_YEAR_DAY_REPORT_COMMAND_ID (0x2) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SET_COMMAND_ID (0x3) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_REPORT_COMMAND_ID (0x3) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_WEEK_DAY_GET_COMMAND_ID (0x4) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SET_COMMAND_ID (0x5) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_YEAR_DAY_GET_COMMAND_ID (0x6) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SET_COMMAND_ID (0x7) ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_GET_COMMAND_ID (0x8) ++ + // Commands for cluster: UnifyHumidityControl + #define DOTDOT_UNIFY_HUMIDITY_CONTROL_MODE_SET_COMMAND_ID (0x1) + #define DOTDOT_UNIFY_HUMIDITY_CONTROL_SETPOINT_SET_COMMAND_ID (0x2) +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 7432fce84e..b32935c29f 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 +@@ -266,6 +266,10 @@ + #define DOTDOT_UNIFY_THERMOSTAT_CLUSTER_ID ((dotdot_cluster_id_t)0xFD15) + + ++// Definitions for cluster: UnifyScheduleEntryLock ++#define DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_CLUSTER_ID ((dotdot_cluster_id_t)0xFD21) ++ ++ + // Definitions for cluster: UnifyHumidityControl + #define DOTDOT_UNIFY_HUMIDITY_CONTROL_CLUSTER_ID ((dotdot_cluster_id_t)0xFDA0) + +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 82dfa2097d..4842178313 100644 +--- a/components/uic_dotdot/zap-generated/readme_ucl_mqtt_reference.md ++++ b/components/uic_dotdot/zap-generated/readme_ucl_mqtt_reference.md +@@ -53568,6 +53568,1307 @@ mosquitto_pub -t 'ucl/by-unid///UnifyThermostat/Commands/ForceReadAttr +


+ + ++ ++ ++ ++ ++ ++\page unify_schedule_entry_lock UnifyScheduleEntryLock Cluster ++The following commands and attributes are accepted as JSON payloads for the ++UnifyScheduleEntryLock cluster. ++ ++

++ ++ ++ ++ ++\section unify_schedule_entry_lock_attrs UnifyScheduleEntryLock Attributes ++The following attribute topics are used to retrieve the UnifyScheduleEntryLock cluster state. ++ ++
++ ++\subsection unify_schedule_entry_lock_attr_slots_week_day UnifyScheduleEntryLock/SlotsWeekDay Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Attributes/SlotsWeekDay/Reported ++[PREFIX]/UnifyScheduleEntryLock/Attributes/SlotsWeekDay/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster SlotsWeekDay Attribute Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see desired/reported value for SlotsWeekDay attribute under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid/+/+/UnifyScheduleEntryLock/Attributes/SlotsWeekDay/+' ++ ++# Example output ++ ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/SlotsWeekDay/Desired { "value": } ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/SlotsWeekDay/Reported { "value": } ++ ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_attr_slots_year_day UnifyScheduleEntryLock/SlotsYearDay Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Attributes/SlotsYearDay/Reported ++[PREFIX]/UnifyScheduleEntryLock/Attributes/SlotsYearDay/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster SlotsYearDay Attribute Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see desired/reported value for SlotsYearDay attribute under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid/+/+/UnifyScheduleEntryLock/Attributes/SlotsYearDay/+' ++ ++# Example output ++ ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/SlotsYearDay/Desired { "value": } ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/SlotsYearDay/Reported { "value": } ++ ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_attr_signtzo UnifyScheduleEntryLock/SignTZO Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Attributes/SignTZO/Reported ++[PREFIX]/UnifyScheduleEntryLock/Attributes/SignTZO/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster SignTZO Attribute Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see desired/reported value for SignTZO attribute under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid/+/+/UnifyScheduleEntryLock/Attributes/SignTZO/+' ++ ++# Example output ++ ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/SignTZO/Desired { "value": } ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/SignTZO/Reported { "value": } ++ ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_attr_hourtzo UnifyScheduleEntryLock/HourTZO Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Attributes/HourTZO/Reported ++[PREFIX]/UnifyScheduleEntryLock/Attributes/HourTZO/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster HourTZO Attribute Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see desired/reported value for HourTZO attribute under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid/+/+/UnifyScheduleEntryLock/Attributes/HourTZO/+' ++ ++# Example output ++ ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/HourTZO/Desired { "value": } ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/HourTZO/Reported { "value": } ++ ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_attr_minutetzo UnifyScheduleEntryLock/MinuteTZO Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Attributes/MinuteTZO/Reported ++[PREFIX]/UnifyScheduleEntryLock/Attributes/MinuteTZO/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster MinuteTZO Attribute Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see desired/reported value for MinuteTZO attribute under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid/+/+/UnifyScheduleEntryLock/Attributes/MinuteTZO/+' ++ ++# Example output ++ ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/MinuteTZO/Desired { "value": } ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/MinuteTZO/Reported { "value": } ++ ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_attr_dst_offset_sign UnifyScheduleEntryLock/DSTOffsetSign Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Attributes/DSTOffsetSign/Reported ++[PREFIX]/UnifyScheduleEntryLock/Attributes/DSTOffsetSign/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster DSTOffsetSign Attribute Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see desired/reported value for DSTOffsetSign attribute under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid/+/+/UnifyScheduleEntryLock/Attributes/DSTOffsetSign/+' ++ ++# Example output ++ ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/DSTOffsetSign/Desired { "value": } ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/DSTOffsetSign/Reported { "value": } ++ ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_attr_dst_offset_minute UnifyScheduleEntryLock/DSTOffsetMinute Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Attributes/DSTOffsetMinute/Reported ++[PREFIX]/UnifyScheduleEntryLock/Attributes/DSTOffsetMinute/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster DSTOffsetMinute Attribute Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see desired/reported value for DSTOffsetMinute attribute under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid/+/+/UnifyScheduleEntryLock/Attributes/DSTOffsetMinute/+' ++ ++# Example output ++ ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/DSTOffsetMinute/Desired { "value": } ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/DSTOffsetMinute/Reported { "value": } ++ ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_attr_number_of_slots_daily_repeating UnifyScheduleEntryLock/NumberOfSlotsDailyRepeating Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Attributes/NumberOfSlotsDailyRepeating/Reported ++[PREFIX]/UnifyScheduleEntryLock/Attributes/NumberOfSlotsDailyRepeating/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster NumberOfSlotsDailyRepeating Attribute Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see desired/reported value for NumberOfSlotsDailyRepeating attribute under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid/+/+/UnifyScheduleEntryLock/Attributes/NumberOfSlotsDailyRepeating/+' ++ ++# Example output ++ ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/NumberOfSlotsDailyRepeating/Desired { "value": } ++ucl/by-unid//ep0/UnifyScheduleEntryLock/Attributes/NumberOfSlotsDailyRepeating/Reported { "value": } ++ ++``` ++ ++

++ ++ ++\subsection unify_schedule_entry_lock_attr_cluster_revision UnifyScheduleEntryLock/ClusterRevision Attribute ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Attributes/ClusterRevision/Reported ++[PREFIX]/UnifyScheduleEntryLock/Attributes/ClusterRevision/Desired ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock 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///UnifyScheduleEntryLock/Attributes/ClusterRevision/+' ++# Example output ++ucl/by-unid///UnifyScheduleEntryLock/Attributes/ClusterRevision/Desired { "value": } ++ucl/by-unid///UnifyScheduleEntryLock/Attributes/ClusterRevision/Reported { "value": } ++``` ++ ++ ++ ++ ++ ++

++ ++ ++ ++ ++\section unify_schedule_entry_lock_recv_cmd_support UnifyScheduleEntryLock Command Support ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/SupportedCommands ++[PREFIX]/UnifyScheduleEntryLock/SupportedGeneratedCommands ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Command Support Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "array", ++ "items" : { ++ "type": "string", ++ "enum": [ ++ "EnableSet", ++ "WeekDayReport", ++ "EnableAllSet", ++ "YearDayReport", ++ "WeekDaySet", ++ "DailyRepeatingReport", ++ "WeekDayGet", ++ "YearDaySet", ++ "YearDayGet", ++ "DailyRepeatingSet", ++ "DailyRepeatingGet", ++ "WriteAttributes", ++ "ForceReadAttributes" ++ ] ++ } ++ } ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To see supported commands for UnifyScheduleEntryLock cluster under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/SupportedCommands' ++# Example output ++ucl/by-unid///UnifyScheduleEntryLock/SupportedCommands { "value": ["EnableSet","EnableAllSet","WeekDaySet","WeekDayGet","YearDaySet","YearDayGet","DailyRepeatingSet","DailyRepeatingGet","WriteAttributes", "ForceReadAttributes"] } ++``` ++ ++To see supported generated commands for UnifyScheduleEntryLock cluster under the by-unid topic space: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/SupportedGeneratedCommands' ++# Example output ++ucl/by-unid///UnifyScheduleEntryLock/SupportedGeneratedCommands { "value": ["WeekDayReport","YearDayReport","DailyRepeatingReport",] } ++``` ++ ++ ++ ++ ++ ++

++ ++ ++ ++ ++\section unify_schedule_entry_lock_cmds UnifyScheduleEntryLock Commands ++ ++

++ ++\subsection unify_schedule_entry_lock_enable_set_cmd UnifyScheduleEntryLock/EnableSet Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/EnableSet ++[PREFIX]/UnifyScheduleEntryLock/GeneratedCommands/EnableSet ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster EnableSet Command Properties", ++ "type": "object", ++ "properties": { ++ "UserIdentifier": { ++ "type": "integer" ++ }, ++ "Enabled": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "UserIdentifier", ++ "Enabled" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To send a UnifyScheduleEntryLock/EnableSet command under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/EnableSet' -m '{ "UserIdentifier": ,"Enabled": }' ++``` ++ ++To receive a UnifyScheduleEntryLock/EnableSet generated command from a UNID/endpoint: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/GeneratedCommands/EnableSet' ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_week_day_report_cmd UnifyScheduleEntryLock/WeekDayReport Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/WeekDayReport ++[PREFIX]/UnifyScheduleEntryLock/GeneratedCommands/WeekDayReport ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster WeekDayReport Command Properties", ++ "type": "object", ++ "properties": { ++ "UserIdentifier": { ++ "type": "integer" ++ }, ++ "ScheduleSlotID": { ++ "type": "integer" ++ }, ++ "DayOfWeek": { ++ "type": "integer" ++ }, ++ "StartHour": { ++ "type": "integer" ++ }, ++ "StartMinute": { ++ "type": "integer" ++ }, ++ "StopHour": { ++ "type": "integer" ++ }, ++ "StopMinute": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "UserIdentifier", ++ "ScheduleSlotID", ++ "DayOfWeek", ++ "StartHour", ++ "StartMinute", ++ "StopHour", ++ "StopMinute" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To send a UnifyScheduleEntryLock/WeekDayReport command under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/WeekDayReport' -m '{ "UserIdentifier": ,"ScheduleSlotID": ,"DayOfWeek": ,"StartHour": ,"StartMinute": ,"StopHour": ,"StopMinute": }' ++``` ++ ++To receive a UnifyScheduleEntryLock/WeekDayReport generated command from a UNID/endpoint: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/GeneratedCommands/WeekDayReport' ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_enable_all_set_cmd UnifyScheduleEntryLock/EnableAllSet Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/EnableAllSet ++[PREFIX]/UnifyScheduleEntryLock/GeneratedCommands/EnableAllSet ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster EnableAllSet Command Properties", ++ "type": "object", ++ "properties": { ++ "Enabled": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "Enabled" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To send a UnifyScheduleEntryLock/EnableAllSet command under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/EnableAllSet' -m '{ "Enabled": }' ++``` ++ ++To receive a UnifyScheduleEntryLock/EnableAllSet generated command from a UNID/endpoint: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/GeneratedCommands/EnableAllSet' ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_year_day_report_cmd UnifyScheduleEntryLock/YearDayReport Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/YearDayReport ++[PREFIX]/UnifyScheduleEntryLock/GeneratedCommands/YearDayReport ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster YearDayReport Command Properties", ++ "type": "object", ++ "properties": { ++ "UserIdentifier": { ++ "type": "integer" ++ }, ++ "ScheduleSlotID": { ++ "type": "integer" ++ }, ++ "StartYear": { ++ "type": "integer" ++ }, ++ "StartMonth": { ++ "type": "integer" ++ }, ++ "StartDay": { ++ "type": "integer" ++ }, ++ "StartHour": { ++ "type": "integer" ++ }, ++ "StartMinute": { ++ "type": "integer" ++ }, ++ "StopYear": { ++ "type": "integer" ++ }, ++ "StopMonth": { ++ "type": "integer" ++ }, ++ "StopDay": { ++ "type": "integer" ++ }, ++ "StopHour": { ++ "type": "integer" ++ }, ++ "StopMinute": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "UserIdentifier", ++ "ScheduleSlotID", ++ "StartYear", ++ "StartMonth", ++ "StartDay", ++ "StartHour", ++ "StartMinute", ++ "StopYear", ++ "StopMonth", ++ "StopDay", ++ "StopHour", ++ "StopMinute" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To send a UnifyScheduleEntryLock/YearDayReport command under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/YearDayReport' -m '{ "UserIdentifier": ,"ScheduleSlotID": ,"StartYear": ,"StartMonth": ,"StartDay": ,"StartHour": ,"StartMinute": ,"StopYear": ,"StopMonth": ,"StopDay": ,"StopHour": ,"StopMinute": }' ++``` ++ ++To receive a UnifyScheduleEntryLock/YearDayReport generated command from a UNID/endpoint: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/GeneratedCommands/YearDayReport' ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_week_day_set_cmd UnifyScheduleEntryLock/WeekDaySet Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/WeekDaySet ++[PREFIX]/UnifyScheduleEntryLock/GeneratedCommands/WeekDaySet ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster WeekDaySet Command Properties", ++ "type": "object", ++ "properties": { ++ "SetAction": { ++ "type": "integer" ++ }, ++ "UserIdentifier": { ++ "type": "integer" ++ }, ++ "ScheduleSlotID": { ++ "type": "integer" ++ }, ++ "DayOfWeek": { ++ "type": "integer" ++ }, ++ "StartHour": { ++ "type": "integer" ++ }, ++ "StartMinute": { ++ "type": "integer" ++ }, ++ "StopHour": { ++ "type": "integer" ++ }, ++ "StopMinute": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "SetAction", ++ "UserIdentifier", ++ "ScheduleSlotID", ++ "DayOfWeek", ++ "StartHour", ++ "StartMinute", ++ "StopHour", ++ "StopMinute" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To send a UnifyScheduleEntryLock/WeekDaySet command under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/WeekDaySet' -m '{ "SetAction": ,"UserIdentifier": ,"ScheduleSlotID": ,"DayOfWeek": ,"StartHour": ,"StartMinute": ,"StopHour": ,"StopMinute": }' ++``` ++ ++To receive a UnifyScheduleEntryLock/WeekDaySet generated command from a UNID/endpoint: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/GeneratedCommands/WeekDaySet' ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_daily_repeating_report_cmd UnifyScheduleEntryLock/DailyRepeatingReport Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/DailyRepeatingReport ++[PREFIX]/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingReport ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster DailyRepeatingReport Command Properties", ++ "type": "object", ++ "properties": { ++ "UserIdentifier": { ++ "type": "integer" ++ }, ++ "ScheduleSlotID": { ++ "type": "integer" ++ }, ++ "WeekDayBitmask": { ++ "type": "integer" ++ }, ++ "StartHour": { ++ "type": "integer" ++ }, ++ "StartMinute": { ++ "type": "integer" ++ }, ++ "DurationHour": { ++ "type": "integer" ++ }, ++ "DurationMinute": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "UserIdentifier", ++ "ScheduleSlotID", ++ "WeekDayBitmask", ++ "StartHour", ++ "StartMinute", ++ "DurationHour", ++ "DurationMinute" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To send a UnifyScheduleEntryLock/DailyRepeatingReport command under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/DailyRepeatingReport' -m '{ "UserIdentifier": ,"ScheduleSlotID": ,"WeekDayBitmask": ,"StartHour": ,"StartMinute": ,"DurationHour": ,"DurationMinute": }' ++``` ++ ++To receive a UnifyScheduleEntryLock/DailyRepeatingReport generated command from a UNID/endpoint: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingReport' ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_week_day_get_cmd UnifyScheduleEntryLock/WeekDayGet Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/WeekDayGet ++[PREFIX]/UnifyScheduleEntryLock/GeneratedCommands/WeekDayGet ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster WeekDayGet Command Properties", ++ "type": "object", ++ "properties": { ++ "UserIdentifier": { ++ "type": "integer" ++ }, ++ "ScheduleSlotID": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "UserIdentifier", ++ "ScheduleSlotID" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To send a UnifyScheduleEntryLock/WeekDayGet command under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/WeekDayGet' -m '{ "UserIdentifier": ,"ScheduleSlotID": }' ++``` ++ ++To receive a UnifyScheduleEntryLock/WeekDayGet generated command from a UNID/endpoint: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/GeneratedCommands/WeekDayGet' ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_year_day_set_cmd UnifyScheduleEntryLock/YearDaySet Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/YearDaySet ++[PREFIX]/UnifyScheduleEntryLock/GeneratedCommands/YearDaySet ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster YearDaySet Command Properties", ++ "type": "object", ++ "properties": { ++ "SetAction": { ++ "type": "integer" ++ }, ++ "UserIdentifier": { ++ "type": "integer" ++ }, ++ "ScheduleSlotID": { ++ "type": "integer" ++ }, ++ "StartYear": { ++ "type": "integer" ++ }, ++ "StartDay": { ++ "type": "integer" ++ }, ++ "StartHour": { ++ "type": "integer" ++ }, ++ "StartMonth": { ++ "type": "integer" ++ }, ++ "StartMinute": { ++ "type": "integer" ++ }, ++ "StopYear": { ++ "type": "integer" ++ }, ++ "StopMonth": { ++ "type": "integer" ++ }, ++ "StopDay": { ++ "type": "integer" ++ }, ++ "StopHour": { ++ "type": "integer" ++ }, ++ "StopMinute": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "SetAction", ++ "UserIdentifier", ++ "ScheduleSlotID", ++ "StartYear", ++ "StartDay", ++ "StartHour", ++ "StartMonth", ++ "StartMinute", ++ "StopYear", ++ "StopMonth", ++ "StopDay", ++ "StopHour", ++ "StopMinute" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To send a UnifyScheduleEntryLock/YearDaySet command under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/YearDaySet' -m '{ "SetAction": ,"UserIdentifier": ,"ScheduleSlotID": ,"StartYear": ,"StartDay": ,"StartHour": ,"StartMonth": ,"StartMinute": ,"StopYear": ,"StopMonth": ,"StopDay": ,"StopHour": ,"StopMinute": }' ++``` ++ ++To receive a UnifyScheduleEntryLock/YearDaySet generated command from a UNID/endpoint: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/GeneratedCommands/YearDaySet' ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_year_day_get_cmd UnifyScheduleEntryLock/YearDayGet Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/YearDayGet ++[PREFIX]/UnifyScheduleEntryLock/GeneratedCommands/YearDayGet ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster YearDayGet Command Properties", ++ "type": "object", ++ "properties": { ++ "UserIdentifier": { ++ "type": "integer" ++ }, ++ "ScheduleSlotID": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "UserIdentifier", ++ "ScheduleSlotID" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To send a UnifyScheduleEntryLock/YearDayGet command under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/YearDayGet' -m '{ "UserIdentifier": ,"ScheduleSlotID": }' ++``` ++ ++To receive a UnifyScheduleEntryLock/YearDayGet generated command from a UNID/endpoint: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/GeneratedCommands/YearDayGet' ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_daily_repeating_set_cmd UnifyScheduleEntryLock/DailyRepeatingSet Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/DailyRepeatingSet ++[PREFIX]/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingSet ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster DailyRepeatingSet Command Properties", ++ "type": "object", ++ "properties": { ++ "SetAction": { ++ "type": "integer" ++ }, ++ "UserIdentifier": { ++ "type": "integer" ++ }, ++ "ScheduleSlotID": { ++ "type": "integer" ++ }, ++ "WeekDayBitmask": { ++ "type": "integer" ++ }, ++ "StartHour": { ++ "type": "integer" ++ }, ++ "StartMinute": { ++ "type": "integer" ++ }, ++ "DurationHour": { ++ "type": "integer" ++ }, ++ "DurationMinute": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "SetAction", ++ "UserIdentifier", ++ "ScheduleSlotID", ++ "WeekDayBitmask", ++ "StartHour", ++ "StartMinute", ++ "DurationHour", ++ "DurationMinute" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To send a UnifyScheduleEntryLock/DailyRepeatingSet command under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/DailyRepeatingSet' -m '{ "SetAction": ,"UserIdentifier": ,"ScheduleSlotID": ,"WeekDayBitmask": ,"StartHour": ,"StartMinute": ,"DurationHour": ,"DurationMinute": }' ++``` ++ ++To receive a UnifyScheduleEntryLock/DailyRepeatingSet generated command from a UNID/endpoint: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingSet' ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_daily_repeating_get_cmd UnifyScheduleEntryLock/DailyRepeatingGet Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/DailyRepeatingGet ++[PREFIX]/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingGet ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster DailyRepeatingGet Command Properties", ++ "type": "object", ++ "properties": { ++ "UserIdentifier": { ++ "type": "integer" ++ }, ++ "ScheduleSlotID": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "UserIdentifier", ++ "ScheduleSlotID" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To send a UnifyScheduleEntryLock/DailyRepeatingGet command under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/DailyRepeatingGet' -m '{ "UserIdentifier": ,"ScheduleSlotID": }' ++``` ++ ++To receive a UnifyScheduleEntryLock/DailyRepeatingGet generated command from a UNID/endpoint: ++ ++```console ++mosquitto_sub -t 'ucl/by-unid///UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingGet' ++``` ++ ++

++ ++\subsection unify_schedule_entry_lock_write_attr_cmd UnifyScheduleEntryLock/WriteAttributes Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/WriteAttributes ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster WriteAttributes Command Properties", ++ "type": "object", ++ "properties": { ++ "SlotsWeekDay": { ++ "type": "integer" ++ }, ++ "SlotsYearDay": { ++ "type": "integer" ++ }, ++ "SignTZO": { ++ "type": "integer" ++ }, ++ "HourTZO": { ++ "type": "integer" ++ }, ++ "MinuteTZO": { ++ "type": "integer" ++ }, ++ "DSTOffsetSign": { ++ "type": "integer" ++ }, ++ "DSTOffsetMinute": { ++ "type": "integer" ++ }, ++ "NumberOfSlotsDailyRepeating": { ++ "type": "integer" ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To update all UnifyScheduleEntryLock attributes under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/WriteAttributes' -m '{ "SlotsWeekDay": ,"SlotsYearDay": ,"SignTZO": ,"HourTZO": ,"MinuteTZO": ,"DSTOffsetSign": ,"DSTOffsetMinute": ,"NumberOfSlotsDailyRepeating": }' ++``` ++ ++> NOTE: Specify only the list of attributes to write in this command. ++> Unspecified attributes will not be updated. ++ ++

++ ++\subsection unify_schedule_entry_lock_force_read_attr_cmd UnifyScheduleEntryLock/ForceReadAttributes Command ++ ++**MQTT Topic Pattern:** ++ ++``` ++[PREFIX]/UnifyScheduleEntryLock/Commands/ForceReadAttributes ++``` ++ ++**MQTT Payload JSON Schema:** ++ ++```json ++{ ++ "$schema": "http://json-schema.org/draft-07/schema#", ++ "title": "UnifyScheduleEntryLock Cluster ForceReadAttributes Command Properties", ++ "type": "object", ++ "properties": { ++ "value": { ++ "type": "array" ++ "items": { ++ "type": "string", ++ "enum": [ ++ "SlotsWeekDay", ++ "SlotsYearDay", ++ "SignTZO", ++ "HourTZO", ++ "MinuteTZO", ++ "DSTOffsetSign", ++ "DSTOffsetMinute", ++ "NumberOfSlotsDailyRepeating" ++ ] ++ } ++ } ++ }, ++ "required": [ ++ "value" ++ ] ++} ++``` ++ ++**Example Mosquitto CLI Tool Usage** ++ ++To force read all UnifyScheduleEntryLock attributes under the by-unid topic space (by sending an empty array): ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/ForceReadAttributes' -m '{ "value": [] }' ++``` ++ ++To force read one of the UnifyScheduleEntryLock attributes under the by-unid topic space: ++ ++```console ++mosquitto_pub -t 'ucl/by-unid///UnifyScheduleEntryLock/Commands/ForceReadAttributes' -m '{ "value": ["SlotsWeekDay"] }' ++``` ++ ++ ++ ++ ++ ++


++ ++ + + + +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 98ebe6435d..05e39a871d 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 +@@ -2068,6 +2068,31 @@ const char *uic_dotdot_get_attribute_name(dotdot_cluster_id_t cluster_id, + return "Unknown"; + } + // clang-format off ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_CLUSTER_ID: ++ // clang-format on ++ switch (attribute_id) { ++ // clang-format off ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY_ATTRIBUTE_ID: ++ return "SlotsWeekDay"; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY_ATTRIBUTE_ID: ++ return "SlotsYearDay"; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO_ATTRIBUTE_ID: ++ return "SignTZO"; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO_ATTRIBUTE_ID: ++ return "HourTZO"; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO_ATTRIBUTE_ID: ++ return "MinuteTZO"; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN_ATTRIBUTE_ID: ++ return "DSTOffsetSign"; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE_ATTRIBUTE_ID: ++ return "DSTOffsetMinute"; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING_ATTRIBUTE_ID: ++ return "NumberOfSlotsDailyRepeating"; ++ // clang-format on ++ default: ++ return "Unknown"; ++ } ++ // clang-format off + case DOTDOT_UNIFY_HUMIDITY_CONTROL_CLUSTER_ID: + // clang-format on + switch (attribute_id) { +@@ -4529,6 +4554,32 @@ dotdot_attribute_id_t + return DOTDOT_UNIFY_THERMOSTAT_OPERATING_STATE_ATTRIBUTE_ID; + } + break; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_CLUSTER_ID: ++ if (strcmp ("SlotsWeekDay", attribute_name) == 0) { ++ return DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY_ATTRIBUTE_ID; ++ } ++ if (strcmp ("SlotsYearDay", attribute_name) == 0) { ++ return DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY_ATTRIBUTE_ID; ++ } ++ if (strcmp ("SignTZO", attribute_name) == 0) { ++ return DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO_ATTRIBUTE_ID; ++ } ++ if (strcmp ("HourTZO", attribute_name) == 0) { ++ return DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO_ATTRIBUTE_ID; ++ } ++ if (strcmp ("MinuteTZO", attribute_name) == 0) { ++ return DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO_ATTRIBUTE_ID; ++ } ++ if (strcmp ("DSTOffsetSign", attribute_name) == 0) { ++ return DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN_ATTRIBUTE_ID; ++ } ++ if (strcmp ("DSTOffsetMinute", attribute_name) == 0) { ++ return DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE_ATTRIBUTE_ID; ++ } ++ if (strcmp ("NumberOfSlotsDailyRepeating", attribute_name) == 0) { ++ return DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING_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; +@@ -6648,6 +6699,31 @@ dotdot_attribute_json_type_t + return JSON_TYPE_UNKNOWN; + } + // clang-format off ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_CLUSTER_ID: ++ // clang-format on ++ switch (attribute_id) { ++ // clang-format off ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY_ATTRIBUTE_ID: ++ return JSON_TYPE_NUMBER; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY_ATTRIBUTE_ID: ++ return JSON_TYPE_NUMBER; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO_ATTRIBUTE_ID: ++ return JSON_TYPE_NUMBER; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO_ATTRIBUTE_ID: ++ return JSON_TYPE_NUMBER; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO_ATTRIBUTE_ID: ++ return JSON_TYPE_NUMBER; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN_ATTRIBUTE_ID: ++ return JSON_TYPE_NUMBER; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE_ATTRIBUTE_ID: ++ return JSON_TYPE_NUMBER; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING_ATTRIBUTE_ID: ++ return JSON_TYPE_NUMBER; ++ // clang-format on ++ default: ++ return JSON_TYPE_UNKNOWN; ++ } ++ // clang-format off + case DOTDOT_UNIFY_HUMIDITY_CONTROL_CLUSTER_ID: + // clang-format on + switch (attribute_id) { +@@ -7046,6 +7122,9 @@ bool uic_dotdot_attribute_is_enum(dotdot_cluster_id_t cluster_id, + } + } + ++ if (64801 == cluster_id) { ++ } ++ + if (64928 == cluster_id) { + if (1 == attribute_id) { + return true; +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 4c251d9e02..d97e241b48 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 +@@ -134,6 +134,8 @@ const char* uic_dotdot_get_cluster_name(dotdot_cluster_id_t cluster_id) { + return "UnifyFanControl"; + case DOTDOT_UNIFY_THERMOSTAT_CLUSTER_ID: + return "UnifyThermostat"; ++ case DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_CLUSTER_ID: ++ return "UnifyScheduleEntryLock"; + case DOTDOT_UNIFY_HUMIDITY_CONTROL_CLUSTER_ID: + return "UnifyHumidityControl"; + default: +@@ -316,6 +318,9 @@ dotdot_cluster_id_t uic_dotdot_get_cluster_id(const char* cluster_name) { + if (strcmp ("UnifyThermostat", cluster_name) == 0) { + return DOTDOT_UNIFY_THERMOSTAT_CLUSTER_ID; + } ++ if (strcmp ("UnifyScheduleEntryLock", cluster_name) == 0) { ++ return DOTDOT_UNIFY_SCHEDULE_ENTRY_LOCK_CLUSTER_ID; ++ } + if (strcmp ("UnifyHumidityControl", cluster_name) == 0) { + return DOTDOT_UNIFY_HUMIDITY_CONTROL_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 f0fdd07d2b..2c4220eecd 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h ++++ b/components/uic_dotdot_mqtt/zap-generated/include/dotdot_mqtt.h +@@ -40140,7 +40140,16 @@ void uic_mqtt_dotdot_unify_thermostat_publish_empty_supported_commands( + const dotdot_unid_t unid + ,dotdot_endpoint_id_t endpoint); + // Callback types used by the unify_schedule_entry_lock cluster +-typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t)( ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uint8_t user_identifier, ++ ++ uint8_t enabled ++ ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t)( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, +@@ -40159,12 +40168,17 @@ typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_l + uint8_t stop_minute + + ); +-typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t)( ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t)( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, +- uint8_t set_action, ++ uint8_t enabled + ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t call_type, + uint8_t user_identifier, + + uint8_t schedule_slotid, +@@ -40190,7 +40204,96 @@ typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_l + uint8_t stop_minute + + ); +-typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t)( ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uint8_t set_action, ++ ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ ++ uint8_t day_of_week, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_minute, ++ ++ uint8_t stop_hour, ++ ++ uint8_t stop_minute ++ ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ ++ uint8_t week_day_bitmask, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_minute, ++ ++ uint8_t duration_hour, ++ ++ uint8_t duration_minute ++ ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid ++ ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uint8_t set_action, ++ ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ ++ uint8_t start_year, ++ ++ uint8_t start_day, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_month, ++ ++ uint8_t start_minute, ++ ++ uint8_t stop_year, ++ ++ uint8_t stop_month, ++ ++ uint8_t stop_day, ++ ++ uint8_t stop_hour, ++ ++ uint8_t stop_minute ++ ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid ++ ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t)( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, +@@ -40210,6 +40313,15 @@ typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_l + + uint8_t duration_minute + ++); ++typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t)( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t call_type, ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid ++ + ); + + typedef struct { +@@ -40251,7 +40363,16 @@ typedef sl_status_t (*uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attri + + + /** +- * @brief Command fields for UnifyScheduleEntryLock/ScheduleEntryLockWeekDayReport ++ * @brief Command fields for UnifyScheduleEntryLock/EnableSet ++ */ ++typedef struct { ++ uint8_t user_identifier; ++ ++ uint8_t enabled; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_set_fields_t; ++ ++/** ++ * @brief Command fields for UnifyScheduleEntryLock/WeekDayReport + */ + typedef struct { + uint8_t user_identifier; +@@ -40267,14 +40388,19 @@ typedef struct { + uint8_t stop_hour; + + uint8_t stop_minute; +-} uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t; + + /** +- * @brief Command fields for UnifyScheduleEntryLock/ScheduleEntryLockYearDayReport ++ * @brief Command fields for UnifyScheduleEntryLock/EnableAllSet + */ + typedef struct { +- uint8_t set_action; ++ uint8_t enabled; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t; + ++/** ++ * @brief Command fields for UnifyScheduleEntryLock/YearDayReport ++ */ ++typedef struct { + uint8_t user_identifier; + + uint8_t schedule_slotid; +@@ -40298,10 +40424,10 @@ typedef struct { + uint8_t stop_hour; + + uint8_t stop_minute; +-} uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t; + + /** +- * @brief Command fields for UnifyScheduleEntryLock/ScheduleEntryLockDailyRepeatingReport ++ * @brief Command fields for UnifyScheduleEntryLock/WeekDaySet + */ + typedef struct { + uint8_t set_action; +@@ -40310,6 +40436,25 @@ typedef struct { + + uint8_t schedule_slotid; + ++ uint8_t day_of_week; ++ ++ uint8_t start_hour; ++ ++ uint8_t start_minute; ++ ++ uint8_t stop_hour; ++ ++ uint8_t stop_minute; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t; ++ ++/** ++ * @brief Command fields for UnifyScheduleEntryLock/DailyRepeatingReport ++ */ ++typedef struct { ++ uint8_t user_identifier; ++ ++ uint8_t schedule_slotid; ++ + uint8_t week_day_bitmask; + + uint8_t start_hour; +@@ -40319,129 +40464,528 @@ typedef struct { + uint8_t duration_hour; + + uint8_t duration_minute; +-} uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t; ++ ++/** ++ * @brief Command fields for UnifyScheduleEntryLock/WeekDayGet ++ */ ++typedef struct { ++ uint8_t user_identifier; + ++ uint8_t schedule_slotid; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_fields_t; ++ ++/** ++ * @brief Command fields for UnifyScheduleEntryLock/YearDaySet ++ */ ++typedef struct { ++ uint8_t set_action; ++ ++ uint8_t user_identifier; ++ ++ uint8_t schedule_slotid; ++ ++ uint8_t start_year; ++ ++ uint8_t start_day; ++ ++ uint8_t start_hour; ++ ++ uint8_t start_month; ++ ++ uint8_t start_minute; ++ ++ uint8_t stop_year; ++ ++ uint8_t stop_month; ++ ++ uint8_t stop_day; + ++ uint8_t stop_hour; ++ ++ uint8_t stop_minute; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_set_fields_t; ++ ++/** ++ * @brief Command fields for UnifyScheduleEntryLock/YearDayGet ++ */ ++typedef struct { ++ uint8_t user_identifier; ++ ++ uint8_t schedule_slotid; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_fields_t; ++ ++/** ++ * @brief Command fields for UnifyScheduleEntryLock/DailyRepeatingSet ++ */ ++typedef struct { ++ uint8_t set_action; ++ ++ uint8_t user_identifier; ++ ++ uint8_t schedule_slotid; ++ ++ uint8_t week_day_bitmask; ++ ++ uint8_t start_hour; ++ ++ uint8_t start_minute; ++ ++ uint8_t duration_hour; ++ ++ uint8_t duration_minute; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_set_fields_t; ++ ++/** ++ * @brief Command fields for UnifyScheduleEntryLock/DailyRepeatingGet ++ */ ++typedef struct { ++ uint8_t user_identifier; ++ ++ uint8_t schedule_slotid; ++} uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_fields_t; ++ ++ ++/** ++ * @brief Setup callback to be called when a ++ * UnifyScheduleEntryLock/Commands/enable_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_schedule_entry_lock_enable_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * UnifyScheduleEntryLock/Commands/enable_set is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * UnifyScheduleEntryLock/Commands/enable_set is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_clear(); ++ ++/** ++ * @brief Setup callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/enable_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_schedule_entry_lock_generated_enable_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/enable_set is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/UnifyScheduleEntryLock/GeneratedCommands/enable_set is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback_clear(); ++/** ++ * @brief Setup callback to be called when a ++ * UnifyScheduleEntryLock/Commands/week_day_report 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_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * UnifyScheduleEntryLock/Commands/week_day_report is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * UnifyScheduleEntryLock/Commands/week_day_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_clear(); ++ ++/** ++ * @brief Setup callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/week_day_report 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_schedule_entry_lock_generated_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/week_day_report is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/UnifyScheduleEntryLock/GeneratedCommands/week_day_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback_clear(); ++/** ++ * @brief Setup callback to be called when a ++ * UnifyScheduleEntryLock/Commands/enable_all_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_schedule_entry_lock_enable_all_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * UnifyScheduleEntryLock/Commands/enable_all_set is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * UnifyScheduleEntryLock/Commands/enable_all_set is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_clear(); ++ ++/** ++ * @brief Setup callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/enable_all_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_schedule_entry_lock_generated_enable_all_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/enable_all_set is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/UnifyScheduleEntryLock/GeneratedCommands/enable_all_set is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback_clear(); ++/** ++ * @brief Setup callback to be called when a ++ * UnifyScheduleEntryLock/Commands/year_day_report 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_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * UnifyScheduleEntryLock/Commands/year_day_report is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * UnifyScheduleEntryLock/Commands/year_day_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_clear(); ++ ++/** ++ * @brief Setup callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/year_day_report 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_schedule_entry_lock_generated_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/year_day_report is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/UnifyScheduleEntryLock/GeneratedCommands/year_day_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback_clear(); ++/** ++ * @brief Setup callback to be called when a ++ * UnifyScheduleEntryLock/Commands/week_day_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_schedule_entry_lock_week_day_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * UnifyScheduleEntryLock/Commands/week_day_set is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * UnifyScheduleEntryLock/Commands/week_day_set is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_clear(); ++ ++/** ++ * @brief Setup callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/week_day_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_schedule_entry_lock_generated_week_day_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/week_day_set is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/UnifyScheduleEntryLock/GeneratedCommands/week_day_set is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_set_callback_clear(); ++/** ++ * @brief Setup callback to be called when a ++ * UnifyScheduleEntryLock/Commands/daily_repeating_report 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_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * UnifyScheduleEntryLock/Commands/daily_repeating_report is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * UnifyScheduleEntryLock/Commands/daily_repeating_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_clear(); ++ ++/** ++ * @brief Setup callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/daily_repeating_report 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_schedule_entry_lock_generated_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/daily_repeating_report is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/UnifyScheduleEntryLock/GeneratedCommands/daily_repeating_report is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_callback_clear(); ++/** ++ * @brief Setup callback to be called when a ++ * UnifyScheduleEntryLock/Commands/week_day_get 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_schedule_entry_lock_week_day_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * UnifyScheduleEntryLock/Commands/week_day_get is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * UnifyScheduleEntryLock/Commands/week_day_get is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_clear(); ++ ++/** ++ * @brief Setup callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/week_day_get 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_schedule_entry_lock_generated_week_day_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/week_day_get is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/UnifyScheduleEntryLock/GeneratedCommands/week_day_get is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_callback_clear(); ++/** ++ * @brief Setup callback to be called when a ++ * UnifyScheduleEntryLock/Commands/year_day_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_schedule_entry_lock_year_day_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * UnifyScheduleEntryLock/Commands/year_day_set is received. ++ * ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * UnifyScheduleEntryLock/Commands/year_day_set is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_clear(); ++ ++/** ++ * @brief Setup callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/year_day_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_schedule_entry_lock_generated_year_day_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t callback); ++/** ++ * @brief Unsets callback to be called when a ++ * +/UnifyScheduleEntryLock/GeneratedCommands/year_day_set is received. ++ * @param callback Function to be no longer called on command reception ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t callback); ++/** ++ * @brief Clears all callbacks registered for when ++ * +/UnifyScheduleEntryLock/GeneratedCommands/year_day_set is received. ++ */ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_set_callback_clear(); + /** + * @brief Setup callback to be called when a +- * UnifyScheduleEntryLock/Commands/schedule_entry_lock_week_day_report is received. ++ * UnifyScheduleEntryLock/Commands/year_day_get 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_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t callback); + /** + * @brief Unsets callback to be called when a +- * UnifyScheduleEntryLock/Commands/schedule_entry_lock_week_day_report is received. ++ * UnifyScheduleEntryLock/Commands/year_day_get is received. + * + * @param callback Function to be no longer called on command reception + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t callback); + /** + * @brief Clears all callbacks registered for when +- * UnifyScheduleEntryLock/Commands/schedule_entry_lock_week_day_report is received. ++ * UnifyScheduleEntryLock/Commands/year_day_get is received. + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_clear(); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_clear(); + + /** + * @brief Setup callback to be called when a +- * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_week_day_report is received. ++ * +/UnifyScheduleEntryLock/GeneratedCommands/year_day_get 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_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t callback); + /** + * @brief Unsets callback to be called when a +- * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_week_day_report is received. ++ * +/UnifyScheduleEntryLock/GeneratedCommands/year_day_get is received. + * @param callback Function to be no longer called on command reception + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t callback); + /** + * @brief Clears all callbacks registered for when +- * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_week_day_report is received. ++ * +/UnifyScheduleEntryLock/GeneratedCommands/year_day_get is received. + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_clear(); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback_clear(); + /** + * @brief Setup callback to be called when a +- * UnifyScheduleEntryLock/Commands/schedule_entry_lock_year_day_report is received. ++ * UnifyScheduleEntryLock/Commands/daily_repeating_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_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t callback); + /** + * @brief Unsets callback to be called when a +- * UnifyScheduleEntryLock/Commands/schedule_entry_lock_year_day_report is received. ++ * UnifyScheduleEntryLock/Commands/daily_repeating_set is received. + * + * @param callback Function to be no longer called on command reception + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t callback); + /** + * @brief Clears all callbacks registered for when +- * UnifyScheduleEntryLock/Commands/schedule_entry_lock_year_day_report is received. ++ * UnifyScheduleEntryLock/Commands/daily_repeating_set is received. + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_clear(); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_clear(); + + /** + * @brief Setup callback to be called when a +- * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_year_day_report is received. ++ * +/UnifyScheduleEntryLock/GeneratedCommands/daily_repeating_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_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t callback); + /** + * @brief Unsets callback to be called when a +- * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_year_day_report is received. ++ * +/UnifyScheduleEntryLock/GeneratedCommands/daily_repeating_set is received. + * @param callback Function to be no longer called on command reception + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t callback); + /** + * @brief Clears all callbacks registered for when +- * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_year_day_report is received. ++ * +/UnifyScheduleEntryLock/GeneratedCommands/daily_repeating_set is received. + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_clear(); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback_clear(); + /** + * @brief Setup callback to be called when a +- * UnifyScheduleEntryLock/Commands/schedule_entry_lock_daily_repeating_report is received. ++ * UnifyScheduleEntryLock/Commands/daily_repeating_get 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_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t callback); + /** + * @brief Unsets callback to be called when a +- * UnifyScheduleEntryLock/Commands/schedule_entry_lock_daily_repeating_report is received. ++ * UnifyScheduleEntryLock/Commands/daily_repeating_get is received. + * + * @param callback Function to be no longer called on command reception + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t callback); + /** + * @brief Clears all callbacks registered for when +- * UnifyScheduleEntryLock/Commands/schedule_entry_lock_daily_repeating_report is received. ++ * UnifyScheduleEntryLock/Commands/daily_repeating_get is received. + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_clear(); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_clear(); + + /** + * @brief Setup callback to be called when a +- * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_daily_repeating_report is received. ++ * +/UnifyScheduleEntryLock/GeneratedCommands/daily_repeating_get 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_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t callback); + /** + * @brief Unsets callback to be called when a +- * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_daily_repeating_report is received. ++ * +/UnifyScheduleEntryLock/GeneratedCommands/daily_repeating_get is received. + * @param callback Function to be no longer called on command reception + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t callback); + /** + * @brief Clears all callbacks registered for when +- * +/UnifyScheduleEntryLock/GeneratedCommands/schedule_entry_lock_daily_repeating_report is received. ++ * +/UnifyScheduleEntryLock/GeneratedCommands/daily_repeating_get is received. + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_clear(); ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback_clear(); + + /** + * @brief Setup a callback for WriteAttribute to be called when a +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 04e8e6b1a2..deea8690b7 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 +@@ -4998,11 +4998,11 @@ void uic_mqtt_dotdot_unify_thermostat_publish_generated_write_attributes_command + ); + + /** +- * @brief Publishes an incoming/generated ScheduleEntryLockWeekDayReport command for ++ * @brief Publishes an incoming/generated EnableSet command for + * the UnifyScheduleEntryLock cluster. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/EnableSet + * + * @param unid The UNID of the node that sent us the command. + * +@@ -5012,18 +5012,18 @@ void uic_mqtt_dotdot_unify_thermostat_publish_generated_write_attributes_command + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_lock_week_day_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_enable_set_command( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_set_fields_t *fields + + ); + /** +- * @brief Publishes an incoming/generated ScheduleEntryLockYearDayReport command for ++ * @brief Publishes an incoming/generated WeekDayReport command for + * the UnifyScheduleEntryLock cluster. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/WeekDayReport + * + * @param unid The UNID of the node that sent us the command. + * +@@ -5033,18 +5033,18 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_ + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_lock_year_day_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_week_day_report_command( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t *fields + + ); + /** +- * @brief Publishes an incoming/generated ScheduleEntryLockDailyRepeatingReport command for ++ * @brief Publishes an incoming/generated EnableAllSet command for + * the UnifyScheduleEntryLock cluster. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/EnableAllSet + * + * @param unid The UNID of the node that sent us the command. + * +@@ -5054,10 +5054,178 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_ + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_lock_daily_repeating_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_enable_all_set_command( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t *fields ++ ++); ++/** ++ * @brief Publishes an incoming/generated YearDayReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/YearDayReport ++ * ++ * @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_schedule_entry_lock_publish_generated_year_day_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t *fields ++ ++); ++/** ++ * @brief Publishes an incoming/generated WeekDaySet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/WeekDaySet ++ * ++ * @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_schedule_entry_lock_publish_generated_week_day_set_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t *fields ++ ++); ++/** ++ * @brief Publishes an incoming/generated DailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_generated_daily_repeating_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t *fields ++ ++); ++/** ++ * @brief Publishes an incoming/generated WeekDayGet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/WeekDayGet ++ * ++ * @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_schedule_entry_lock_publish_generated_week_day_get_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_fields_t *fields ++ ++); ++/** ++ * @brief Publishes an incoming/generated YearDaySet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/YearDaySet ++ * ++ * @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_schedule_entry_lock_publish_generated_year_day_set_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_set_fields_t *fields ++ ++); ++/** ++ * @brief Publishes an incoming/generated YearDayGet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/YearDayGet ++ * ++ * @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_schedule_entry_lock_publish_generated_year_day_get_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_fields_t *fields ++ ++); ++/** ++ * @brief Publishes an incoming/generated DailyRepeatingSet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingSet ++ * ++ * @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_schedule_entry_lock_publish_generated_daily_repeating_set_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_set_fields_t *fields ++ ++); ++/** ++ * @brief Publishes an incoming/generated DailyRepeatingGet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingGet ++ * ++ * @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_schedule_entry_lock_publish_generated_daily_repeating_get_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_fields_t *fields + + ); + +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 7220d03d38..1695f8ab8a 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 +@@ -3710,52 +3710,180 @@ void uic_mqtt_dotdot_by_group_unify_thermostat_write_attributes_callback_set( + + + /** +- * @brief Callback signature for by-group UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport command. ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::EnableSet command. + */ +-typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t)( ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_set_callback_t)( + const dotdot_group_id_t group_id, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_set_fields_t *fields + ); + + /** + * Setup handler to be called when a +- * ucl/by-group/+/UnifyScheduleEntryLock/schedule_entry_lock_week_day_report is received. ++ * ucl/by-group/+/UnifyScheduleEntryLock/enable_set is received. + * Setting this callback will overwrite the previous set callback. + * + */ +-void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback); ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_set_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_set_callback_t callback); + + /** +- * @brief Callback signature for by-group UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport command. ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::WeekDayReport command. + */ +-typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t)( ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback_t)( + const dotdot_group_id_t group_id, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t *fields + ); + + /** + * Setup handler to be called when a +- * ucl/by-group/+/UnifyScheduleEntryLock/schedule_entry_lock_year_day_report is received. ++ * ucl/by-group/+/UnifyScheduleEntryLock/week_day_report is received. + * Setting this callback will overwrite the previous set callback. + * + */ +-void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback); ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback_t callback); + + /** +- * @brief Callback signature for by-group UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport command. ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::EnableAllSet command. + */ +-typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t)( ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback_t)( + const dotdot_group_id_t group_id, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t *fields + ); + + /** + * Setup handler to be called when a +- * ucl/by-group/+/UnifyScheduleEntryLock/schedule_entry_lock_daily_repeating_report is received. ++ * ucl/by-group/+/UnifyScheduleEntryLock/enable_all_set is received. + * Setting this callback will overwrite the previous set callback. + * + */ +-void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback); ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback_t callback); ++ ++/** ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::YearDayReport command. ++ */ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_report_callback_t)( ++ const dotdot_group_id_t group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t *fields ++); ++ ++/** ++ * Setup handler to be called when a ++ * ucl/by-group/+/UnifyScheduleEntryLock/year_day_report is received. ++ * Setting this callback will overwrite the previous set callback. ++ * ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_report_callback_t callback); ++ ++/** ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::WeekDaySet command. ++ */ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback_t)( ++ const dotdot_group_id_t group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t *fields ++); ++ ++/** ++ * Setup handler to be called when a ++ * ucl/by-group/+/UnifyScheduleEntryLock/week_day_set is received. ++ * Setting this callback will overwrite the previous set callback. ++ * ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback_t callback); ++ ++/** ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::DailyRepeatingReport command. ++ */ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback_t)( ++ const dotdot_group_id_t group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t *fields ++); ++ ++/** ++ * Setup handler to be called when a ++ * ucl/by-group/+/UnifyScheduleEntryLock/daily_repeating_report is received. ++ * Setting this callback will overwrite the previous set callback. ++ * ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback_t callback); ++ ++/** ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::WeekDayGet command. ++ */ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_get_callback_t)( ++ const dotdot_group_id_t group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_fields_t *fields ++); ++ ++/** ++ * Setup handler to be called when a ++ * ucl/by-group/+/UnifyScheduleEntryLock/week_day_get is received. ++ * Setting this callback will overwrite the previous set callback. ++ * ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_get_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_get_callback_t callback); ++ ++/** ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::YearDaySet command. ++ */ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_set_callback_t)( ++ const dotdot_group_id_t group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_set_fields_t *fields ++); ++ ++/** ++ * Setup handler to be called when a ++ * ucl/by-group/+/UnifyScheduleEntryLock/year_day_set is received. ++ * Setting this callback will overwrite the previous set callback. ++ * ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_set_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_set_callback_t callback); ++ ++/** ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::YearDayGet command. ++ */ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_get_callback_t)( ++ const dotdot_group_id_t group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_fields_t *fields ++); ++ ++/** ++ * Setup handler to be called when a ++ * ucl/by-group/+/UnifyScheduleEntryLock/year_day_get is received. ++ * Setting this callback will overwrite the previous set callback. ++ * ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_get_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_get_callback_t callback); ++ ++/** ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::DailyRepeatingSet command. ++ */ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_set_callback_t)( ++ const dotdot_group_id_t group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_set_fields_t *fields ++); ++ ++/** ++ * Setup handler to be called when a ++ * ucl/by-group/+/UnifyScheduleEntryLock/daily_repeating_set is received. ++ * Setting this callback will overwrite the previous set callback. ++ * ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_set_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_set_callback_t callback); ++ ++/** ++ * @brief Callback signature for by-group UnifyScheduleEntryLock::DailyRepeatingGet command. ++ */ ++typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_get_callback_t)( ++ const dotdot_group_id_t group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_fields_t *fields ++); ++ ++/** ++ * Setup handler to be called when a ++ * ucl/by-group/+/UnifyScheduleEntryLock/daily_repeating_get is received. ++ * Setting this callback will overwrite the previous set callback. ++ * ++ */ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_get_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_get_callback_t callback); + + typedef void (*uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback_t)( + const dotdot_group_id_t group_id, +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 098475c6d2..09d4aea8f6 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 +@@ -7109,11 +7109,11 @@ void uic_mqtt_dotdot_unify_fan_control_publish_turn_off_command_to_group( + uint16_t destination_group_id + ); + /** +- * @brief Sends/Publishes a ScheduleEntryLockWeekDayReport command for ++ * @brief Sends/Publishes a EnableSet command for + * the UnifyScheduleEntryLock cluster to a destination. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/EnableSet + * + * @param destination_unid The UNID of the node that should receive the command. + * +@@ -7123,36 +7123,36 @@ void uic_mqtt_dotdot_unify_fan_control_publish_turn_off_command_to_group( + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_week_day_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_enable_set_command( + const dotdot_unid_t destination_unid, + const dotdot_endpoint_id_t destination_endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_set_fields_t *fields + + ); + + /** +- * @brief Sends/Publishes a ScheduleEntryLockWeekDayReport command for ++ * @brief Sends/Publishes a EnableSet command for + * the UnifyScheduleEntryLock cluster to a group. + * + * Publication will be made at the following topic +- * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/EnableSet + * + * @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_schedule_entry_lock_publish_schedule_entry_lock_week_day_report_command_to_group( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_enable_set_command_to_group( + uint16_t destination_group_id, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_set_fields_t *fields + + ); + /** +- * @brief Sends/Publishes a ScheduleEntryLockYearDayReport command for ++ * @brief Sends/Publishes a WeekDayReport command for + * the UnifyScheduleEntryLock cluster to a destination. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/WeekDayReport + * + * @param destination_unid The UNID of the node that should receive the command. + * +@@ -7162,36 +7162,36 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_week_ + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_year_day_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_week_day_report_command( + const dotdot_unid_t destination_unid, + const dotdot_endpoint_id_t destination_endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t *fields + + ); + + /** +- * @brief Sends/Publishes a ScheduleEntryLockYearDayReport command for ++ * @brief Sends/Publishes a WeekDayReport command for + * the UnifyScheduleEntryLock cluster to a group. + * + * Publication will be made at the following topic +- * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/WeekDayReport + * + * @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_schedule_entry_lock_publish_schedule_entry_lock_year_day_report_command_to_group( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_week_day_report_command_to_group( + uint16_t destination_group_id, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t *fields + + ); + /** +- * @brief Sends/Publishes a ScheduleEntryLockDailyRepeatingReport command for ++ * @brief Sends/Publishes a EnableAllSet command for + * the UnifyScheduleEntryLock cluster to a destination. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/EnableAllSet + * + * @param destination_unid The UNID of the node that should receive the command. + * +@@ -7201,28 +7201,340 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_year_ + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_daily_repeating_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_enable_all_set_command( + const dotdot_unid_t destination_unid, + const dotdot_endpoint_id_t destination_endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t *fields + + ); + + /** +- * @brief Sends/Publishes a ScheduleEntryLockDailyRepeatingReport command for ++ * @brief Sends/Publishes a EnableAllSet command for + * the UnifyScheduleEntryLock cluster to a group. + * + * Publication will be made at the following topic +- * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/EnableAllSet + * + * @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_schedule_entry_lock_publish_schedule_entry_lock_daily_repeating_report_command_to_group( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_enable_all_set_command_to_group( + uint16_t destination_group_id, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t *fields ++ ++); ++/** ++ * @brief Sends/Publishes a YearDayReport command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/YearDayReport ++ * ++ * @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_schedule_entry_lock_publish_year_day_report_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t *fields ++ ++); ++ ++/** ++ * @brief Sends/Publishes a YearDayReport command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/YearDayReport ++ * ++ * @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_schedule_entry_lock_publish_year_day_report_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t *fields ++ ++); ++/** ++ * @brief Sends/Publishes a WeekDaySet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/WeekDaySet ++ * ++ * @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_schedule_entry_lock_publish_week_day_set_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t *fields ++ ++); ++ ++/** ++ * @brief Sends/Publishes a WeekDaySet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/WeekDaySet ++ * ++ * @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_schedule_entry_lock_publish_week_day_set_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t *fields ++ ++); ++/** ++ * @brief Sends/Publishes a DailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/DailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_report_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t *fields ++ ++); ++ ++/** ++ * @brief Sends/Publishes a DailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/DailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_report_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t *fields ++ ++); ++/** ++ * @brief Sends/Publishes a WeekDayGet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/WeekDayGet ++ * ++ * @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_schedule_entry_lock_publish_week_day_get_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_fields_t *fields ++ ++); ++ ++/** ++ * @brief Sends/Publishes a WeekDayGet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/WeekDayGet ++ * ++ * @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_schedule_entry_lock_publish_week_day_get_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_fields_t *fields ++ ++); ++/** ++ * @brief Sends/Publishes a YearDaySet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/YearDaySet ++ * ++ * @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_schedule_entry_lock_publish_year_day_set_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_set_fields_t *fields ++ ++); ++ ++/** ++ * @brief Sends/Publishes a YearDaySet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/YearDaySet ++ * ++ * @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_schedule_entry_lock_publish_year_day_set_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_set_fields_t *fields ++ ++); ++/** ++ * @brief Sends/Publishes a YearDayGet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/YearDayGet ++ * ++ * @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_schedule_entry_lock_publish_year_day_get_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_fields_t *fields ++ ++); ++ ++/** ++ * @brief Sends/Publishes a YearDayGet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/YearDayGet ++ * ++ * @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_schedule_entry_lock_publish_year_day_get_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_fields_t *fields ++ ++); ++/** ++ * @brief Sends/Publishes a DailyRepeatingSet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/DailyRepeatingSet ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_set_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_set_fields_t *fields ++ ++); ++ ++/** ++ * @brief Sends/Publishes a DailyRepeatingSet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/DailyRepeatingSet ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_set_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_set_fields_t *fields ++ ++); ++/** ++ * @brief Sends/Publishes a DailyRepeatingGet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/DailyRepeatingGet ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_get_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_fields_t *fields ++ ++); ++ ++/** ++ * @brief Sends/Publishes a DailyRepeatingGet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/DailyRepeatingGet ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_get_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_fields_t *fields + + ); + /** +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 3778a1ec8c..d54fd5cd0b 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 +@@ -1696,9 +1696,17 @@ void uic_mqtt_dotdot_unify_thermostat_publish_supported_generated_commands( + * @brief Struct containing the list of commands for UnifyScheduleEntryLock + */ + typedef struct _uic_mqtt_dotdot_unify_schedule_entry_lock_supported_commands_ { +- bool schedule_entry_lock_week_day_report; +- bool schedule_entry_lock_year_day_report; +- bool schedule_entry_lock_daily_repeating_report; ++ bool enable_set; ++ bool week_day_report; ++ bool enable_all_set; ++ bool year_day_report; ++ bool week_day_set; ++ bool daily_repeating_report; ++ bool week_day_get; ++ bool year_day_set; ++ bool year_day_get; ++ bool daily_repeating_set; ++ bool daily_repeating_get; + bool write_attributes; + } uic_mqtt_dotdot_unify_schedule_entry_lock_supported_commands_t; + +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 a9ce13461d..5e796f77f2 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.cpp +@@ -93962,114 +93962,394 @@ sl_status_t uic_mqtt_dotdot_unify_thermostat_init() + } + + // Callbacks pointers +-static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback; +-static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback; +-static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback; +-static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback; +-static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback; +-static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_set_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_set_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback; ++static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback; + static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback; + static std::set uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attributes_callback; + + // Callbacks setters +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t callback) + { + if (callback != nullptr) { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback.insert(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback.insert(callback); + } + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t callback) + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback.erase(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback.erase(callback); + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_clear() ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_clear() + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback.clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback.clear(); + } +-std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback() ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback() + { +- return uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback; ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback; + } + +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t callback) + { + if (callback != nullptr) { +- uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback.insert(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback.insert(callback); + } + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t callback) + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback.erase(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback.erase(callback); + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback_clear() ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback_clear() + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback.clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback.clear(); + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t callback) + { + if (callback != nullptr) { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback.insert(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback.insert(callback); + } + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t callback) + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback.erase(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback.erase(callback); + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_clear() ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_clear() + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback.clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback.clear(); + } +-std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback() ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback() + { +- return uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback; ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback; + } + +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t callback) + { + if (callback != nullptr) { +- uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback.insert(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback.insert(callback); + } + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t callback) + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback.erase(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback.erase(callback); + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback_clear() ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback_clear() + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback.clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback.clear(); + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t callback) + { + if (callback != nullptr) { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback.insert(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback.insert(callback); + } + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t callback) + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback.erase(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback.erase(callback); + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_clear() ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_clear() + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback.clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback.clear(); + } +-std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback() ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback() + { +- return uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback; ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback; + } + +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t callback) + { + if (callback != nullptr) { +- uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback.insert(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback.insert(callback); + } + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t callback) + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback.erase(callback); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback.erase(callback); + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback_clear() ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback_clear() + { +- uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback.clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback.clear(); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback; ++} ++ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback.clear(); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback; ++} ++ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_set_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_set_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_set_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_set_callback.clear(); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback; ++} ++ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_callback.clear(); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback; ++} ++ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_callback.clear(); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback; ++} ++ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_set_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_set_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_set_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_set_callback.clear(); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback; ++} ++ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback.clear(); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback; ++} ++ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback.clear(); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback.clear(); ++} ++std::set& get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback() ++{ ++ return uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback; ++} ++ ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback_set(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t callback) ++{ ++ if (callback != nullptr) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback.insert(callback); ++ } ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback_unset(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t callback) ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback.erase(callback); ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback_clear() ++{ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback.clear(); + } + + void uic_mqtt_dotdot_set_unify_schedule_entry_lock_write_attributes_callback( +@@ -94111,13 +94391,13 @@ void uic_mqtt_dotdot_clear_unify_schedule_entry_lock_force_read_attributes_callb + } + + +-// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport +-void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/EnableSet ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_enable_set( + const char *topic, + const char *message, + const size_t message_length) + { +- if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback.empty())) { ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback.empty())) { + return; + } + +@@ -94131,12 +94411,7 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_week_day_r + } + + uint8_t user_identifier = {}; +- uint8_t schedule_slotid = {}; +- uint8_t day_of_week = {}; +- uint8_t start_hour = {}; +- uint8_t start_minute = {}; +- uint8_t stop_hour = {}; +- uint8_t stop_minute = {}; ++ uint8_t enabled = {}; + + + nlohmann::json jsn; +@@ -94144,69 +94419,49 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_week_day_r + jsn = nlohmann::json::parse(std::string(message)); + + +- uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_enable_set( + jsn, + user_identifier, + +- schedule_slotid, +- +- day_of_week, +- +- start_hour, +- +- start_minute, +- +- stop_hour, +- +- stop_minute ++ enabled + ); + + } catch (const nlohmann::json::parse_error& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport"); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "EnableSet"); + return; + } catch (const nlohmann::json::exception& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", e.what()); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableSet", e.what()); + return; + } catch (const std::exception& e) { +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", ""); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableSet", ""); + return; + } + + + +- for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback){ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback){ + callback( + static_cast(unid.c_str()), + endpoint, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, + user_identifier, + +- schedule_slotid, +- +- day_of_week, +- +- start_hour, +- +- start_minute, +- +- stop_hour, +- +- stop_minute ++ enabled + + ); + } + + } + +-// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport +-static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/EnableSet ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_enable_set( + const char *topic, + const char *message, + const size_t message_length) + { +- if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback.empty())) { ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback.empty())) { + return; + } + +@@ -94220,12 +94475,7 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + } + + uint8_t user_identifier = {}; +- uint8_t schedule_slotid = {}; +- uint8_t day_of_week = {}; +- uint8_t start_hour = {}; +- uint8_t start_minute = {}; +- uint8_t stop_hour = {}; +- uint8_t stop_minute = {}; ++ uint8_t enabled = {}; + + + nlohmann::json jsn; +@@ -94233,70 +94483,50 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + jsn = nlohmann::json::parse(std::string(message)); + + +- uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_enable_set( + jsn, + user_identifier, + +- schedule_slotid, +- +- day_of_week, +- +- start_hour, +- +- start_minute, +- +- stop_hour, +- +- stop_minute ++ enabled + ); + + } catch (const nlohmann::json::parse_error& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport"); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "EnableSet"); + return; + } catch (const nlohmann::json::exception& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", e.what()); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableSet", e.what()); + return; + } catch (const std::exception& e) { +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", ""); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableSet", ""); + return; + } + + + + +- for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback){ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback){ + callback( + static_cast(unid.c_str()), + endpoint, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, + user_identifier, + +- schedule_slotid, +- +- day_of_week, +- +- start_hour, +- +- start_minute, +- +- stop_hour, +- +- stop_minute ++ enabled + + ); + } + } + + +-// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport +-void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WeekDayReport ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_report( + const char *topic, + const char *message, + const size_t message_length) + { +- if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback.empty())) { ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback.empty())) { + return; + } + +@@ -94309,17 +94539,11 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_r + return; + } + +- uint8_t set_action = {}; + uint8_t user_identifier = {}; + uint8_t schedule_slotid = {}; +- uint8_t start_year = {}; +- uint8_t start_month = {}; +- uint8_t start_day = {}; ++ uint8_t day_of_week = {}; + uint8_t start_hour = {}; + uint8_t start_minute = {}; +- uint8_t stop_year = {}; +- uint8_t stop_month = {}; +- uint8_t stop_day = {}; + uint8_t stop_hour = {}; + uint8_t stop_minute = {}; + +@@ -94329,30 +94553,18 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_r + jsn = nlohmann::json::parse(std::string(message)); + + +- uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_report( + jsn, +- set_action, +- + user_identifier, + + schedule_slotid, + +- start_year, +- +- start_month, +- +- start_day, ++ day_of_week, + + start_hour, + + start_minute, + +- stop_year, +- +- stop_month, +- +- stop_day, +- + stop_hour, + + stop_minute +@@ -94360,46 +94572,34 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_r + + } catch (const nlohmann::json::parse_error& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport"); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "WeekDayReport"); + return; + } catch (const nlohmann::json::exception& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", e.what()); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayReport", e.what()); + return; + } catch (const std::exception& e) { +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", ""); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayReport", ""); + return; + } + + + +- for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback){ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback){ + callback( + static_cast(unid.c_str()), + endpoint, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, +- set_action, +- + user_identifier, + + schedule_slotid, + +- start_year, +- +- start_month, +- +- start_day, ++ day_of_week, + + start_hour, + + start_minute, + +- stop_year, +- +- stop_month, +- +- stop_day, +- + stop_hour, + + stop_minute +@@ -94409,13 +94609,13 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_r + + } + +-// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport +-static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/WeekDayReport ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_week_day_report( + const char *topic, + const char *message, + const size_t message_length) + { +- if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback.empty())) { ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback.empty())) { + return; + } + +@@ -94428,17 +94628,11 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + return; + } + +- uint8_t set_action = {}; + uint8_t user_identifier = {}; + uint8_t schedule_slotid = {}; +- uint8_t start_year = {}; +- uint8_t start_month = {}; +- uint8_t start_day = {}; ++ uint8_t day_of_week = {}; + uint8_t start_hour = {}; + uint8_t start_minute = {}; +- uint8_t stop_year = {}; +- uint8_t stop_month = {}; +- uint8_t stop_day = {}; + uint8_t stop_hour = {}; + uint8_t stop_minute = {}; + +@@ -94448,30 +94642,18 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + jsn = nlohmann::json::parse(std::string(message)); + + +- uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_report( + jsn, +- set_action, +- + user_identifier, + + schedule_slotid, + +- start_year, +- +- start_month, +- +- start_day, ++ day_of_week, + + start_hour, + + start_minute, + +- stop_year, +- +- stop_month, +- +- stop_day, +- + stop_hour, + + stop_minute +@@ -94479,47 +94661,35 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + + } catch (const nlohmann::json::parse_error& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport"); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "WeekDayReport"); + return; + } catch (const nlohmann::json::exception& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", e.what()); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayReport", e.what()); + return; + } catch (const std::exception& e) { +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", ""); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayReport", ""); + return; + } + + + + +- for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback){ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback){ + callback( + static_cast(unid.c_str()), + endpoint, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, +- set_action, +- + user_identifier, + + schedule_slotid, + +- start_year, +- +- start_month, +- +- start_day, ++ day_of_week, + + start_hour, + + start_minute, + +- stop_year, +- +- stop_month, +- +- stop_day, +- + stop_hour, + + stop_minute +@@ -94529,13 +94699,13 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + } + + +-// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport +-void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/EnableAllSet ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_enable_all_set( + const char *topic, + const char *message, + const size_t message_length) + { +- if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback.empty())) { ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback.empty())) { + return; + } + +@@ -94548,14 +94718,7 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_daily_repe + return; + } + +- uint8_t set_action = {}; +- uint8_t user_identifier = {}; +- uint8_t schedule_slotid = {}; +- uint8_t week_day_bitmask = {}; +- uint8_t start_hour = {}; +- uint8_t start_minute = {}; +- uint8_t duration_hour = {}; +- uint8_t duration_minute = {}; ++ uint8_t enabled = {}; + + + nlohmann::json jsn; +@@ -94563,73 +94726,105 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_daily_repe + jsn = nlohmann::json::parse(std::string(message)); + + +- uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_enable_all_set( + jsn, +- set_action, ++ enabled ++ ); + +- user_identifier, ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "EnableAllSet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableAllSet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableAllSet", ""); ++ return; ++ } + +- schedule_slotid, + +- week_day_bitmask, + +- start_hour, ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ enabled ++ ++ ); ++ } + +- start_minute, ++} + +- duration_hour, ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/EnableAllSet ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_enable_all_set( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback.empty())) { ++ return; ++ } + +- duration_minute ++ 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; ++ } ++ ++ uint8_t enabled = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_enable_all_set( ++ jsn, ++ enabled + ); + + } catch (const nlohmann::json::parse_error& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport"); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "EnableAllSet"); + return; + } catch (const nlohmann::json::exception& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", e.what()); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableAllSet", e.what()); + return; + } catch (const std::exception& e) { +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", ""); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableAllSet", ""); + return; + } + + + +- for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback){ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback){ + callback( + static_cast(unid.c_str()), + endpoint, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, +- set_action, +- +- user_identifier, +- +- schedule_slotid, +- +- week_day_bitmask, +- +- start_hour, +- +- start_minute, +- +- duration_hour, +- +- duration_minute ++ enabled + + ); + } +- + } + +-// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport +-static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/YearDayReport ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_report( + const char *topic, + const char *message, + const size_t message_length) + { +- if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback.empty())) { ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback.empty())) { + return; + } + +@@ -94642,14 +94837,18 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + return; + } + +- uint8_t set_action = {}; + uint8_t user_identifier = {}; + uint8_t schedule_slotid = {}; +- uint8_t week_day_bitmask = {}; ++ uint8_t start_year = {}; ++ uint8_t start_month = {}; ++ uint8_t start_day = {}; + uint8_t start_hour = {}; + uint8_t start_minute = {}; +- uint8_t duration_hour = {}; +- uint8_t duration_minute = {}; ++ uint8_t stop_year = {}; ++ uint8_t stop_month = {}; ++ uint8_t stop_day = {}; ++ uint8_t stop_hour = {}; ++ uint8_t stop_minute = {}; + + + nlohmann::json jsn; +@@ -94657,78 +94856,89 @@ static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entr + jsn = nlohmann::json::parse(std::string(message)); + + +- uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_report( + jsn, +- set_action, +- + user_identifier, + + schedule_slotid, + +- week_day_bitmask, ++ start_year, ++ ++ start_month, ++ ++ start_day, + + start_hour, + + start_minute, + +- duration_hour, ++ stop_year, + +- duration_minute ++ stop_month, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute + ); + + } catch (const nlohmann::json::parse_error& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport"); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "YearDayReport"); + return; + } catch (const nlohmann::json::exception& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", e.what()); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayReport", e.what()); + return; + } catch (const std::exception& e) { +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", ""); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayReport", ""); + return; + } + + + +- +- for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback){ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback){ + callback( + static_cast(unid.c_str()), + endpoint, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, +- set_action, +- + user_identifier, + + schedule_slotid, + +- week_day_bitmask, ++ start_year, ++ ++ start_month, ++ ++ start_day, + + start_hour, + + start_minute, + +- duration_hour, ++ stop_year, + +- duration_minute ++ stop_month, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute + + ); + } +-} + ++} + +-// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WriteAttributes +-void uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes( ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/YearDayReport ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_year_day_report( + const char *topic, + const char *message, + const size_t message_length) + { +- if (uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback.empty()) { +- return; +- } +- +- if (message_length == 0) { ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback.empty())) { + return; + } + +@@ -94741,66 +94951,1368 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes( + return; + } + +- uic_mqtt_dotdot_unify_schedule_entry_lock_state_t new_state = {}; +- uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t new_updated_state = {}; ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t start_year = {}; ++ uint8_t start_month = {}; ++ uint8_t start_day = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t stop_year = {}; ++ uint8_t stop_month = {}; ++ uint8_t stop_day = {}; ++ uint8_t stop_hour = {}; ++ uint8_t stop_minute = {}; + + + nlohmann::json jsn; + try { + jsn = nlohmann::json::parse(std::string(message)); + +- uic_mqtt_dotdot_parse_unify_schedule_entry_lock_write_attributes( ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_report( + jsn, +- new_state, +- new_updated_state +- ); ++ user_identifier, ++ ++ schedule_slotid, ++ ++ start_year, ++ ++ start_month, ++ ++ start_day, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_year, ++ ++ stop_month, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute ++ ); ++ + } catch (const nlohmann::json::parse_error& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "WriteAttributes"); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "YearDayReport"); + return; + } catch (const nlohmann::json::exception& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", e.what()); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayReport", e.what()); + return; + } catch (const std::exception& e) { +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", ""); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayReport", ""); + return; + } + +- for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback){ ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback){ + callback( + static_cast(unid.c_str()), + endpoint, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, +- new_state, +- new_updated_state ++ user_identifier, ++ ++ schedule_slotid, ++ ++ start_year, ++ ++ start_month, ++ ++ start_day, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_year, ++ ++ stop_month, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute ++ + ); + } +- + } + +-static void uic_mqtt_dotdot_on_unify_schedule_entry_lock_force_read_attributes( ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WeekDaySet ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_set( + 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_schedule_entry_lock_force_read_attributes_callback.empty())) { ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback.empty())) { + return; + } + +- if(! uic_dotdot_mqtt::parse_topic(topic, unid, endpoint)) { ++ 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; + } + +- try { +- uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t force_update = {0}; +- bool trigger_handler = false; ++ uint8_t set_action = {}; ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t day_of_week = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t stop_hour = {}; ++ uint8_t stop_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_set( ++ jsn, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ day_of_week, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_hour, ++ ++ stop_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "WeekDaySet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDaySet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDaySet", ""); ++ return; ++ } ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ day_of_week, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_hour, ++ ++ stop_minute ++ ++ ); ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/WeekDaySet ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_week_day_set( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_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; ++ } ++ ++ uint8_t set_action = {}; ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t day_of_week = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t stop_hour = {}; ++ uint8_t stop_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_set( ++ jsn, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ day_of_week, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_hour, ++ ++ stop_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "WeekDaySet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDaySet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDaySet", ""); ++ return; ++ } ++ ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_set_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ day_of_week, ++ ++ start_hour, ++ ++ start_minute, ++ ++ stop_hour, ++ ++ stop_minute ++ ++ ); ++ } ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/DailyRepeatingReport ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_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; ++ } ++ ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t week_day_bitmask = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t duration_hour = {}; ++ uint8_t duration_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_report( ++ jsn, ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "DailyRepeatingReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingReport", ""); ++ return; ++ } ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ++ ); ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingReport ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_daily_repeating_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_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; ++ } ++ ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t week_day_bitmask = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t duration_hour = {}; ++ uint8_t duration_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_report( ++ jsn, ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "DailyRepeatingReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingReport", ""); ++ return; ++ } ++ ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ++ ); ++ } ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WeekDayGet ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_get( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_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; ++ } ++ ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_get( ++ jsn, ++ user_identifier, ++ ++ schedule_slotid ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "WeekDayGet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayGet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayGet", ""); ++ return; ++ } ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ user_identifier, ++ ++ schedule_slotid ++ ++ ); ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/WeekDayGet ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_week_day_get( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_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; ++ } ++ ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_get( ++ jsn, ++ user_identifier, ++ ++ schedule_slotid ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "WeekDayGet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayGet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayGet", ""); ++ return; ++ } ++ ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ user_identifier, ++ ++ schedule_slotid ++ ++ ); ++ } ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/YearDaySet ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_set( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_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; ++ } ++ ++ uint8_t set_action = {}; ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t start_year = {}; ++ uint8_t start_day = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_month = {}; ++ uint8_t start_minute = {}; ++ uint8_t stop_year = {}; ++ uint8_t stop_month = {}; ++ uint8_t stop_day = {}; ++ uint8_t stop_hour = {}; ++ uint8_t stop_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_set( ++ jsn, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ start_year, ++ ++ start_day, ++ ++ start_hour, ++ ++ start_month, ++ ++ start_minute, ++ ++ stop_year, ++ ++ stop_month, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "YearDaySet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDaySet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDaySet", ""); ++ return; ++ } ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ start_year, ++ ++ start_day, ++ ++ start_hour, ++ ++ start_month, ++ ++ start_minute, ++ ++ stop_year, ++ ++ stop_month, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute ++ ++ ); ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/YearDaySet ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_year_day_set( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_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; ++ } ++ ++ uint8_t set_action = {}; ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t start_year = {}; ++ uint8_t start_day = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_month = {}; ++ uint8_t start_minute = {}; ++ uint8_t stop_year = {}; ++ uint8_t stop_month = {}; ++ uint8_t stop_day = {}; ++ uint8_t stop_hour = {}; ++ uint8_t stop_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_set( ++ jsn, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ start_year, ++ ++ start_day, ++ ++ start_hour, ++ ++ start_month, ++ ++ start_minute, ++ ++ stop_year, ++ ++ stop_month, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "YearDaySet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDaySet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDaySet", ""); ++ return; ++ } ++ ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_set_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ start_year, ++ ++ start_day, ++ ++ start_hour, ++ ++ start_month, ++ ++ start_minute, ++ ++ stop_year, ++ ++ stop_month, ++ ++ stop_day, ++ ++ stop_hour, ++ ++ stop_minute ++ ++ ); ++ } ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/YearDayGet ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_get( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_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; ++ } ++ ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_get( ++ jsn, ++ user_identifier, ++ ++ schedule_slotid ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "YearDayGet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayGet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayGet", ""); ++ return; ++ } ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ user_identifier, ++ ++ schedule_slotid ++ ++ ); ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/YearDayGet ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_year_day_get( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_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; ++ } ++ ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_get( ++ jsn, ++ user_identifier, ++ ++ schedule_slotid ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "YearDayGet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayGet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayGet", ""); ++ return; ++ } ++ ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ user_identifier, ++ ++ schedule_slotid ++ ++ ); ++ } ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/DailyRepeatingSet ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_set( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_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; ++ } ++ ++ uint8_t set_action = {}; ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t week_day_bitmask = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t duration_hour = {}; ++ uint8_t duration_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_set( ++ jsn, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "DailyRepeatingSet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingSet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingSet", ""); ++ return; ++ } ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ++ ); ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingSet ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_daily_repeating_set( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_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; ++ } ++ ++ uint8_t set_action = {}; ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ uint8_t week_day_bitmask = {}; ++ uint8_t start_hour = {}; ++ uint8_t start_minute = {}; ++ uint8_t duration_hour = {}; ++ uint8_t duration_minute = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_set( ++ jsn, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "DailyRepeatingSet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingSet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingSet", ""); ++ return; ++ } ++ ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ set_action, ++ ++ user_identifier, ++ ++ schedule_slotid, ++ ++ week_day_bitmask, ++ ++ start_hour, ++ ++ start_minute, ++ ++ duration_hour, ++ ++ duration_minute ++ ++ ); ++ } ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/DailyRepeatingGet ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_get( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_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; ++ } ++ ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_get( ++ jsn, ++ user_identifier, ++ ++ schedule_slotid ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "DailyRepeatingGet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingGet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingGet", ""); ++ return; ++ } ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ user_identifier, ++ ++ schedule_slotid ++ ++ ); ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingGet ++static void uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_daily_repeating_get( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (message_length == 0 || (uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_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; ++ } ++ ++ uint8_t user_identifier = {}; ++ uint8_t schedule_slotid = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_get( ++ jsn, ++ user_identifier, ++ ++ schedule_slotid ++ ); ++ ++ } catch (const nlohmann::json::parse_error& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "DailyRepeatingGet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingGet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingGet", ""); ++ return; ++ } ++ ++ ++ ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback){ ++ callback( ++ static_cast(unid.c_str()), ++ endpoint, ++ UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, ++ user_identifier, ++ ++ schedule_slotid ++ ++ ); ++ } ++} ++ ++ ++// Callback function for incoming publications on ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WriteAttributes ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_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_schedule_entry_lock_state_t new_state = {}; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t new_updated_state = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_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, "UnifyScheduleEntryLock", "WriteAttributes"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", ""); ++ return; ++ } ++ ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_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_schedule_entry_lock_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_schedule_entry_lock_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_schedule_entry_lock_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>(); +@@ -95428,29 +96940,93 @@ sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_init() + subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/ForceReadAttributes"; + uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_force_read_attributes); + } +- if (!uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback.empty()) { +- subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport"; +- uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_week_day_report); ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/EnableSet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_enable_set); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_set_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/EnableSet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_enable_set); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/WeekDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_report); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/WeekDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_week_day_report); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/EnableAllSet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_enable_all_set); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_enable_all_set_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/EnableAllSet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_enable_all_set); + } +- if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_week_day_report_callback.empty()) { +- subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport"; +- uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_week_day_report); ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/YearDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_report); + } +- if (!uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback.empty()) { +- subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport"; +- uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_report); ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/YearDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_year_day_report); + } +- if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_year_day_report_callback.empty()) { +- subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport"; +- uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_year_day_report); ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/WeekDaySet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_set); + } +- if (!uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback.empty()) { +- subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport"; +- uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report); ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_set_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/WeekDaySet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_week_day_set); + } +- if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_schedule_entry_lock_daily_repeating_report_callback.empty()) { +- subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport"; +- uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report); ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/DailyRepeatingReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_report); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_report_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_daily_repeating_report); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/WeekDayGet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_get); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_week_day_get_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/WeekDayGet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_week_day_get); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/YearDaySet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_set); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_set_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/YearDaySet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_year_day_set); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/YearDayGet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_get); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_year_day_get_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/YearDayGet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_year_day_get); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/DailyRepeatingSet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_set); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_set_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingSet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_daily_repeating_set); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/Commands/DailyRepeatingGet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_get); ++ } ++ if (!uic_mqtt_dotdot_unify_schedule_entry_lock_generated_daily_repeating_get_callback.empty()) { ++ subscription_topic = base_topic + "UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingGet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_generated_unify_schedule_entry_lock_daily_repeating_get); + } + + // Init the attributes for that cluster +@@ -111296,48 +112872,194 @@ void uic_mqtt_dotdot_unify_thermostat_publish_empty_supported_commands( + strlen(EMPTY_VALUE_ARRAY), + true); + } +-} ++} ++ ++// Publishing Cluster Revision for UnifyScheduleEntryLock Cluster ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_cluster_revision(const char* base_topic, uint16_t value) ++{ ++ std::string cluster_topic = std::string(base_topic) + "/UnifyScheduleEntryLock/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 UnifyScheduleEntryLock Cluster ++void uic_mqtt_dotdot_unify_schedule_entry_lock_unretain_cluster_revision(const char* base_topic) ++{ ++ // clang-format on ++ std::string cluster_topic ++ = std::string(base_topic) ++ + "/UnifyScheduleEntryLock/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_schedule_entry_lock_enable_set_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t enabled_value; ++ memset(&enabled_value, 0x00, sizeof(enabled_value)); ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback) { ++ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ enabled_value ++ ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ ++ return false; ++} ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t day_of_week_value; ++ memset(&day_of_week_value, 0x00, sizeof(day_of_week_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback) { ++ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ day_of_week_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ ++ return false; ++} ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ uint8_t enabled_value; ++ memset(&enabled_value, 0x00, sizeof(enabled_value)); ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback) { ++ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ enabled_value ++ ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } + +-// Publishing Cluster Revision for UnifyScheduleEntryLock Cluster +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_cluster_revision(const char* base_topic, uint16_t value) +-{ +- std::string cluster_topic = std::string(base_topic) + "/UnifyScheduleEntryLock/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); ++ return false; + } +- +-// Unretain Cluster Revision for UnifyScheduleEntryLock Cluster +-void uic_mqtt_dotdot_unify_schedule_entry_lock_unretain_cluster_revision(const char* base_topic) ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) + { +- // clang-format on +- std::string cluster_topic +- = std::string(base_topic) +- + "/UnifyScheduleEntryLock/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 +-} ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t start_year_value; ++ memset(&start_year_value, 0x00, sizeof(start_year_value)); ++ uint8_t start_month_value; ++ memset(&start_month_value, 0x00, sizeof(start_month_value)); ++ uint8_t start_day_value; ++ memset(&start_day_value, 0x00, sizeof(start_day_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_year_value; ++ memset(&stop_year_value, 0x00, sizeof(stop_year_value)); ++ uint8_t stop_month_value; ++ memset(&stop_month_value, 0x00, sizeof(stop_month_value)); ++ uint8_t stop_day_value; ++ memset(&stop_day_value, 0x00, sizeof(stop_day_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback) { ++ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ start_year_value, ++ ++ start_month_value, ++ ++ start_day_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ stop_year_value, ++ ++ stop_month_value, ++ ++ stop_day_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } + +-static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_is_supported( ++ return false; ++} ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_is_supported( + const dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint_id) + { ++ uint8_t set_action_value; ++ memset(&set_action_value, 0x00, sizeof(set_action_value)); + uint8_t user_identifier_value; + memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); + uint8_t schedule_slotid_value; +@@ -111352,9 +113074,11 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); + uint8_t stop_minute_value; + memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); +- for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback) { ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback) { + if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK + , ++ set_action_value, ++ + user_identifier_value, + + schedule_slotid_value, +@@ -111376,7 +113100,71 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + + return false; + } +-static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_is_supported( ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t week_day_bitmask_value; ++ memset(&week_day_bitmask_value, 0x00, sizeof(week_day_bitmask_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t duration_hour_value; ++ memset(&duration_hour_value, 0x00, sizeof(duration_hour_value)); ++ uint8_t duration_minute_value; ++ memset(&duration_minute_value, 0x00, sizeof(duration_minute_value)); ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback) { ++ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ week_day_bitmask_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ duration_hour_value, ++ ++ duration_minute_value ++ ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ ++ return false; ++} ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback) { ++ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value ++ ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ ++ return false; ++} ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_is_supported( + const dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint_id) + { +@@ -111388,12 +113176,12 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); + uint8_t start_year_value; + memset(&start_year_value, 0x00, sizeof(start_year_value)); +- uint8_t start_month_value; +- memset(&start_month_value, 0x00, sizeof(start_month_value)); + uint8_t start_day_value; + memset(&start_day_value, 0x00, sizeof(start_day_value)); + uint8_t start_hour_value; + memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_month_value; ++ memset(&start_month_value, 0x00, sizeof(start_month_value)); + uint8_t start_minute_value; + memset(&start_minute_value, 0x00, sizeof(start_minute_value)); + uint8_t stop_year_value; +@@ -111406,7 +113194,7 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); + uint8_t stop_minute_value; + memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); +- for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback) { ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback) { + if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK + , + set_action_value, +@@ -111417,12 +113205,12 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + + start_year_value, + +- start_month_value, +- + start_day_value, + + start_hour_value, + ++ start_month_value, ++ + start_minute_value, + + stop_year_value, +@@ -111442,7 +113230,29 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + + return false; + } +-static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_is_supported( ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback) { ++ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value ++ ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ ++ return false; ++} ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_is_supported( + const dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint_id) + { +@@ -111462,7 +113272,7 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + memset(&duration_hour_value, 0x00, sizeof(duration_hour_value)); + uint8_t duration_minute_value; + memset(&duration_minute_value, 0x00, sizeof(duration_minute_value)); +- for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback) { ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback) { + if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK + , + set_action_value, +@@ -111488,6 +113298,28 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + + return false; + } ++static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_is_supported( ++ const dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint_id) ++{ ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ for (const auto& callback: uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback) { ++ if (callback( unid, endpoint_id, UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value ++ ++ ) == SL_STATUS_OK) { ++ return true; ++ } ++ } ++ ++ return false; ++} + + static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_is_supported( + const dotdot_unid_t unid, +@@ -111525,39 +113357,95 @@ static inline bool uic_mqtt_dotdot_unify_schedule_entry_lock_force_read_attribut + return true; + } + } +- return false; +-} +- +-// Publishing Supported Commands for UnifyScheduleEntryLock Cluster +-void uic_mqtt_dotdot_unify_schedule_entry_lock_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_schedule_entry_lock_schedule_entry_lock_week_day_report_is_supported(unid, endpoint_id)) { ++ return false; ++} ++ ++// Publishing Supported Commands for UnifyScheduleEntryLock Cluster ++void uic_mqtt_dotdot_unify_schedule_entry_lock_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_schedule_entry_lock_enable_set_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("EnableSet")"; ++ } ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("WeekDayReport")"; ++ } ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("EnableAllSet")"; ++ } ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("YearDayReport")"; ++ } ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("WeekDaySet")"; ++ } ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("DailyRepeatingReport")"; ++ } ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("WeekDayGet")"; ++ } ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_is_supported(unid, endpoint_id)) { ++ if (first_command == false) { ++ ss << ", "; ++ } ++ first_command = false; ++ ss << R"("YearDaySet")"; ++ } ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_is_supported(unid, endpoint_id)) { + if (first_command == false) { + ss << ", "; + } + first_command = false; +- ss << R"("ScheduleEntryLockWeekDayReport")"; ++ ss << R"("YearDayGet")"; + } +- if (uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_is_supported(unid, endpoint_id)) { ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_is_supported(unid, endpoint_id)) { + if (first_command == false) { + ss << ", "; + } + first_command = false; +- ss << R"("ScheduleEntryLockYearDayReport")"; ++ ss << R"("DailyRepeatingSet")"; + } +- if (uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_is_supported(unid, endpoint_id)) { ++ if (uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_is_supported(unid, endpoint_id)) { + if (first_command == false) { + ss << ", "; + } + first_command = false; +- ss << R"("ScheduleEntryLockDailyRepeatingReport")"; ++ ss << R"("DailyRepeatingGet")"; + } + + // Check for a WriteAttributes Callback +@@ -118468,11 +120356,299 @@ void uic_mqtt_dotdot_unify_fan_control_publish_generated_turn_off_command( + false); + } + /** +- * @brief Publishes an incoming/generated ScheduleEntryLockWeekDayReport command for ++ * @brief Publishes an incoming/generated EnableSet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/EnableSet ++ * ++ * @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_schedule_entry_lock_publish_generated_enable_set_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_set_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/EnableSet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_enable_set_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated WeekDayReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/WeekDayReport ++ * ++ * @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_schedule_entry_lock_publish_generated_week_day_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/WeekDayReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_week_day_report_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated EnableAllSet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/EnableAllSet ++ * ++ * @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_schedule_entry_lock_publish_generated_enable_all_set_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/EnableAllSet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_enable_all_set_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated YearDayReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/YearDayReport ++ * ++ * @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_schedule_entry_lock_publish_generated_year_day_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/YearDayReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_year_day_report_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated WeekDaySet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/WeekDaySet ++ * ++ * @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_schedule_entry_lock_publish_generated_week_day_set_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/WeekDaySet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_week_day_set_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated DailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_generated_daily_repeating_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_report_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated WeekDayGet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/WeekDayGet ++ * ++ * @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_schedule_entry_lock_publish_generated_week_day_get_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/WeekDayGet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_week_day_get_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated YearDaySet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/YearDaySet ++ * ++ * @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_schedule_entry_lock_publish_generated_year_day_set_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_set_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/YearDaySet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_year_day_set_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated YearDayGet command for + * the UnifyScheduleEntryLock cluster. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/YearDayGet + * + * @param unid The UNID of the node that sent us the command. + * +@@ -118482,19 +120658,19 @@ void uic_mqtt_dotdot_unify_fan_control_publish_generated_turn_off_command( + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_lock_week_day_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_year_day_get_command( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_fields_t *fields + + ) { + // Create the topic + std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + + std::to_string(endpoint) + "/"; +- topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/YearDayGet"; + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_year_day_get_command( + fields); + + // Publish our command +@@ -118504,11 +120680,11 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_ + false); + } + /** +- * @brief Publishes an incoming/generated ScheduleEntryLockYearDayReport command for ++ * @brief Publishes an incoming/generated DailyRepeatingSet command for + * the UnifyScheduleEntryLock cluster. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingSet + * + * @param unid The UNID of the node that sent us the command. + * +@@ -118518,19 +120694,19 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_ + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_lock_year_day_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_daily_repeating_set_command( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_set_fields_t *fields + + ) { + // Create the topic + std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + + std::to_string(endpoint) + "/"; +- topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingSet"; + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_set_command( + fields); + + // Publish our command +@@ -118540,11 +120716,11 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_ + false); + } + /** +- * @brief Publishes an incoming/generated ScheduleEntryLockDailyRepeatingReport command for ++ * @brief Publishes an incoming/generated DailyRepeatingGet command for + * the UnifyScheduleEntryLock cluster. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingGet + * + * @param unid The UNID of the node that sent us the command. + * +@@ -118554,19 +120730,19 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_ + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_lock_daily_repeating_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_daily_repeating_get_command( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_fields_t *fields + + ) { + // Create the topic + std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + + std::to_string(endpoint) + "/"; +- topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingGet"; + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_get_command( + fields); + + // Publish our command +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 bb5785ac9c..400b1cc45d 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.hpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt.hpp +@@ -5070,22 +5070,43 @@ void uic_mqtt_dotdot_on_unify_fan_control_WriteAttributes( + 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_thermostat_write_attributes_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyThermostat/Commands/WriteAttributes ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_thermostat_WriteAttributes( ++ const char *topic, ++ const char *message, ++ const size_t message_length); ++ ++ + // clang-format on + + /** + * @brief Retrieves the container with callbacks pointer for +- * by-unid UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport messages ++ * by-unid UnifyScheduleEntryLock/Commands/EnableSet messages + * + * @returns std::set of callbacks. + */ +-std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback(); ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback(); + + /** + * @brief MQTT Subscribe handler for incoming publications on: +- * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/EnableSet + */ + // clang-format off +-void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_enable_set( + const char *topic, + const char *message, + const size_t message_length); +@@ -5093,18 +5114,18 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_week_day_r + + /** + * @brief Retrieves the container with callbacks pointer for +- * by-unid UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport messages ++ * by-unid UnifyScheduleEntryLock/Commands/WeekDayReport messages + * + * @returns std::set of callbacks. + */ +-std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback(); ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback(); + + /** + * @brief MQTT Subscribe handler for incoming publications on: +- * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WeekDayReport + */ + // clang-format off +-void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_report( + const char *topic, + const char *message, + const size_t message_length); +@@ -5112,42 +5133,173 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_r + + /** + * @brief Retrieves the container with callbacks pointer for +- * by-unid UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport messages ++ * by-unid UnifyScheduleEntryLock/Commands/EnableAllSet messages + * + * @returns std::set of callbacks. + */ +-std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback(); ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback(); + + /** + * @brief MQTT Subscribe handler for incoming publications on: +- * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/EnableAllSet + */ + // clang-format off +-void uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_enable_all_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 ++ * @brief Retrieves the container with callbacks pointer for ++ * by-unid UnifyScheduleEntryLock/Commands/YearDayReport messages + * + * @returns std::set of callbacks. + */ +-std::set & get_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback(); ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback(); + + /** + * @brief MQTT Subscribe handler for incoming publications on: +- * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WriteAttributes ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/YearDayReport + */ + // clang-format off +-void uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes( ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length); ++// clang-format on ++ ++/** ++ * @brief Retrieves the container with callbacks pointer for ++ * by-unid UnifyScheduleEntryLock/Commands/WeekDaySet messages ++ * ++ * @returns std::set of callbacks. ++ */ ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WeekDaySet ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_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 UnifyScheduleEntryLock/Commands/DailyRepeatingReport messages ++ * ++ * @returns std::set of callbacks. ++ */ ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/DailyRepeatingReport ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length); ++// clang-format on ++ ++/** ++ * @brief Retrieves the container with callbacks pointer for ++ * by-unid UnifyScheduleEntryLock/Commands/WeekDayGet messages ++ * ++ * @returns std::set of callbacks. ++ */ ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WeekDayGet ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_get( ++ const char *topic, ++ const char *message, ++ const size_t message_length); ++// clang-format on ++ ++/** ++ * @brief Retrieves the container with callbacks pointer for ++ * by-unid UnifyScheduleEntryLock/Commands/YearDaySet messages ++ * ++ * @returns std::set of callbacks. ++ */ ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/YearDaySet ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_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 UnifyScheduleEntryLock/Commands/YearDayGet messages ++ * ++ * @returns std::set of callbacks. ++ */ ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/YearDayGet ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_get( + const char *topic, + const char *message, + const size_t message_length); ++// clang-format on + ++/** ++ * @brief Retrieves the container with callbacks pointer for ++ * by-unid UnifyScheduleEntryLock/Commands/DailyRepeatingSet messages ++ * ++ * @returns std::set of callbacks. ++ */ ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback(); ++ ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/DailyRepeatingSet ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_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 UnifyScheduleEntryLock/Commands/DailyRepeatingGet messages ++ * ++ * @returns std::set of callbacks. ++ */ ++std::set &get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback(); + ++/** ++ * @brief MQTT Subscribe handler for incoming publications on: ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/DailyRepeatingGet ++ */ ++// clang-format off ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_get( ++ const char *topic, ++ const char *message, ++ const size_t message_length); + // clang-format on + + /** +@@ -5156,14 +5308,14 @@ void uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes( + * + * @returns std::set of callbacks. + */ +-std::set & get_uic_mqtt_dotdot_unify_thermostat_write_attributes_callback(); ++std::set & get_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback(); + + /** + * @brief MQTT Subscribe handler for incoming publications on: +- * ucl/by-unid/+/+/UnifyThermostat/Commands/WriteAttributes ++ * ucl/by-unid/+/+/UnifyScheduleEntryLock/Commands/WriteAttributes + */ + // clang-format off +-void uic_mqtt_dotdot_on_unify_thermostat_WriteAttributes( ++void uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes( + const char *topic, + const char *message, + const size_t message_length); +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 9d5eb3d4a7..1da48e495d 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 +@@ -14523,9 +14523,59 @@ void uic_mqtt_dotdot_parse_unify_thermostat_write_attributes( + } + + +-std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++std::string get_json_payload_for_unify_schedule_entry_lock_enable_set_command( + +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_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 ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["UserIdentifier"] = nlohmann::json(fields->user_identifier); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["Enabled"] = nlohmann::json(fields->enabled); ++ ++ // 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_schedule_entry_lock_enable_set( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &enabled ++ ++) { ++ ++ if (jsn.at("UserIdentifier").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ user_identifier = jsn.at("UserIdentifier").get< uint8_t >(); ++ if (jsn.at("Enabled").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ enabled = jsn.at("Enabled").get< uint8_t >(); ++ } ++ ++ ++std::string get_json_payload_for_unify_schedule_entry_lock_week_day_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t *fields + + ){ + bool command_with_no_fields = true; +@@ -14570,7 +14620,7 @@ std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_w + } + + +-void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_report( + nlohmann::json &jsn, + uint8_t &user_identifier, + +@@ -14633,9 +14683,9 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_week_da + } + + +-std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++std::string get_json_payload_for_unify_schedule_entry_lock_enable_all_set_command( + +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t *fields + + ){ + bool command_with_no_fields = true; +@@ -14645,7 +14695,41 @@ std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_y + command_with_no_fields = false; + // Single Value + // Non-enum and non-bitmask (struct, string or scalar) +- json_payload["SetAction"] = nlohmann::json(fields->set_action); ++ json_payload["Enabled"] = nlohmann::json(fields->enabled); ++ ++ // 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_schedule_entry_lock_enable_all_set( ++ nlohmann::json &jsn, ++ uint8_t &enabled ++ ++) { ++ ++ if (jsn.at("Enabled").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ enabled = jsn.at("Enabled").get< uint8_t >(); ++ } ++ ++ ++std::string get_json_payload_for_unify_schedule_entry_lock_year_day_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_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 + // Non-enum and non-bitmask (struct, string or scalar) +@@ -14704,10 +14788,8 @@ std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_y + } + + +-void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_report( + nlohmann::json &jsn, +- uint8_t &set_action, +- + uint8_t &user_identifier, + + uint8_t &schedule_slotid, +@@ -14734,13 +14816,7 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_da + + ) { + +- if (jsn.at("SetAction").is_null()) { +- sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); +- return; +- } +- +- set_action = jsn.at("SetAction").get< uint8_t >(); +- if (jsn.at("UserIdentifier").is_null()) { ++ if (jsn.at("UserIdentifier").is_null()) { + sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); + return; + } +@@ -14815,9 +14891,9 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_da + } + + +-std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_command( ++std::string get_json_payload_for_unify_schedule_entry_lock_week_day_set_command( + +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t *fields + + ){ + bool command_with_no_fields = true; +@@ -14839,7 +14915,7 @@ std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_d + command_with_no_fields = false; + // Single Value + // Non-enum and non-bitmask (struct, string or scalar) +- json_payload["WeekDayBitmask"] = nlohmann::json(fields->week_day_bitmask); ++ json_payload["DayOfWeek"] = nlohmann::json(fields->day_of_week); + command_with_no_fields = false; + // Single Value + // Non-enum and non-bitmask (struct, string or scalar) +@@ -14847,19 +14923,15 @@ std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_d + command_with_no_fields = false; + // Single Value + // Non-enum and non-bitmask (struct, string or scalar) +- json_payload["StartMonth"] = nlohmann::json(fields->start_month); +- command_with_no_fields = false; +- // Single Value +- // Non-enum and non-bitmask (struct, string or scalar) + json_payload["StartMinute"] = nlohmann::json(fields->start_minute); + command_with_no_fields = false; + // Single Value + // Non-enum and non-bitmask (struct, string or scalar) +- json_payload["DurationHour"] = nlohmann::json(fields->duration_hour); ++ json_payload["StopHour"] = nlohmann::json(fields->stop_hour); + command_with_no_fields = false; + // Single Value + // Non-enum and non-bitmask (struct, string or scalar) +- json_payload["DurationMinute"] = nlohmann::json(fields->duration_minute); ++ json_payload["StopMinute"] = nlohmann::json(fields->stop_minute); + + // Get the string + if (command_with_no_fields == true) { +@@ -14870,7 +14942,7 @@ std::string get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_d + } + + +-void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_set( + nlohmann::json &jsn, + uint8_t &set_action, + +@@ -14878,15 +14950,15 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_r + + uint8_t &schedule_slotid, + +- uint8_t &week_day_bitmask, ++ uint8_t &day_of_week, + + uint8_t &start_hour, + + uint8_t &start_minute, + +- uint8_t &duration_hour, ++ uint8_t &stop_hour, + +- uint8_t &duration_minute ++ uint8_t &stop_minute + + ) { + +@@ -14908,24 +14980,128 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_r + } + + schedule_slotid = jsn.at("ScheduleSlotID").get< uint8_t >(); +- if (jsn.at("WeekDayBitmask").is_null()) { ++ if (jsn.at("DayOfWeek").is_null()) { + sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); + return; + } + +- week_day_bitmask = jsn.at("WeekDayBitmask").get< uint8_t >(); ++ day_of_week = jsn.at("DayOfWeek").get< uint8_t >(); + if (jsn.at("StartHour").is_null()) { + sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); + return; + } + + start_hour = jsn.at("StartHour").get< uint8_t >(); +- if (jsn.at("StartMonth").is_null()) { ++ if (jsn.at("StartMinute").is_null()) { + sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); + return; + } + +- start_month = jsn.at("StartMonth").get< uint8_t >(); ++ start_minute = jsn.at("StartMinute").get< uint8_t >(); ++ if (jsn.at("StopHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_hour = jsn.at("StopHour").get< uint8_t >(); ++ if (jsn.at("StopMinute").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_minute = jsn.at("StopMinute").get< uint8_t >(); ++ } ++ ++ ++std::string get_json_payload_for_unify_schedule_entry_lock_daily_repeating_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_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 ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["UserIdentifier"] = nlohmann::json(fields->user_identifier); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["ScheduleSlotID"] = nlohmann::json(fields->schedule_slotid); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["WeekDayBitmask"] = nlohmann::json(fields->week_day_bitmask); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartHour"] = nlohmann::json(fields->start_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartMinute"] = nlohmann::json(fields->start_minute); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["DurationHour"] = nlohmann::json(fields->duration_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["DurationMinute"] = nlohmann::json(fields->duration_minute); ++ ++ // 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_schedule_entry_lock_daily_repeating_report( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ ++ uint8_t &week_day_bitmask, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &duration_hour, ++ ++ uint8_t &duration_minute ++ ++) { ++ ++ if (jsn.at("UserIdentifier").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ user_identifier = jsn.at("UserIdentifier").get< uint8_t >(); ++ if (jsn.at("ScheduleSlotID").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ schedule_slotid = jsn.at("ScheduleSlotID").get< uint8_t >(); ++ if (jsn.at("WeekDayBitmask").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ week_day_bitmask = jsn.at("WeekDayBitmask").get< uint8_t >(); ++ if (jsn.at("StartHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_hour = jsn.at("StartHour").get< uint8_t >(); + if (jsn.at("StartMinute").is_null()) { + sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); + return; +@@ -14947,6 +15123,460 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_r + } + + ++std::string get_json_payload_for_unify_schedule_entry_lock_week_day_get_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_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 ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["UserIdentifier"] = nlohmann::json(fields->user_identifier); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["ScheduleSlotID"] = nlohmann::json(fields->schedule_slotid); ++ ++ // 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_schedule_entry_lock_week_day_get( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid ++ ++) { ++ ++ if (jsn.at("UserIdentifier").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ user_identifier = jsn.at("UserIdentifier").get< uint8_t >(); ++ if (jsn.at("ScheduleSlotID").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ schedule_slotid = jsn.at("ScheduleSlotID").get< uint8_t >(); ++ } ++ ++ ++std::string get_json_payload_for_unify_schedule_entry_lock_year_day_set_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_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 ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["SetAction"] = nlohmann::json(fields->set_action); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["UserIdentifier"] = nlohmann::json(fields->user_identifier); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["ScheduleSlotID"] = nlohmann::json(fields->schedule_slotid); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartYear"] = nlohmann::json(fields->start_year); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartDay"] = nlohmann::json(fields->start_day); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartHour"] = nlohmann::json(fields->start_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartMonth"] = nlohmann::json(fields->start_month); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartMinute"] = nlohmann::json(fields->start_minute); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopYear"] = nlohmann::json(fields->stop_year); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopMonth"] = nlohmann::json(fields->stop_month); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopDay"] = nlohmann::json(fields->stop_day); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopHour"] = nlohmann::json(fields->stop_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StopMinute"] = nlohmann::json(fields->stop_minute); ++ ++ // 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_schedule_entry_lock_year_day_set( ++ nlohmann::json &jsn, ++ uint8_t &set_action, ++ ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ ++ uint8_t &start_year, ++ ++ uint8_t &start_day, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_month, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &stop_year, ++ ++ uint8_t &stop_month, ++ ++ uint8_t &stop_day, ++ ++ uint8_t &stop_hour, ++ ++ uint8_t &stop_minute ++ ++) { ++ ++ if (jsn.at("SetAction").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ set_action = jsn.at("SetAction").get< uint8_t >(); ++ if (jsn.at("UserIdentifier").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ user_identifier = jsn.at("UserIdentifier").get< uint8_t >(); ++ if (jsn.at("ScheduleSlotID").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ schedule_slotid = jsn.at("ScheduleSlotID").get< uint8_t >(); ++ if (jsn.at("StartYear").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_year = jsn.at("StartYear").get< uint8_t >(); ++ if (jsn.at("StartDay").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_day = jsn.at("StartDay").get< uint8_t >(); ++ if (jsn.at("StartHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_hour = jsn.at("StartHour").get< uint8_t >(); ++ if (jsn.at("StartMonth").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_month = jsn.at("StartMonth").get< uint8_t >(); ++ if (jsn.at("StartMinute").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_minute = jsn.at("StartMinute").get< uint8_t >(); ++ if (jsn.at("StopYear").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_year = jsn.at("StopYear").get< uint8_t >(); ++ if (jsn.at("StopMonth").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_month = jsn.at("StopMonth").get< uint8_t >(); ++ if (jsn.at("StopDay").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_day = jsn.at("StopDay").get< uint8_t >(); ++ if (jsn.at("StopHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_hour = jsn.at("StopHour").get< uint8_t >(); ++ if (jsn.at("StopMinute").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ stop_minute = jsn.at("StopMinute").get< uint8_t >(); ++ } ++ ++ ++std::string get_json_payload_for_unify_schedule_entry_lock_year_day_get_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_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 ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["UserIdentifier"] = nlohmann::json(fields->user_identifier); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["ScheduleSlotID"] = nlohmann::json(fields->schedule_slotid); ++ ++ // 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_schedule_entry_lock_year_day_get( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid ++ ++) { ++ ++ if (jsn.at("UserIdentifier").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ user_identifier = jsn.at("UserIdentifier").get< uint8_t >(); ++ if (jsn.at("ScheduleSlotID").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ schedule_slotid = jsn.at("ScheduleSlotID").get< uint8_t >(); ++ } ++ ++ ++std::string get_json_payload_for_unify_schedule_entry_lock_daily_repeating_set_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_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 ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["SetAction"] = nlohmann::json(fields->set_action); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["UserIdentifier"] = nlohmann::json(fields->user_identifier); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["ScheduleSlotID"] = nlohmann::json(fields->schedule_slotid); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["WeekDayBitmask"] = nlohmann::json(fields->week_day_bitmask); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartHour"] = nlohmann::json(fields->start_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["StartMinute"] = nlohmann::json(fields->start_minute); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["DurationHour"] = nlohmann::json(fields->duration_hour); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["DurationMinute"] = nlohmann::json(fields->duration_minute); ++ ++ // 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_schedule_entry_lock_daily_repeating_set( ++ nlohmann::json &jsn, ++ uint8_t &set_action, ++ ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ ++ uint8_t &week_day_bitmask, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &duration_hour, ++ ++ uint8_t &duration_minute ++ ++) { ++ ++ if (jsn.at("SetAction").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ set_action = jsn.at("SetAction").get< uint8_t >(); ++ if (jsn.at("UserIdentifier").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ user_identifier = jsn.at("UserIdentifier").get< uint8_t >(); ++ if (jsn.at("ScheduleSlotID").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ schedule_slotid = jsn.at("ScheduleSlotID").get< uint8_t >(); ++ if (jsn.at("WeekDayBitmask").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ week_day_bitmask = jsn.at("WeekDayBitmask").get< uint8_t >(); ++ if (jsn.at("StartHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_hour = jsn.at("StartHour").get< uint8_t >(); ++ if (jsn.at("StartMinute").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ start_minute = jsn.at("StartMinute").get< uint8_t >(); ++ if (jsn.at("DurationHour").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ duration_hour = jsn.at("DurationHour").get< uint8_t >(); ++ if (jsn.at("DurationMinute").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ duration_minute = jsn.at("DurationMinute").get< uint8_t >(); ++ } ++ ++ ++std::string get_json_payload_for_unify_schedule_entry_lock_daily_repeating_get_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_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 ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["UserIdentifier"] = nlohmann::json(fields->user_identifier); ++ command_with_no_fields = false; ++ // Single Value ++ // Non-enum and non-bitmask (struct, string or scalar) ++ json_payload["ScheduleSlotID"] = nlohmann::json(fields->schedule_slotid); ++ ++ // 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_schedule_entry_lock_daily_repeating_get( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid ++ ++) { ++ ++ if (jsn.at("UserIdentifier").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ user_identifier = jsn.at("UserIdentifier").get< uint8_t >(); ++ if (jsn.at("ScheduleSlotID").is_null()) { ++ sl_log_debug(LOG_TAG, "Ignoring JSON Null object"); ++ return; ++ } ++ ++ schedule_slotid = jsn.at("ScheduleSlotID").get< uint8_t >(); ++ } ++ ++ + /** + * @brief JSON parser for ::WriteAttributes command arguments. + * +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 31a79e1ade..7213b5a3b8 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 +@@ -6031,25 +6031,55 @@ void uic_mqtt_dotdot_parse_unify_thermostat_write_attributes( + + /** + * @brief Private helper function that will create a JSON string based on the +- * fields of a UnifyScheduleEntryLock ScheduleEntryLockWeekDayReport command ++ * fields of a UnifyScheduleEntryLock EnableSet 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_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++std::string get_json_payload_for_unify_schedule_entry_lock_enable_set_command( + +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_set_fields_t *fields + + ); + + + /** +- * @brief JSON parser for UnifyScheduleEntryLock ScheduleEntryLockWeekDayReport command arguments. ++ * @brief JSON parser for UnifyScheduleEntryLock EnableSet command arguments. + * + * Parse incoming JSON object to populate command arguments passed in by reference. + */ +-void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_enable_set( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &enabled ++ ++); ++ ++ ++ ++/** ++ * @brief Private helper function that will create a JSON string based on the ++ * fields of a UnifyScheduleEntryLock WeekDayReport 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_schedule_entry_lock_week_day_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t *fields ++ ++); ++ ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock WeekDayReport command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_report( + nlohmann::json &jsn, + uint8_t &user_identifier, + +@@ -6071,28 +6101,54 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_week_da + + /** + * @brief Private helper function that will create a JSON string based on the +- * fields of a UnifyScheduleEntryLock ScheduleEntryLockYearDayReport command ++ * fields of a UnifyScheduleEntryLock EnableAllSet 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_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++std::string get_json_payload_for_unify_schedule_entry_lock_enable_all_set_command( + +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t *fields + + ); + + + /** +- * @brief JSON parser for UnifyScheduleEntryLock ScheduleEntryLockYearDayReport command arguments. ++ * @brief JSON parser for UnifyScheduleEntryLock EnableAllSet command arguments. + * + * Parse incoming JSON object to populate command arguments passed in by reference. + */ +-void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_enable_all_set( + nlohmann::json &jsn, +- uint8_t &set_action, ++ uint8_t &enabled ++ ++); ++ ++ ++ ++/** ++ * @brief Private helper function that will create a JSON string based on the ++ * fields of a UnifyScheduleEntryLock YearDayReport 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_schedule_entry_lock_year_day_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t *fields ++ ++); + ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock YearDayReport command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_report( ++ nlohmann::json &jsn, + uint8_t &user_identifier, + + uint8_t &schedule_slotid, +@@ -6123,25 +6179,25 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_da + + /** + * @brief Private helper function that will create a JSON string based on the +- * fields of a UnifyScheduleEntryLock ScheduleEntryLockDailyRepeatingReport command ++ * fields of a UnifyScheduleEntryLock WeekDaySet 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_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_command( ++std::string get_json_payload_for_unify_schedule_entry_lock_week_day_set_command( + +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t *fields + + ); + + + /** +- * @brief JSON parser for UnifyScheduleEntryLock ScheduleEntryLockDailyRepeatingReport command arguments. ++ * @brief JSON parser for UnifyScheduleEntryLock WeekDaySet command arguments. + * + * Parse incoming JSON object to populate command arguments passed in by reference. + */ +-void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_set( + nlohmann::json &jsn, + uint8_t &set_action, + +@@ -6149,6 +6205,46 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_r + + uint8_t &schedule_slotid, + ++ uint8_t &day_of_week, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &stop_hour, ++ ++ uint8_t &stop_minute ++ ++); ++ ++ ++ ++/** ++ * @brief Private helper function that will create a JSON string based on the ++ * fields of a UnifyScheduleEntryLock DailyRepeatingReport 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_schedule_entry_lock_daily_repeating_report_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t *fields ++ ++); ++ ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock DailyRepeatingReport command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_report( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ + uint8_t &week_day_bitmask, + + uint8_t &start_hour, +@@ -6163,6 +6259,190 @@ void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_r + + + ++/** ++ * @brief Private helper function that will create a JSON string based on the ++ * fields of a UnifyScheduleEntryLock WeekDayGet 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_schedule_entry_lock_week_day_get_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_fields_t *fields ++ ++); ++ ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock WeekDayGet command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_get( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid ++ ++); ++ ++ ++ ++/** ++ * @brief Private helper function that will create a JSON string based on the ++ * fields of a UnifyScheduleEntryLock YearDaySet 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_schedule_entry_lock_year_day_set_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_set_fields_t *fields ++ ++); ++ ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock YearDaySet command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_set( ++ nlohmann::json &jsn, ++ uint8_t &set_action, ++ ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ ++ uint8_t &start_year, ++ ++ uint8_t &start_day, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_month, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &stop_year, ++ ++ uint8_t &stop_month, ++ ++ uint8_t &stop_day, ++ ++ uint8_t &stop_hour, ++ ++ uint8_t &stop_minute ++ ++); ++ ++ ++ ++/** ++ * @brief Private helper function that will create a JSON string based on the ++ * fields of a UnifyScheduleEntryLock YearDayGet 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_schedule_entry_lock_year_day_get_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_fields_t *fields ++ ++); ++ ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock YearDayGet command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_get( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid ++ ++); ++ ++ ++ ++/** ++ * @brief Private helper function that will create a JSON string based on the ++ * fields of a UnifyScheduleEntryLock DailyRepeatingSet 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_schedule_entry_lock_daily_repeating_set_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_set_fields_t *fields ++ ++); ++ ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock DailyRepeatingSet command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_set( ++ nlohmann::json &jsn, ++ uint8_t &set_action, ++ ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid, ++ ++ uint8_t &week_day_bitmask, ++ ++ uint8_t &start_hour, ++ ++ uint8_t &start_minute, ++ ++ uint8_t &duration_hour, ++ ++ uint8_t &duration_minute ++ ++); ++ ++ ++ ++/** ++ * @brief Private helper function that will create a JSON string based on the ++ * fields of a UnifyScheduleEntryLock DailyRepeatingGet 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_schedule_entry_lock_daily_repeating_get_command( ++ ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_fields_t *fields ++ ++); ++ ++ ++/** ++ * @brief JSON parser for UnifyScheduleEntryLock DailyRepeatingGet command arguments. ++ * ++ * Parse incoming JSON object to populate command arguments passed in by reference. ++ */ ++void uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_get( ++ nlohmann::json &jsn, ++ uint8_t &user_identifier, ++ ++ uint8_t &schedule_slotid ++ ++); ++ ++ ++ + /** + * @brief JSON parser for UnifyScheduleEntryLock WriteAttributes command arguments. + * +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 03c7efb978..581108431c 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 +@@ -11236,11 +11236,11 @@ void uic_mqtt_dotdot_unify_thermostat_publish_generated_write_attributes_command + } + + /** +- * @brief Publishes an incoming/generated ScheduleEntryLockWeekDayReport command for ++ * @brief Publishes an incoming/generated EnableSet command for + * the UnifyScheduleEntryLock cluster. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/EnableSet + * + * @param unid The UNID of the node that sent us the command. + * +@@ -11250,19 +11250,19 @@ void uic_mqtt_dotdot_unify_thermostat_publish_generated_write_attributes_command + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_lock_week_day_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_enable_set_command( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_set_fields_t *fields + + ) { + // Create the topic + std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + + std::to_string(endpoint) + "/"; +- topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockWeekDayReport"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/EnableSet"; + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_enable_set_command( + fields); + + // Publish our command +@@ -11272,11 +11272,11 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_ + false); + } + /** +- * @brief Publishes an incoming/generated ScheduleEntryLockYearDayReport command for ++ * @brief Publishes an incoming/generated WeekDayReport command for + * the UnifyScheduleEntryLock cluster. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/WeekDayReport + * + * @param unid The UNID of the node that sent us the command. + * +@@ -11286,19 +11286,19 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_ + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_lock_year_day_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_week_day_report_command( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t *fields + + ) { + // Create the topic + std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + + std::to_string(endpoint) + "/"; +- topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockYearDayReport"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/WeekDayReport"; + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_week_day_report_command( + fields); + + // Publish our command +@@ -11308,11 +11308,11 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_ + false); + } + /** +- * @brief Publishes an incoming/generated ScheduleEntryLockDailyRepeatingReport command for ++ * @brief Publishes an incoming/generated EnableAllSet command for + * the UnifyScheduleEntryLock cluster. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/EnableAllSet + * + * @param unid The UNID of the node that sent us the command. + * +@@ -11322,19 +11322,307 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_ + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_schedule_entry_lock_daily_repeating_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_enable_all_set_command( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t *fields + + ) { + // Create the topic + std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + + std::to_string(endpoint) + "/"; +- topic += "UnifyScheduleEntryLock/GeneratedCommands/ScheduleEntryLockDailyRepeatingReport"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/EnableAllSet"; + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_enable_all_set_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated YearDayReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/YearDayReport ++ * ++ * @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_schedule_entry_lock_publish_generated_year_day_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/YearDayReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_year_day_report_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated WeekDaySet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/WeekDaySet ++ * ++ * @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_schedule_entry_lock_publish_generated_week_day_set_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/WeekDaySet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_week_day_set_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated DailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_generated_daily_repeating_report_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_report_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated WeekDayGet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/WeekDayGet ++ * ++ * @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_schedule_entry_lock_publish_generated_week_day_get_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/WeekDayGet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_week_day_get_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated YearDaySet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/YearDaySet ++ * ++ * @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_schedule_entry_lock_publish_generated_year_day_set_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_set_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/YearDaySet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_year_day_set_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated YearDayGet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/YearDayGet ++ * ++ * @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_schedule_entry_lock_publish_generated_year_day_get_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/YearDayGet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_year_day_get_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated DailyRepeatingSet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingSet ++ * ++ * @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_schedule_entry_lock_publish_generated_daily_repeating_set_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_set_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingSet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_set_command( ++ fields); ++ ++ // Publish our command ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++/** ++ * @brief Publishes an incoming/generated DailyRepeatingGet command for ++ * the UnifyScheduleEntryLock cluster. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingGet ++ * ++ * @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_schedule_entry_lock_publish_generated_daily_repeating_get_command( ++ const dotdot_unid_t unid, ++ const dotdot_endpoint_id_t endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(unid) + "/ep" + ++ std::to_string(endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/GeneratedCommands/DailyRepeatingGet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_get_command( + fields); + + // Publish our command +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 76008f3cbf..defeb60be8 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 +@@ -368,9 +368,17 @@ static uic_mqtt_dotdot_by_group_unify_fan_control_write_attributes_callback_t ui + static uic_mqtt_dotdot_by_group_unify_thermostat_write_attributes_callback_t uic_mqtt_dotdot_by_group_unify_thermostat_write_attributes_callback = nullptr; + + +-static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback = nullptr; +-static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback = nullptr; +-static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_set_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_set_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_report_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_report_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_get_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_get_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_set_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_set_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_get_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_get_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_set_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_set_callback = nullptr; ++static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_get_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_get_callback = nullptr; + static uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback = nullptr; + + +@@ -1894,21 +1902,69 @@ void uic_mqtt_dotdot_by_group_unify_thermostat_write_attributes_callback_set( + + // Callbacks setters + +-void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback) ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_set_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_set_callback_t callback) + { +- uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback = callback; ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_set_callback = callback; + } + + +-void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback) ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback_t callback) + { +- uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback = callback; ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback = callback; + } + + +-void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback) ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback_t callback) + { +- uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback = callback; ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback = callback; ++} ++ ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_report_callback = callback; ++} ++ ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback = callback; ++} ++ ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback = callback; ++} ++ ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_get_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_get_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_get_callback = callback; ++} ++ ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_set_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_set_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_set_callback = callback; ++} ++ ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_get_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_get_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_get_callback = callback; ++} ++ ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_set_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_set_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_set_callback = callback; ++} ++ ++ ++void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_get_callback_set(const uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_get_callback_t callback) ++{ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_get_callback = callback; + } + + void uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback_set( +@@ -23460,13 +23516,104 @@ sl_status_t uic_mqtt_dotdot_by_group_unify_thermostat_init() + + + +-// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport +-static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/EnableSet ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_enable_set( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_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_schedule_entry_lock_enable_set_callback != nullptr) { ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_set_fields_t fields; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_enable_set( ++ jsn, ++ fields.user_identifier, ++ ++ fields.enabled ++ ); ++ ++ // 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, "UnifyScheduleEntryLock", "EnableSet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableSet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableSet", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_set_callback( ++ group_id, ++ &fields ++ ); ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_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("UserIdentifier") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::EnableSet: Missing command-argument: UserIdentifier\n"); ++ return; ++ } ++ if (jsn.find("Enabled") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::EnableSet: Missing command-argument: Enabled\n"); ++ return; ++ } ++ ++ group_dispatch_callback( ++ group_id, ++ "UnifyScheduleEntryLock", ++ "EnableSet", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_enable_set); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "EnableSet: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/WeekDayReport ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_week_day_report( + const char *topic, + const char *message, + const size_t message_length) + { +- if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback == nullptr)) { ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback == nullptr)) { + return; + } + if (message_length == 0) { +@@ -23483,10 +23630,10 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + + // Pass to command-specific callback if set. Otherwise, pass to + // group-dispatch callback +- if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback != nullptr) { ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback != nullptr) { + + +- uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t fields; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t fields; + + + nlohmann::json jsn; +@@ -23494,7 +23641,7 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + jsn = nlohmann::json::parse(std::string(message)); + + +- uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_week_day_report( ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_report( + jsn, + fields.user_identifier, + +@@ -23516,78 +23663,78 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + + } catch (const nlohmann::json::parse_error& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport"); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "WeekDayReport"); + return; + } catch (const nlohmann::json::exception& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", e.what()); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayReport", e.what()); + return; + } catch (const std::exception& e) { +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockWeekDayReport", ""); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayReport", ""); + return; + } + +- uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback( ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback( + group_id, + &fields + ); +- } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback().empty())) { ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_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("UserIdentifier") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: UserIdentifier\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDayReport: Missing command-argument: UserIdentifier\n"); + return; + } + if (jsn.find("ScheduleSlotID") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: ScheduleSlotID\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDayReport: Missing command-argument: ScheduleSlotID\n"); + return; + } + if (jsn.find("DayOfWeek") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: DayOfWeek\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDayReport: Missing command-argument: DayOfWeek\n"); + return; + } + if (jsn.find("StartHour") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: StartHour\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDayReport: Missing command-argument: StartHour\n"); + return; + } + if (jsn.find("StartMinute") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: StartMinute\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDayReport: Missing command-argument: StartMinute\n"); + return; + } + if (jsn.find("StopHour") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: StopHour\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDayReport: Missing command-argument: StopHour\n"); + return; + } + if (jsn.find("StopMinute") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockWeekDayReport: Missing command-argument: StopMinute\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDayReport: Missing command-argument: StopMinute\n"); + return; + } + + group_dispatch_callback( + group_id, + "UnifyScheduleEntryLock", +- "ScheduleEntryLockWeekDayReport", ++ "WeekDayReport", + message, + message_length, +- uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_week_day_report); ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_report); + + } catch (...) { +- sl_log_debug(LOG_TAG, "ScheduleEntryLockWeekDayReport: Unable to parse JSON payload.\n"); ++ sl_log_debug(LOG_TAG, "WeekDayReport: Unable to parse JSON payload.\n"); + return; + } + } + + } + +-// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport +-static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/EnableAllSet ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_enable_all_set( + const char *topic, + const char *message, + const size_t message_length) + { +- if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback == nullptr)) { ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback == nullptr)) { + return; + } + if (message_length == 0) { +@@ -23604,10 +23751,10 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + + // Pass to command-specific callback if set. Otherwise, pass to + // group-dispatch callback +- if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback != nullptr) { ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback != nullptr) { + + +- uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t fields; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t fields; + + + nlohmann::json jsn; +@@ -23615,10 +23762,93 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + jsn = nlohmann::json::parse(std::string(message)); + + +- uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_year_day_report( ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_enable_all_set( ++ jsn, ++ fields.enabled ++ ); ++ ++ // 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, "UnifyScheduleEntryLock", "EnableAllSet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableAllSet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "EnableAllSet", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback( ++ group_id, ++ &fields ++ ); ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_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("Enabled") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::EnableAllSet: Missing command-argument: Enabled\n"); ++ return; ++ } ++ ++ group_dispatch_callback( ++ group_id, ++ "UnifyScheduleEntryLock", ++ "EnableAllSet", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_enable_all_set); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "EnableAllSet: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/YearDayReport ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_year_day_report( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_report_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_schedule_entry_lock_year_day_report_callback != nullptr) { ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t fields; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_report( + jsn, +- fields.set_action, +- + fields.user_identifier, + + fields.schedule_slotid, +@@ -23649,94 +23879,98 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + + } catch (const nlohmann::json::parse_error& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport"); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "YearDayReport"); + return; + } catch (const nlohmann::json::exception& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", e.what()); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayReport", e.what()); + return; + } catch (const std::exception& e) { +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockYearDayReport", ""); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayReport", ""); + return; + } + +- uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback( ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_report_callback( + group_id, + &fields + ); +- } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback().empty())) { ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_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("SetAction") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: SetAction\n"); +- return; +- } + if (jsn.find("UserIdentifier") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: UserIdentifier\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: UserIdentifier\n"); + return; + } + if (jsn.find("ScheduleSlotID") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: ScheduleSlotID\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: ScheduleSlotID\n"); + return; + } + if (jsn.find("StartYear") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StartYear\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: StartYear\n"); ++ return; ++ } ++ if (jsn.find("StartMonth") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: StartMonth\n"); + return; + } + if (jsn.find("StartDay") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StartDay\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: StartDay\n"); + return; + } + if (jsn.find("StartHour") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StartHour\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: StartHour\n"); + return; + } + if (jsn.find("StartMinute") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StartMinute\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: StartMinute\n"); + return; + } + if (jsn.find("StopYear") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StopYear\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: StopYear\n"); ++ return; ++ } ++ if (jsn.find("StopMonth") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: StopMonth\n"); + return; + } + if (jsn.find("StopDay") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StopDay\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: StopDay\n"); + return; + } + if (jsn.find("StopHour") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StopHour\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: StopHour\n"); + return; + } + if (jsn.find("StopMinute") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockYearDayReport: Missing command-argument: StopMinute\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayReport: Missing command-argument: StopMinute\n"); + return; + } + + group_dispatch_callback( + group_id, + "UnifyScheduleEntryLock", +- "ScheduleEntryLockYearDayReport", ++ "YearDayReport", + message, + message_length, +- uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_year_day_report); ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_report); + + } catch (...) { +- sl_log_debug(LOG_TAG, "ScheduleEntryLockYearDayReport: Unable to parse JSON payload.\n"); ++ sl_log_debug(LOG_TAG, "YearDayReport: Unable to parse JSON payload.\n"); + return; + } + } + + } + +-// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport +-static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/WeekDaySet ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_week_day_set( + const char *topic, + const char *message, + const size_t message_length) + { +- if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback == nullptr)) { ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback == nullptr)) { + return; + } + if (message_length == 0) { +@@ -23753,10 +23987,10 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + + // Pass to command-specific callback if set. Otherwise, pass to + // group-dispatch callback +- if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback != nullptr) { ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback != nullptr) { + + +- uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t fields; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t fields; + + + nlohmann::json jsn; +@@ -23764,7 +23998,7 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + jsn = nlohmann::json::parse(std::string(message)); + + +- uic_mqtt_dotdot_parse_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report( ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_set( + jsn, + fields.set_action, + +@@ -23772,15 +24006,15 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + + fields.schedule_slotid, + +- fields.week_day_bitmask, ++ fields.day_of_week, + + fields.start_hour, + + fields.start_minute, + +- fields.duration_hour, ++ fields.stop_hour, + +- fields.duration_minute ++ fields.stop_minute + ); + + // Populate list fields from vector or string types +@@ -23788,82 +24022,82 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry + + } catch (const nlohmann::json::parse_error& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport"); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_PARSE_FAIL, "UnifyScheduleEntryLock", "WeekDaySet"); + return; + } catch (const nlohmann::json::exception& e) { + // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", e.what()); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDaySet", e.what()); + return; + } catch (const std::exception& e) { +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "ScheduleEntryLockDailyRepeatingReport", ""); ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDaySet", ""); + return; + } + +- uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback( ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback( + group_id, + &fields + ); +- } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback().empty())) { ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_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("SetAction") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: SetAction\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDaySet: Missing command-argument: SetAction\n"); + return; + } + if (jsn.find("UserIdentifier") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: UserIdentifier\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDaySet: Missing command-argument: UserIdentifier\n"); + return; + } + if (jsn.find("ScheduleSlotID") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: ScheduleSlotID\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDaySet: Missing command-argument: ScheduleSlotID\n"); + return; + } +- if (jsn.find("WeekDayBitmask") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: WeekDayBitmask\n"); ++ if (jsn.find("DayOfWeek") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDaySet: Missing command-argument: DayOfWeek\n"); + return; + } + if (jsn.find("StartHour") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: StartHour\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDaySet: Missing command-argument: StartHour\n"); + return; + } + if (jsn.find("StartMinute") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: StartMinute\n"); ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDaySet: Missing command-argument: StartMinute\n"); + return; + } +- if (jsn.find("DurationHour") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: DurationHour\n"); ++ if (jsn.find("StopHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDaySet: Missing command-argument: StopHour\n"); + return; + } +- if (jsn.find("DurationMinute") == jsn.end()) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::ScheduleEntryLockDailyRepeatingReport: Missing command-argument: DurationMinute\n"); ++ if (jsn.find("StopMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDaySet: Missing command-argument: StopMinute\n"); + return; + } + + group_dispatch_callback( + group_id, + "UnifyScheduleEntryLock", +- "ScheduleEntryLockDailyRepeatingReport", ++ "WeekDaySet", + message, + message_length, +- uic_mqtt_dotdot_on_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report); ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_set); + + } catch (...) { +- sl_log_debug(LOG_TAG, "ScheduleEntryLockDailyRepeatingReport: Unable to parse JSON payload.\n"); ++ sl_log_debug(LOG_TAG, "WeekDaySet: Unable to parse JSON payload.\n"); + return; + } + } + + } + +-static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_WriteAttributes( ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/DailyRepeatingReport ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_daily_repeating_report( + const char *topic, + const char *message, + const size_t message_length) + { +- +- if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback == nullptr)) { ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback == nullptr)) { + return; + } + if (message_length == 0) { +@@ -23878,74 +24112,784 @@ static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_WriteAttribute + return; + } + +- if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback().empty())) { +- try { +- group_dispatch_callback(group_id, +- "UnifyScheduleEntryLock", +- "WriteAttributes", +- message, +- message_length, +- uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes); +- +- } catch (...) { +- sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock: Unable to parse JSON payload.\n"); +- return; +- } +- } else if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback != nullptr) { ++ // Pass to command-specific callback if set. Otherwise, pass to ++ // group-dispatch callback ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback != nullptr) { + +- uic_mqtt_dotdot_unify_schedule_entry_lock_state_t new_state = {}; +- uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t new_updated_state = {}; + ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t fields; + +- nlohmann::json jsn; +- try { +- jsn = nlohmann::json::parse(std::string(message)); +- +- uic_mqtt_dotdot_parse_unify_schedule_entry_lock_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, "UnifyScheduleEntryLock", "WriteAttributes"); +- return; +- } catch (const nlohmann::json::exception& e) { +- // Catch JSON object field parsing errors +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", e.what()); +- return; +- } catch (const std::exception& e) { +- sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", ""); +- return; +- } + +- uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback( +- group_id, +- new_state, +- new_updated_state +- ); +- } +-} ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); + +-sl_status_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_init() +-{ +- std::string subscription_topic; +- const std::string topic_bygroup = TOPIC_BY_GROUP_PREFIX; +- if(uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback) { +- subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/WriteAttributes"; +- uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_WriteAttributes); ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_report( ++ jsn, ++ fields.user_identifier, ++ ++ fields.schedule_slotid, ++ ++ fields.week_day_bitmask, ++ ++ fields.start_hour, ++ ++ fields.start_minute, ++ ++ fields.duration_hour, ++ ++ fields.duration_minute ++ ); ++ ++ // 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, "UnifyScheduleEntryLock", "DailyRepeatingReport"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingReport", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingReport", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback( ++ group_id, ++ &fields ++ ); ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_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("UserIdentifier") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingReport: Missing command-argument: UserIdentifier\n"); ++ return; ++ } ++ if (jsn.find("ScheduleSlotID") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingReport: Missing command-argument: ScheduleSlotID\n"); ++ return; ++ } ++ if (jsn.find("WeekDayBitmask") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingReport: Missing command-argument: WeekDayBitmask\n"); ++ return; ++ } ++ if (jsn.find("StartHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingReport: Missing command-argument: StartHour\n"); ++ return; ++ } ++ if (jsn.find("StartMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingReport: Missing command-argument: StartMinute\n"); ++ return; ++ } ++ if (jsn.find("DurationHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingReport: Missing command-argument: DurationHour\n"); ++ return; ++ } ++ if (jsn.find("DurationMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingReport: Missing command-argument: DurationMinute\n"); ++ return; ++ } ++ ++ group_dispatch_callback( ++ group_id, ++ "UnifyScheduleEntryLock", ++ "DailyRepeatingReport", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_report); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "DailyRepeatingReport: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/WeekDayGet ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_week_day_get( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_get_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_schedule_entry_lock_week_day_get_callback != nullptr) { ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_fields_t fields; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_week_day_get( ++ jsn, ++ fields.user_identifier, ++ ++ fields.schedule_slotid ++ ); ++ ++ // 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, "UnifyScheduleEntryLock", "WeekDayGet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayGet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WeekDayGet", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_get_callback( ++ group_id, ++ &fields ++ ); ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_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("UserIdentifier") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDayGet: Missing command-argument: UserIdentifier\n"); ++ return; ++ } ++ if (jsn.find("ScheduleSlotID") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::WeekDayGet: Missing command-argument: ScheduleSlotID\n"); ++ return; ++ } ++ ++ group_dispatch_callback( ++ group_id, ++ "UnifyScheduleEntryLock", ++ "WeekDayGet", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_week_day_get); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "WeekDayGet: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/YearDaySet ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_year_day_set( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_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_schedule_entry_lock_year_day_set_callback != nullptr) { ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_set_fields_t fields; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_set( ++ jsn, ++ fields.set_action, ++ ++ fields.user_identifier, ++ ++ fields.schedule_slotid, ++ ++ fields.start_year, ++ ++ fields.start_day, ++ ++ fields.start_hour, ++ ++ fields.start_month, ++ ++ fields.start_minute, ++ ++ fields.stop_year, ++ ++ fields.stop_month, ++ ++ fields.stop_day, ++ ++ fields.stop_hour, ++ ++ fields.stop_minute ++ ); ++ ++ // 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, "UnifyScheduleEntryLock", "YearDaySet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDaySet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDaySet", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_set_callback( ++ group_id, ++ &fields ++ ); ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_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("SetAction") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: SetAction\n"); ++ return; ++ } ++ if (jsn.find("UserIdentifier") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: UserIdentifier\n"); ++ return; ++ } ++ if (jsn.find("ScheduleSlotID") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: ScheduleSlotID\n"); ++ return; ++ } ++ if (jsn.find("StartYear") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: StartYear\n"); ++ return; ++ } ++ if (jsn.find("StartDay") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: StartDay\n"); ++ return; ++ } ++ if (jsn.find("StartHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: StartHour\n"); ++ return; ++ } ++ if (jsn.find("StartMonth") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: StartMonth\n"); ++ return; ++ } ++ if (jsn.find("StartMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: StartMinute\n"); ++ return; ++ } ++ if (jsn.find("StopYear") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: StopYear\n"); ++ return; ++ } ++ if (jsn.find("StopMonth") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: StopMonth\n"); ++ return; ++ } ++ if (jsn.find("StopDay") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: StopDay\n"); ++ return; ++ } ++ if (jsn.find("StopHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: StopHour\n"); ++ return; ++ } ++ if (jsn.find("StopMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDaySet: Missing command-argument: StopMinute\n"); ++ return; ++ } ++ ++ group_dispatch_callback( ++ group_id, ++ "UnifyScheduleEntryLock", ++ "YearDaySet", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_set); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "YearDaySet: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/YearDayGet ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_year_day_get( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_get_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_schedule_entry_lock_year_day_get_callback != nullptr) { ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_fields_t fields; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_year_day_get( ++ jsn, ++ fields.user_identifier, ++ ++ fields.schedule_slotid ++ ); ++ ++ // 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, "UnifyScheduleEntryLock", "YearDayGet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayGet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "YearDayGet", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_get_callback( ++ group_id, ++ &fields ++ ); ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_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("UserIdentifier") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayGet: Missing command-argument: UserIdentifier\n"); ++ return; ++ } ++ if (jsn.find("ScheduleSlotID") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::YearDayGet: Missing command-argument: ScheduleSlotID\n"); ++ return; ++ } ++ ++ group_dispatch_callback( ++ group_id, ++ "UnifyScheduleEntryLock", ++ "YearDayGet", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_year_day_get); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "YearDayGet: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/DailyRepeatingSet ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_daily_repeating_set( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_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_schedule_entry_lock_daily_repeating_set_callback != nullptr) { ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_set_fields_t fields; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_set( ++ jsn, ++ fields.set_action, ++ ++ fields.user_identifier, ++ ++ fields.schedule_slotid, ++ ++ fields.week_day_bitmask, ++ ++ fields.start_hour, ++ ++ fields.start_minute, ++ ++ fields.duration_hour, ++ ++ fields.duration_minute ++ ); ++ ++ // 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, "UnifyScheduleEntryLock", "DailyRepeatingSet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingSet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingSet", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_set_callback( ++ group_id, ++ &fields ++ ); ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_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("SetAction") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingSet: Missing command-argument: SetAction\n"); ++ return; ++ } ++ if (jsn.find("UserIdentifier") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingSet: Missing command-argument: UserIdentifier\n"); ++ return; ++ } ++ if (jsn.find("ScheduleSlotID") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingSet: Missing command-argument: ScheduleSlotID\n"); ++ return; ++ } ++ if (jsn.find("WeekDayBitmask") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingSet: Missing command-argument: WeekDayBitmask\n"); ++ return; ++ } ++ if (jsn.find("StartHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingSet: Missing command-argument: StartHour\n"); ++ return; ++ } ++ if (jsn.find("StartMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingSet: Missing command-argument: StartMinute\n"); ++ return; ++ } ++ if (jsn.find("DurationHour") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingSet: Missing command-argument: DurationHour\n"); ++ return; ++ } ++ if (jsn.find("DurationMinute") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingSet: Missing command-argument: DurationMinute\n"); ++ return; ++ } ++ ++ group_dispatch_callback( ++ group_id, ++ "UnifyScheduleEntryLock", ++ "DailyRepeatingSet", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_set); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "DailyRepeatingSet: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } ++ ++} ++ ++// Callback function for incoming publications on ucl/by-group/+/UnifyScheduleEntryLock/Commands/DailyRepeatingGet ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_daily_repeating_get( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_get_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_schedule_entry_lock_daily_repeating_get_callback != nullptr) { ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_fields_t fields; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_daily_repeating_get( ++ jsn, ++ fields.user_identifier, ++ ++ fields.schedule_slotid ++ ); ++ ++ // 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, "UnifyScheduleEntryLock", "DailyRepeatingGet"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingGet", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "DailyRepeatingGet", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_get_callback( ++ group_id, ++ &fields ++ ); ++ } else if ((group_dispatch_callback != nullptr) && (!get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_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("UserIdentifier") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingGet: Missing command-argument: UserIdentifier\n"); ++ return; ++ } ++ if (jsn.find("ScheduleSlotID") == jsn.end()) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock::DailyRepeatingGet: Missing command-argument: ScheduleSlotID\n"); ++ return; ++ } ++ ++ group_dispatch_callback( ++ group_id, ++ "UnifyScheduleEntryLock", ++ "DailyRepeatingGet", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_daily_repeating_get); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "DailyRepeatingGet: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } ++ ++} ++ ++static void uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_WriteAttributes( ++ const char *topic, ++ const char *message, ++ const size_t message_length) ++{ ++ ++ if ((group_dispatch_callback == nullptr) && (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_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_schedule_entry_lock_write_attributes_callback().empty())) { ++ try { ++ group_dispatch_callback(group_id, ++ "UnifyScheduleEntryLock", ++ "WriteAttributes", ++ message, ++ message_length, ++ uic_mqtt_dotdot_on_unify_schedule_entry_lock_WriteAttributes); ++ ++ } catch (...) { ++ sl_log_debug(LOG_TAG, "UnifyScheduleEntryLock: Unable to parse JSON payload.\n"); ++ return; ++ } ++ } else if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback != nullptr) { ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_state_t new_state = {}; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t new_updated_state = {}; ++ ++ ++ nlohmann::json jsn; ++ try { ++ jsn = nlohmann::json::parse(std::string(message)); ++ ++ uic_mqtt_dotdot_parse_unify_schedule_entry_lock_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, "UnifyScheduleEntryLock", "WriteAttributes"); ++ return; ++ } catch (const nlohmann::json::exception& e) { ++ // Catch JSON object field parsing errors ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", e.what()); ++ return; ++ } catch (const std::exception& e) { ++ sl_log_debug(LOG_TAG, LOG_FMT_JSON_ERROR, "UnifyScheduleEntryLock", "WriteAttributes", ""); ++ return; ++ } ++ ++ uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback( ++ group_id, ++ new_state, ++ new_updated_state ++ ); ++ } ++} ++ ++sl_status_t uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_init() ++{ ++ std::string subscription_topic; ++ const std::string topic_bygroup = TOPIC_BY_GROUP_PREFIX; ++ if(uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_write_attributes_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/WriteAttributes"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_WriteAttributes); ++ } ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_set_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/EnableSet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_enable_set); ++ } ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_report_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/WeekDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_week_day_report); ++ } ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_enable_all_set_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/EnableAllSet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_enable_all_set); ++ } ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_report_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/YearDayReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_year_day_report); ++ } ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_set_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/WeekDaySet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_week_day_set); ++ } ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_report_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/DailyRepeatingReport"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_daily_repeating_report); ++ } ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_week_day_get_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/WeekDayGet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_week_day_get); ++ } ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_set_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/YearDaySet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_year_day_set); + } +- if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback) { +- subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport"; +- uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report); ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_year_day_get_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/YearDayGet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_year_day_get); + } +- if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback) { +- subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport"; +- uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report); ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_set_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/DailyRepeatingSet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_daily_repeating_set); + } +- if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback) { +- subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport"; +- uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report); ++ if (uic_mqtt_dotdot_by_group_unify_schedule_entry_lock_daily_repeating_get_callback) { ++ subscription_topic = topic_bygroup + "UnifyScheduleEntryLock/Commands/DailyRepeatingGet"; ++ uic_mqtt_subscribe(subscription_topic.c_str(), uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_daily_repeating_get); + } + + return SL_STATUS_OK; +@@ -24517,9 +25461,17 @@ void uic_mqtt_dotdot_set_group_dispatch_callback(group_dispatch_t callback) + uic_mqtt_subscribe("ucl/by-group/+/UnifyThermostat/Commands/WriteAttributes", uic_mqtt_dotdot_on_by_group_unify_thermostat_WriteAttributes); + + uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/WriteAttributes", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_WriteAttributes); +- uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_week_day_report); +- uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_year_day_report); +- uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/EnableSet", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_enable_set); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/WeekDayReport", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_week_day_report); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/EnableAllSet", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_enable_all_set); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/YearDayReport", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_year_day_report); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/WeekDaySet", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_week_day_set); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/DailyRepeatingReport", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_daily_repeating_report); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/WeekDayGet", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_week_day_get); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/YearDaySet", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_year_day_set); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/YearDayGet", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_year_day_get); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/DailyRepeatingSet", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_daily_repeating_set); ++ uic_mqtt_subscribe("ucl/by-group/+/UnifyScheduleEntryLock/Commands/DailyRepeatingGet", uic_mqtt_dotdot_on_by_group_unify_schedule_entry_lock_daily_repeating_get); + + 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); +diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_send_commands.cpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_send_commands.cpp +index 2f17f4fceb..b0f33cde6d 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_send_commands.cpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_send_commands.cpp +@@ -13709,11 +13709,11 @@ void uic_mqtt_dotdot_unify_fan_control_publish_turn_off_command_to_group( + } + + /** +- * @brief Sends/Publishes a ScheduleEntryLockWeekDayReport command for ++ * @brief Sends/Publishes a EnableSet command for + * the UnifyScheduleEntryLock cluster to a destination. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/EnableSet + * + * @param destination_unid The UNID of the node that should receive the command. + * +@@ -13723,20 +13723,20 @@ void uic_mqtt_dotdot_unify_fan_control_publish_turn_off_command_to_group( + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_week_day_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_enable_set_command( + const dotdot_unid_t destination_unid, + const dotdot_endpoint_id_t destination_endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_set_fields_t *fields + + ) { + // Create the topic + std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + + std::to_string(destination_endpoint) + "/"; +- topic += "UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport"; ++ topic += "UnifyScheduleEntryLock/Commands/EnableSet"; + + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_enable_set_command( + fields); + + sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); +@@ -13749,28 +13749,28 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_week_ + } + + /** +- * @brief Sends/Publishes a ScheduleEntryLockWeekDayReport command for ++ * @brief Sends/Publishes a EnableSet command for + * the UnifyScheduleEntryLock cluster to a group. + * + * Publication will be made at the following topic +- * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/EnableSet + * + * @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_schedule_entry_lock_publish_schedule_entry_lock_week_day_report_command_to_group( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_enable_set_command_to_group( + uint16_t destination_group_id, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_week_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_set_fields_t *fields + + ){ + // Create the topic + std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + +- "/UnifyScheduleEntryLock/Commands/ScheduleEntryLockWeekDayReport"; ++ "/UnifyScheduleEntryLock/Commands/EnableSet"; + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_enable_set_command( + fields); + + sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); +@@ -13783,11 +13783,11 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_week_ + } + + /** +- * @brief Sends/Publishes a ScheduleEntryLockYearDayReport command for ++ * @brief Sends/Publishes a WeekDayReport command for + * the UnifyScheduleEntryLock cluster to a destination. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/WeekDayReport + * + * @param destination_unid The UNID of the node that should receive the command. + * +@@ -13797,20 +13797,20 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_week_ + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_year_day_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_week_day_report_command( + const dotdot_unid_t destination_unid, + const dotdot_endpoint_id_t destination_endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t *fields + + ) { + // Create the topic + std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + + std::to_string(destination_endpoint) + "/"; +- topic += "UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport"; ++ topic += "UnifyScheduleEntryLock/Commands/WeekDayReport"; + + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_week_day_report_command( + fields); + + sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); +@@ -13823,28 +13823,28 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_year_ + } + + /** +- * @brief Sends/Publishes a ScheduleEntryLockYearDayReport command for ++ * @brief Sends/Publishes a WeekDayReport command for + * the UnifyScheduleEntryLock cluster to a group. + * + * Publication will be made at the following topic +- * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/WeekDayReport + * + * @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_schedule_entry_lock_publish_schedule_entry_lock_year_day_report_command_to_group( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_week_day_report_command_to_group( + uint16_t destination_group_id, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_year_day_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t *fields + + ){ + // Create the topic + std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + +- "/UnifyScheduleEntryLock/Commands/ScheduleEntryLockYearDayReport"; ++ "/UnifyScheduleEntryLock/Commands/WeekDayReport"; + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_week_day_report_command( + fields); + + sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); +@@ -13857,11 +13857,11 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_year_ + } + + /** +- * @brief Sends/Publishes a ScheduleEntryLockDailyRepeatingReport command for ++ * @brief Sends/Publishes a EnableAllSet command for + * the UnifyScheduleEntryLock cluster to a destination. + * + * Publication will be made at the following topic +- * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/EnableAllSet + * + * @param destination_unid The UNID of the node that should receive the command. + * +@@ -13871,20 +13871,20 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_year_ + * @param fields Struct pointer with the fields value of the command + * + */ +-void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_daily_repeating_report_command( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_enable_all_set_command( + const dotdot_unid_t destination_unid, + const dotdot_endpoint_id_t destination_endpoint, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t *fields + + ) { + // Create the topic + std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + + std::to_string(destination_endpoint) + "/"; +- topic += "UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport"; ++ topic += "UnifyScheduleEntryLock/Commands/EnableAllSet"; + + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_enable_all_set_command( + fields); + + sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); +@@ -13897,28 +13897,620 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_schedule_entry_lock_daily + } + + /** +- * @brief Sends/Publishes a ScheduleEntryLockDailyRepeatingReport command for ++ * @brief Sends/Publishes a EnableAllSet command for + * the UnifyScheduleEntryLock cluster to a group. + * + * Publication will be made at the following topic +- * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/EnableAllSet + * + * @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_schedule_entry_lock_publish_schedule_entry_lock_daily_repeating_report_command_to_group( ++void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_enable_all_set_command_to_group( + uint16_t destination_group_id, +- const uic_mqtt_dotdot_unify_schedule_entry_lock_command_schedule_entry_lock_daily_repeating_report_fields_t *fields ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_enable_all_set_fields_t *fields + + ){ + // Create the topic + std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + +- "/UnifyScheduleEntryLock/Commands/ScheduleEntryLockDailyRepeatingReport"; ++ "/UnifyScheduleEntryLock/Commands/EnableAllSet"; + + std::string payload = +- get_json_payload_for_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_command( ++ get_json_payload_for_unify_schedule_entry_lock_enable_all_set_command( ++ fields); ++ ++ sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a YearDayReport command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/YearDayReport ++ * ++ * @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_schedule_entry_lock_publish_year_day_report_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + ++ std::to_string(destination_endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/Commands/YearDayReport"; ++ ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_year_day_report_command( ++ fields); ++ ++ sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a YearDayReport command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/YearDayReport ++ * ++ * @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_schedule_entry_lock_publish_year_day_report_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t *fields ++ ++){ ++ // Create the topic ++ std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + ++ "/UnifyScheduleEntryLock/Commands/YearDayReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_year_day_report_command( ++ fields); ++ ++ sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a WeekDaySet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/WeekDaySet ++ * ++ * @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_schedule_entry_lock_publish_week_day_set_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + ++ std::to_string(destination_endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/Commands/WeekDaySet"; ++ ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_week_day_set_command( ++ fields); ++ ++ sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a WeekDaySet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/WeekDaySet ++ * ++ * @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_schedule_entry_lock_publish_week_day_set_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_set_fields_t *fields ++ ++){ ++ // Create the topic ++ std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + ++ "/UnifyScheduleEntryLock/Commands/WeekDaySet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_week_day_set_command( ++ fields); ++ ++ sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a DailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/DailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_report_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + ++ std::to_string(destination_endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/Commands/DailyRepeatingReport"; ++ ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_report_command( ++ fields); ++ ++ sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a DailyRepeatingReport command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/DailyRepeatingReport ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_report_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t *fields ++ ++){ ++ // Create the topic ++ std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + ++ "/UnifyScheduleEntryLock/Commands/DailyRepeatingReport"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_report_command( ++ fields); ++ ++ sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a WeekDayGet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/WeekDayGet ++ * ++ * @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_schedule_entry_lock_publish_week_day_get_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + ++ std::to_string(destination_endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/Commands/WeekDayGet"; ++ ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_week_day_get_command( ++ fields); ++ ++ sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a WeekDayGet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/WeekDayGet ++ * ++ * @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_schedule_entry_lock_publish_week_day_get_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_get_fields_t *fields ++ ++){ ++ // Create the topic ++ std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + ++ "/UnifyScheduleEntryLock/Commands/WeekDayGet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_week_day_get_command( ++ fields); ++ ++ sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a YearDaySet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/YearDaySet ++ * ++ * @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_schedule_entry_lock_publish_year_day_set_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_set_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + ++ std::to_string(destination_endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/Commands/YearDaySet"; ++ ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_year_day_set_command( ++ fields); ++ ++ sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a YearDaySet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/YearDaySet ++ * ++ * @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_schedule_entry_lock_publish_year_day_set_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_set_fields_t *fields ++ ++){ ++ // Create the topic ++ std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + ++ "/UnifyScheduleEntryLock/Commands/YearDaySet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_year_day_set_command( ++ fields); ++ ++ sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a YearDayGet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/YearDayGet ++ * ++ * @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_schedule_entry_lock_publish_year_day_get_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + ++ std::to_string(destination_endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/Commands/YearDayGet"; ++ ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_year_day_get_command( ++ fields); ++ ++ sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a YearDayGet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/YearDayGet ++ * ++ * @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_schedule_entry_lock_publish_year_day_get_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_get_fields_t *fields ++ ++){ ++ // Create the topic ++ std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + ++ "/UnifyScheduleEntryLock/Commands/YearDayGet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_year_day_get_command( ++ fields); ++ ++ sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a DailyRepeatingSet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/DailyRepeatingSet ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_set_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_set_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + ++ std::to_string(destination_endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/Commands/DailyRepeatingSet"; ++ ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_set_command( ++ fields); ++ ++ sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a DailyRepeatingSet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/DailyRepeatingSet ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_set_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_set_fields_t *fields ++ ++){ ++ // Create the topic ++ std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + ++ "/UnifyScheduleEntryLock/Commands/DailyRepeatingSet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_set_command( ++ fields); ++ ++ sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a DailyRepeatingGet command for ++ * the UnifyScheduleEntryLock cluster to a destination. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-unid/UNID/epID/UnifyScheduleEntryLock/Commands/DailyRepeatingGet ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_get_command( ++ const dotdot_unid_t destination_unid, ++ const dotdot_endpoint_id_t destination_endpoint, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_fields_t *fields ++ ++) { ++ // Create the topic ++ std::string topic = "ucl/by-unid/"+ std::string(destination_unid) + "/ep" + ++ std::to_string(destination_endpoint) + "/"; ++ topic += "UnifyScheduleEntryLock/Commands/DailyRepeatingGet"; ++ ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_get_command( ++ fields); ++ ++ sl_log_debug(LOG_TAG, "Sending command to %s with payload %s ---", topic.c_str() , payload.c_str()); ++ ++ // Publish our command, not retained ++ uic_mqtt_publish(topic.c_str(), ++ payload.c_str(), ++ payload.size(), ++ false); ++} ++ ++/** ++ * @brief Sends/Publishes a DailyRepeatingGet command for ++ * the UnifyScheduleEntryLock cluster to a group. ++ * ++ * Publication will be made at the following topic ++ * ucl/by-group/GroupID/UnifyScheduleEntryLock/Commands/DailyRepeatingGet ++ * ++ * @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_schedule_entry_lock_publish_daily_repeating_get_command_to_group( ++ uint16_t destination_group_id, ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_get_fields_t *fields ++ ++){ ++ // Create the topic ++ std::string topic = "ucl/by-group/"+ std::to_string(destination_group_id) + ++ "/UnifyScheduleEntryLock/Commands/DailyRepeatingGet"; ++ ++ std::string payload = ++ get_json_payload_for_unify_schedule_entry_lock_daily_repeating_get_command( + fields); + + sl_log_info(LOG_TAG, "Sending group command to %s with payload %s ---", topic.c_str() , payload.c_str()); +diff --git a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp +index 39ed2297f0..0749270e54 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp ++++ b/components/uic_dotdot_mqtt/zap-generated/src/dotdot_mqtt_supported_generated_commands.cpp +@@ -2881,14 +2881,38 @@ void uic_mqtt_dotdot_unify_schedule_entry_lock_publish_supported_generated_comma + + // Assemble of vector of strings for the Supported Commands: + std::vector command_vector; +- if (command_list->schedule_entry_lock_week_day_report == true) { +- command_vector.emplace_back("ScheduleEntryLockWeekDayReport"); ++ if (command_list->enable_set == true) { ++ command_vector.emplace_back("EnableSet"); + } +- if (command_list->schedule_entry_lock_year_day_report == true) { +- command_vector.emplace_back("ScheduleEntryLockYearDayReport"); ++ if (command_list->week_day_report == true) { ++ command_vector.emplace_back("WeekDayReport"); + } +- if (command_list->schedule_entry_lock_daily_repeating_report == true) { +- command_vector.emplace_back("ScheduleEntryLockDailyRepeatingReport"); ++ if (command_list->enable_all_set == true) { ++ command_vector.emplace_back("EnableAllSet"); ++ } ++ if (command_list->year_day_report == true) { ++ command_vector.emplace_back("YearDayReport"); ++ } ++ if (command_list->week_day_set == true) { ++ command_vector.emplace_back("WeekDaySet"); ++ } ++ if (command_list->daily_repeating_report == true) { ++ command_vector.emplace_back("DailyRepeatingReport"); ++ } ++ if (command_list->week_day_get == true) { ++ command_vector.emplace_back("WeekDayGet"); ++ } ++ if (command_list->year_day_set == true) { ++ command_vector.emplace_back("YearDaySet"); ++ } ++ if (command_list->year_day_get == true) { ++ command_vector.emplace_back("YearDayGet"); ++ } ++ if (command_list->daily_repeating_set == true) { ++ command_vector.emplace_back("DailyRepeatingSet"); ++ } ++ if (command_list->daily_repeating_get == true) { ++ command_vector.emplace_back("DailyRepeatingGet"); + } + if (command_list->write_attributes == true) { + command_vector.emplace_back("WriteAttributes"); +diff --git a/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include b/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include +index c047606bb6..cb26310863 100644 +--- a/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include ++++ b/components/uic_dotdot_mqtt/zap-generated/test/dotdot_mqtt_test.include +@@ -2995,8 +2995,23 @@ static sl_status_t uic_mqtt_dotdot_unify_fan_control_turn_off_callback_func( + return SL_STATUS_OK; + } + +-static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_count; +-static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_func( ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_func( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t callback_type, ++ uint8_t user_identifier, ++ ++ uint8_t enabled ++ ++) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_count++; ++ num_command_callbacks++; ++ return SL_STATUS_OK; ++} ++ ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_func( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t callback_type, +@@ -3015,18 +3030,29 @@ static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + uint8_t stop_minute + + ) { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_count++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_count++; + num_command_callbacks++; + return SL_STATUS_OK; + } + +-static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_count; +-static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_func( ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_func( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t callback_type, +- uint8_t set_action, ++ uint8_t enabled + ++) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_count++; ++ num_command_callbacks++; ++ return SL_STATUS_OK; ++} ++ ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_func( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t callback_type, + uint8_t user_identifier, + + uint8_t schedule_slotid, +@@ -3052,13 +3078,13 @@ static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + uint8_t stop_minute + + ) { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_count++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_count++; + num_command_callbacks++; + return SL_STATUS_OK; + } + +-static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_count; +-static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_func( ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_func( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t callback_type, +@@ -3068,6 +3094,31 @@ static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + + uint8_t schedule_slotid, + ++ uint8_t day_of_week, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_minute, ++ ++ uint8_t stop_hour, ++ ++ uint8_t stop_minute ++ ++) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_count++; ++ num_command_callbacks++; ++ return SL_STATUS_OK; ++} ++ ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_func( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t callback_type, ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ + uint8_t week_day_bitmask, + + uint8_t start_hour, +@@ -3079,7 +3130,116 @@ static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock + uint8_t duration_minute + + ) { +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_count++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_count++; ++ num_command_callbacks++; ++ return SL_STATUS_OK; ++} ++ ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_func( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t callback_type, ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid ++ ++) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_count++; ++ num_command_callbacks++; ++ return SL_STATUS_OK; ++} ++ ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_func( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t callback_type, ++ uint8_t set_action, ++ ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ ++ uint8_t start_year, ++ ++ uint8_t start_day, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_month, ++ ++ uint8_t start_minute, ++ ++ uint8_t stop_year, ++ ++ uint8_t stop_month, ++ ++ uint8_t stop_day, ++ ++ uint8_t stop_hour, ++ ++ uint8_t stop_minute ++ ++) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_count++; ++ num_command_callbacks++; ++ return SL_STATUS_OK; ++} ++ ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_func( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t callback_type, ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid ++ ++) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_count++; ++ num_command_callbacks++; ++ return SL_STATUS_OK; ++} ++ ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_func( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t callback_type, ++ uint8_t set_action, ++ ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid, ++ ++ uint8_t week_day_bitmask, ++ ++ uint8_t start_hour, ++ ++ uint8_t start_minute, ++ ++ uint8_t duration_hour, ++ ++ uint8_t duration_minute ++ ++) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_count++; ++ num_command_callbacks++; ++ return SL_STATUS_OK; ++} ++ ++static unsigned int uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_count; ++static sl_status_t uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_func( ++ dotdot_unid_t unid, ++ dotdot_endpoint_id_t endpoint, ++ uic_mqtt_dotdot_callback_call_type_t callback_type, ++ uint8_t user_identifier, ++ ++ uint8_t schedule_slotid ++ ++) { ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_count++; + num_command_callbacks++; + return SL_STATUS_OK; + } +@@ -3498,11 +3658,27 @@ static unsigned int set_all_callbacks() + num_callbacks++; + uic_mqtt_dotdot_unify_fan_control_turn_off_callback_set(&uic_mqtt_dotdot_unify_fan_control_turn_off_callback_func); + num_callbacks++; +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_func); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_func); ++ num_callbacks++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_func); ++ num_callbacks++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_func); ++ num_callbacks++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_func); ++ num_callbacks++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_func); ++ num_callbacks++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_func); ++ num_callbacks++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_func); ++ num_callbacks++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_func); ++ num_callbacks++; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_func); + num_callbacks++; +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_func); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_func); + num_callbacks++; +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_func); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_set(&uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_func); + num_callbacks++; + uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_set(&uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_func); + num_callbacks++; +@@ -3756,9 +3932,17 @@ static void unset_all_callbacks() + uic_mqtt_dotdot_unify_fan_control_turn_off_callback_clear(); + uic_mqtt_dotdot_clear_unify_fan_control_write_attributes_callbacks(); + uic_mqtt_dotdot_clear_unify_thermostat_write_attributes_callbacks(); +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_clear(); +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_clear(); +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_clear(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_clear(); + uic_mqtt_dotdot_clear_unify_schedule_entry_lock_write_attributes_callbacks(); + uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_clear(); + uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_clear(); +@@ -3957,9 +4141,17 @@ static void reset_callback_counters() + uic_mqtt_dotdot_protocol_controller_network_management_write_callback_count = 0; + uic_mqtt_dotdot_unify_fan_control_set_fan_mode_callback_count = 0; + uic_mqtt_dotdot_unify_fan_control_turn_off_callback_count = 0; +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_count = 0; +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_count = 0; +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_count = 0; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_count = 0; + uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_count = 0; + uic_mqtt_dotdot_unify_humidity_control_setpoint_set_callback_count = 0; + } +diff --git a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c +index b4559eb2d0..f37674dd63 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c ++++ b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.c +@@ -1332,17 +1332,49 @@ uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t get_uic_mq + return test_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback; + } + +-static uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback = NULL; +-uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback(){ +- return test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback; ++static uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback; + } +-static uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback = NULL; +-uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback(){ +- return test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback; ++static uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback; + } +-static uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback = NULL; +-uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback(){ +- return test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback; ++static uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback; ++} ++static uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback; ++} ++static uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback; ++} ++static uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback; ++} ++static uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback; ++} ++static uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback; ++} ++static uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback; ++} ++static uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback; ++} ++static uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback = NULL; ++uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback(){ ++ return test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback; + } + static uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_t test_uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback = NULL; + static uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback_t test_uic_mqtt_dotdot_unify_humidity_control_write_attributes_callback = NULL; +@@ -2963,20 +2995,60 @@ void set_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_stu + { + test_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback = callback; + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set_stub( +- const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t callback, int cmock_num_calls) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t callback, int cmock_num_calls) ++{ ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback = callback; ++} ++void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t callback, int cmock_num_calls) + { +- test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback = callback; ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback = callback; + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set_stub( +- const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t callback, int cmock_num_calls) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t callback, int cmock_num_calls) + { +- test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback = callback; ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback = callback; + } +-void uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set_stub( +- const uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t callback, int cmock_num_calls) ++void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_set_stub( ++ const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t callback, int cmock_num_calls) + { +- test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback = callback; ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback = callback; + } + void set_uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_stub( + const uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_t callback, int cmock_num_calls) +@@ -3930,15 +4002,39 @@ void setUp() + test_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback = NULL; + uic_mqtt_dotdot_set_unify_schedule_entry_lock_write_attributes_callback_Stub( + &set_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_stub); +- test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback = NULL; +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set_Stub( +- &uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_set_stub); +- test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback = NULL; +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set_Stub( +- &uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_set_stub); +- test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback = NULL; +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set_Stub( +- &uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_set_stub); ++ test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback = NULL; ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_set_Stub( ++ &uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_set_stub); + test_uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback = NULL; + uic_mqtt_dotdot_set_unify_humidity_control_force_read_attributes_callback_Stub( + &set_uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_stub); +@@ -7818,7 +7914,22 @@ void test_automatic_deduction_of_supported_commands() + + )); + } +- if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback) { ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t enabled_value; ++ memset(&enabled_value, 0x00, sizeof(enabled_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ enabled_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback) { + // Dummy command parameters + uint8_t user_identifier_value; + memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); +@@ -7835,7 +7946,7 @@ void test_automatic_deduction_of_supported_commands() + uint8_t stop_minute_value; + memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); + // Invoke with support check +- TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK + , + user_identifier_value, + +@@ -7853,10 +7964,19 @@ void test_automatic_deduction_of_supported_commands() + + )); + } +- if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback) { ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback) { ++ // Dummy command parameters ++ uint8_t enabled_value; ++ memset(&enabled_value, 0x00, sizeof(enabled_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ enabled_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback) { + // Dummy command parameters +- uint8_t set_action_value; +- memset(&set_action_value, 0x00, sizeof(set_action_value)); + uint8_t user_identifier_value; + memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); + uint8_t schedule_slotid_value; +@@ -7882,10 +8002,8 @@ void test_automatic_deduction_of_supported_commands() + uint8_t stop_minute_value; + memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); + // Invoke with support check +- TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK + , +- set_action_value, +- + user_identifier_value, + + schedule_slotid_value, +@@ -7912,7 +8030,170 @@ void test_automatic_deduction_of_supported_commands() + + )); + } +- if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback) { ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback) { ++ // Dummy command parameters ++ uint8_t set_action_value; ++ memset(&set_action_value, 0x00, sizeof(set_action_value)); ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t day_of_week_value; ++ memset(&day_of_week_value, 0x00, sizeof(day_of_week_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ set_action_value, ++ ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ day_of_week_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t week_day_bitmask_value; ++ memset(&week_day_bitmask_value, 0x00, sizeof(week_day_bitmask_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t duration_hour_value; ++ memset(&duration_hour_value, 0x00, sizeof(duration_hour_value)); ++ uint8_t duration_minute_value; ++ memset(&duration_minute_value, 0x00, sizeof(duration_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ week_day_bitmask_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ duration_hour_value, ++ ++ duration_minute_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback) { ++ // Dummy command parameters ++ uint8_t set_action_value; ++ memset(&set_action_value, 0x00, sizeof(set_action_value)); ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t start_year_value; ++ memset(&start_year_value, 0x00, sizeof(start_year_value)); ++ uint8_t start_day_value; ++ memset(&start_day_value, 0x00, sizeof(start_day_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_month_value; ++ memset(&start_month_value, 0x00, sizeof(start_month_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_year_value; ++ memset(&stop_year_value, 0x00, sizeof(stop_year_value)); ++ uint8_t stop_month_value; ++ memset(&stop_month_value, 0x00, sizeof(stop_month_value)); ++ uint8_t stop_day_value; ++ memset(&stop_day_value, 0x00, sizeof(stop_day_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ set_action_value, ++ ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ start_year_value, ++ ++ start_day_value, ++ ++ start_hour_value, ++ ++ start_month_value, ++ ++ start_minute_value, ++ ++ stop_year_value, ++ ++ stop_month_value, ++ ++ stop_day_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback) { + // Dummy command parameters + uint8_t set_action_value; + memset(&set_action_value, 0x00, sizeof(set_action_value)); +@@ -7931,7 +8212,7 @@ void test_automatic_deduction_of_supported_commands() + uint8_t duration_minute_value; + memset(&duration_minute_value, 0x00, sizeof(duration_minute_value)); + // Invoke with support check +- TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK + , + set_action_value, + +@@ -7951,6 +8232,21 @@ void test_automatic_deduction_of_supported_commands() + + )); + } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_FAIL, test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value ++ ++ )); ++ } + if (NULL != test_uic_mqtt_dotdot_unify_humidity_control_mode_set_callback) { + // Dummy command parameters + ModeType mode_value; +@@ -11066,7 +11362,22 @@ void test_automatic_deduction_of_supported_commands() + + )); + } +- if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback) { ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t enabled_value; ++ memset(&enabled_value, 0x00, sizeof(enabled_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ enabled_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback) { + // Dummy command parameters + uint8_t user_identifier_value; + memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); +@@ -11083,7 +11394,7 @@ void test_automatic_deduction_of_supported_commands() + uint8_t stop_minute_value; + memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); + // Invoke with support check +- TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK + , + user_identifier_value, + +@@ -11101,7 +11412,162 @@ void test_automatic_deduction_of_supported_commands() + + )); + } +- if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback) { ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback) { ++ // Dummy command parameters ++ uint8_t enabled_value; ++ memset(&enabled_value, 0x00, sizeof(enabled_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ enabled_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t start_year_value; ++ memset(&start_year_value, 0x00, sizeof(start_year_value)); ++ uint8_t start_month_value; ++ memset(&start_month_value, 0x00, sizeof(start_month_value)); ++ uint8_t start_day_value; ++ memset(&start_day_value, 0x00, sizeof(start_day_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_year_value; ++ memset(&stop_year_value, 0x00, sizeof(stop_year_value)); ++ uint8_t stop_month_value; ++ memset(&stop_month_value, 0x00, sizeof(stop_month_value)); ++ uint8_t stop_day_value; ++ memset(&stop_day_value, 0x00, sizeof(stop_day_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ start_year_value, ++ ++ start_month_value, ++ ++ start_day_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ stop_year_value, ++ ++ stop_month_value, ++ ++ stop_day_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback) { ++ // Dummy command parameters ++ uint8_t set_action_value; ++ memset(&set_action_value, 0x00, sizeof(set_action_value)); ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t day_of_week_value; ++ memset(&day_of_week_value, 0x00, sizeof(day_of_week_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t stop_hour_value; ++ memset(&stop_hour_value, 0x00, sizeof(stop_hour_value)); ++ uint8_t stop_minute_value; ++ memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ set_action_value, ++ ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ day_of_week_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ stop_hour_value, ++ ++ stop_minute_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ uint8_t week_day_bitmask_value; ++ memset(&week_day_bitmask_value, 0x00, sizeof(week_day_bitmask_value)); ++ uint8_t start_hour_value; ++ memset(&start_hour_value, 0x00, sizeof(start_hour_value)); ++ uint8_t start_minute_value; ++ memset(&start_minute_value, 0x00, sizeof(start_minute_value)); ++ uint8_t duration_hour_value; ++ memset(&duration_hour_value, 0x00, sizeof(duration_hour_value)); ++ uint8_t duration_minute_value; ++ memset(&duration_minute_value, 0x00, sizeof(duration_minute_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value, ++ ++ week_day_bitmask_value, ++ ++ start_hour_value, ++ ++ start_minute_value, ++ ++ duration_hour_value, ++ ++ duration_minute_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback) { + // Dummy command parameters + uint8_t set_action_value; + memset(&set_action_value, 0x00, sizeof(set_action_value)); +@@ -11130,7 +11596,7 @@ void test_automatic_deduction_of_supported_commands() + uint8_t stop_minute_value; + memset(&stop_minute_value, 0x00, sizeof(stop_minute_value)); + // Invoke with support check +- TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK + , + set_action_value, + +@@ -11160,7 +11626,22 @@ void test_automatic_deduction_of_supported_commands() + + )); + } +- if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback) { ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value ++ ++ )); ++ } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback) { + // Dummy command parameters + uint8_t set_action_value; + memset(&set_action_value, 0x00, sizeof(set_action_value)); +@@ -11179,7 +11660,7 @@ void test_automatic_deduction_of_supported_commands() + uint8_t duration_minute_value; + memset(&duration_minute_value, 0x00, sizeof(duration_minute_value)); + // Invoke with support check +- TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK + , + set_action_value, + +@@ -11199,6 +11680,21 @@ void test_automatic_deduction_of_supported_commands() + + )); + } ++ if (NULL != test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback) { ++ // Dummy command parameters ++ uint8_t user_identifier_value; ++ memset(&user_identifier_value, 0x00, sizeof(user_identifier_value)); ++ uint8_t schedule_slotid_value; ++ memset(&schedule_slotid_value, 0x00, sizeof(schedule_slotid_value)); ++ // Invoke with support check ++ TEST_ASSERT_EQUAL(SL_STATUS_OK, test_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback(expected_unid,expected_endpoint_id,UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK ++ , ++ user_identifier_value, ++ ++ schedule_slotid_value ++ ++ )); ++ } + if (NULL != test_uic_mqtt_dotdot_unify_humidity_control_mode_set_callback) { + // Dummy command parameters + ModeType mode_value; +diff --git a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h +index cf53259d15..7f909e84ff 100644 +--- a/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h ++++ b/components/unify_dotdot_attribute_store/zap-generated/test/unify_dotdot_attribute_store_test.h +@@ -802,13 +802,37 @@ + uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback(); + + +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_week_day_report_callback(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback(); + + +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_year_day_report_callback(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_report_callback(); + + +- uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_schedule_entry_lock_daily_repeating_report_callback(); ++ uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_report_callback(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_report_callback(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback(); ++ ++ ++ uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t get_uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback(); + + + uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback_t get_uic_mqtt_dotdot_unify_humidity_control_force_read_attributes_callback(); +-- +2.39.5 + From d55edd034d9c9cabc273ef4e1994889020a35e8b Mon Sep 17 00:00:00 2001 From: Thirupathi S Date: Wed, 4 Sep 2024 07:51:41 +0000 Subject: [PATCH 06/12] UIC-3434: Define and Register Z-Wave Attributes for Schedule Entry CC Merge in UIC/uic from feature/UIC-3434-data-model-Schedule-Entry-CC to feature/UIC-3271-Schedule-Entry-Lock-CC --- .../attribute_store_defined_attribute_types.h | 160 +++++++++++++++++- .../zpc_attribute_store_type_registration.cpp | 48 +++++- 2 files changed, 205 insertions(+), 3 deletions(-) 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 8d5e36adb..0167e691e 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 @@ -305,6 +305,164 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_DOOR_LOCK_OPERATION_REPORT_TARGET_MODE, DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_DOOR_LOCK_OPERATION_REPORT_DURATION, ((COMMAND_CLASS_DOOR_LOCK << 8) | 0x1e)) +/////////////////////////////////// +// Schedule Entry Lock Command Class + +// Version Attribute for the Schedule Entry Lock Command Class +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_VERSION, + ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_SCHEDULE_ENTRY_LOCK)) + +// V1 +// User Identifier Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x02)) + +// Enabled Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_ENABLED, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x03)) + +// Attribute for the Schedule Entry Lock Enable All Set Command (Enabled field) +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_ENABLE_ALL, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x04)) + +// Number of Slots Week Day Attribute (for Schedule Entry Lock Supported Report Command) +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x05)) + +// Number of Slots Year Day Attribute (for Schedule Entry Lock Supported Report Command) +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x06)) + +// Week Day Schedule Set Action Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SET_ACTION, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x07)) + +// Week Day Schedule Slot ID Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x09)) + +// Week Day Schedule Day of Week Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_DAY_OF_WEEK, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x0A)) + +// Week Day Schedule Start Hour Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_START_HOUR, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x0B)) + +// Week Day Schedule Start Minute Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_START_MINUTE, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x0C)) + +// Week Day Schedule Stop Hour Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_STOP_HOUR, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x0D)) + +// Week Day Schedule Stop Minute Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_STOP_MINUTE, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x0E)) + +// Year Day Schedule Set Action +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SET_ACTION, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x0F)) + +// Year Day Schedule Slot ID +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x10)) + +// Year Day Schedule Start Year +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_YEAR, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x11)) + +// Year Day Schedule Start Month +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_MONTH, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x12)) + +// Year Day Schedule Start Day +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_DAY, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x13)) + +// Year Day Schedule Start Hour +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_HOUR, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x14)) + +// Year Day Schedule Start Minutes +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_MINUTE, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x15)) + +// Year Day Schedule Stop Year +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_YEAR, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x16)) + +// Year Day Schedule Stop Month +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_MONTH, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x17)) + +// Year Day Schedule Stop Day +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_DAY, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x18)) + +// Year Day Schedule Stop Hour +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_HOUR, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x19)) + +// Year Day Schedule Stop Minutes +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_MINUTE, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x1A)) + +// V2 +// Time Zone Offset Sign Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SIGN_TZO, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x1B)) + +// Time Zone Offset Hour Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_HOUR_TZO, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x1C)) + +// Time Zone Offset Minute Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_MINUTE_TZO, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x1D)) + +// Daylight Saving Time (DST) Offset Sign Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x1E)) + +// DST Offset Minute Attribute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x1F)) + +// V3 +/// Number of Slots Daily Repeating +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x20)) + +// Daily Repeating Set Action +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SET_ACTION, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x21)) + +// Daily Repeating Slot ID +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x22)) + +// Daily Repeating Week Day +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_WEEK_DAY, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x23)) + +// Daily Repeating Start Hour +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_START_HOUR, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x24)) + +// Daily Repeating Start Minute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_START_MINUTE, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x25)) + +// Daily Repeating Duration Hour +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_DURATION_HOUR, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x26)) + +// Daily Repeating Duration Minute +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_DURATION_MINUTE, + ((COMMAND_CLASS_SCHEDULE_ENTRY_LOCK << 8) | 0x27)) + /////////////////////////////////// // Binary Switch Command Class DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_BINARY_SWITCH_VERSION, @@ -822,7 +980,7 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE, // 0x0B DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE_SCALE, ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x0A + SETPOINT_SCALE_ATTRIBUTE_ID_OFFSET))) -// 0x0C +// 0x0C DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE_PRECISION, ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x0A + SETPOINT_PRECISION_ATTRIBUTE_ID_OFFSET))) 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 574642769..121fbb924 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 @@ -121,7 +121,7 @@ static const std::vector attribute_schema = { // V3+ report {ATTRIBUTE_COMMAND_CLASS_BATTERY_LOW_TEMPERATURE, "Battery Low Temperature", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - // Health report (V2+) + // Health report (V2+) {ATTRIBUTE_COMMAND_CLASS_BATTERY_HEALTH_MAXIMUM_CAPACITY, "Maximum Capacity", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_BATTERY_HEALTH_SCALE, "Scale", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_BATTERY_HEALTH_PRECISION, "Precision", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, @@ -406,7 +406,7 @@ static const std::vector attribute_schema = { ///////////////////////////////////////////////////////////////////// {ATTRIBUTE_COMMAND_CLASS_SUPERVISION_VERSION, "Supervision Version", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SUPERVISION_ENABLED, "Supervision Enabled flag", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - + ///////////////////////////////////////////////////////////////////// // Wake Up Command Class attributes ///////////////////////////////////////////////////////////////////// @@ -514,6 +514,50 @@ static const std::vector attribute_schema = { {ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_NAME, "Tone Info Name", ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_IDENTIFIER, C_STRING_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_PLAY, "Tone Play", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + ///////////////////////////////////////////////////////////////////// + // Schedule Entry Lock Class attributes + ///////////////////////////////////////////////////////////////////// + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_VERSION, "Schedule Entry Lock Version", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, "Schedule Entry Lock User Identifier", ATTRIBUTE_ENDPOINT_ID, U16_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_ENABLED, "Schedule Entry Lock Enable", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_ENABLE_ALL, "Schedule Entry Lock All Set Enable", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY, "Number Of Slots Week Day", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY, "Number Of Slots Year Day", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SET_ACTION, "Week Day Schedule Set Action", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, "Week Day Schedule Slot ID", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_DAY_OF_WEEK, "Week Day Schedule Day Of Week", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_START_HOUR, "Week Day Schedule Start Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_START_MINUTE, "Week Day Schedule Start Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_STOP_HOUR, "Week Day Schedule Stop Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_STOP_MINUTE, "Week Day Schedule Stop Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SET_ACTION, "Year Day Schedule Set Action", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, "Year Day Schedule Slot ID", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_YEAR, "Year Day Schedule Start Year", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_MONTH, "Year Day Schedule Start Month", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_DAY, "Year Day Schedule Start Day", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_HOUR, "Year Day Schedule Start Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_MINUTE, "Year Day Schedule Start Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_YEAR, "Year Day Schedule Stop Year", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_MONTH, "Year Day Schedule Stop Month", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_DAY, "Year Day Schedule Stop Day", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_HOUR, "Year Day Schedule Stop Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_MINUTE, "Year Day Schedule Stop Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SIGN_TZO, "Schedule Entry Lock Sign TZO", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_HOUR_TZO, "Schedule Entry Lock Hour TZO", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_MINUTE_TZO, "Schedule Entry Lock Minute TZO", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN, "Schedule Entry Lock Sign Offset DST", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE, "Schedule Entry Lock Minute Offset DST", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING, "Number of Slots Daily Repeating", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SET_ACTION, "Daily Repeating Set Action", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, "Daily Repeating Slot ID", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_WEEK_DAY, "Daily Repeating Week Day", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_START_HOUR, "Daily Repeating Start Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_START_MINUTE, "Daily Repeating Start Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_DURATION_HOUR, "Daily Repeating Duration Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_DURATION_MINUTE, "Daily Repeating Duration Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + //DoorLock Command Class attributes {ATTRIBUTE_DOOR_LOCK_CONFIGURATION_OPERATION_TYPE, "Door Lock Configuration Operation Type", ATTRIBUTE_ENDPOINT_ID, I32_STORAGE_TYPE }, {ATTRIBUTE_DOOR_LOCK_CONFIGURATION_INSIDE_DOOR_HANDLES_STATE, "Door Lock Configuration Inside Handles State", ATTRIBUTE_ENDPOINT_ID, I32_STORAGE_TYPE }, From 22dca868f93bba7424a32cc4365ca8fb897ff7ce Mon Sep 17 00:00:00 2001 From: Thirupathi S Date: Tue, 10 Sep 2024 06:08:07 +0000 Subject: [PATCH 07/12] UIC-3435:Base skeleton code for schedule entry lock CC Merge in UIC/uic from feature/UIC-3435-Base-Skeleton-Code-Schedule-Entry-Lock-CC to feature/UIC-3271-Schedule-Entry-Lock-CC --- ...wave_command_class_schedule_entry_lock.cpp | 239 ++++++++++++++++++ .../zwave_command_class_schedule_entry_lock.h | 44 ++++ .../src/zwave_command_classes_fixt.c | 2 + 3 files changed, 285 insertions(+) create mode 100644 applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp create mode 100644 applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.h diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp new file mode 100644 index 000000000..0320e0d82 --- /dev/null +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp @@ -0,0 +1,239 @@ +/****************************************************************************** + * # 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 "zwave_command_class_schedule_entry_lock.h" +#include "zwave_command_classes_utils.h" + +// Generic includes +#include +#include + +// Includes from other ZPC Components +#include "zwave_command_class_indices.h" +#include "zwave_command_handler.h" +#include "zpc_attribute_store_network_helper.h" +#include "attribute_store_defined_attribute_types.h" +#include "ZW_classcmd.h" +#include "zpc_attribute_resolver.h" + +// Includes from other Unify Components +#include "dotdot_mqtt.h" +#include "dotdot_mqtt_generated_commands.h" +#include "attribute_store_helper.h" +#include "attribute_resolver.h" +#include "attribute_timeouts.h" +#include "sl_log.h" + +// Cpp include +#include "attribute.hpp" +#include "zwave_frame_generator.hpp" +#include "zwave_frame_parser.hpp" + +// Attribute macro, shortening those long defines for attribute types: +#define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_##type + +// Log tag +constexpr char LOG_TAG[] = "zwave_command_class_schedule_entry_lock"; + + +// Cpp helpers +namespace +{ +const zwave_frame_generator frame_generator(COMMAND_CLASS_SCHEDULE_ENTRY_LOCK); //NOSONAR - false positive since it is warped in a namespace +} + +/////////////////////////////////////////////////////////////////////////////// +// Helper functions +/////////////////////////////////////////////////////////////////////////////// +zwave_cc_version_t get_current_schedule_entry_lock_version(attribute_store_node_t node) +{ + zwave_cc_version_t version + = zwave_command_class_get_version_from_node(node, COMMAND_CLASS_SCHEDULE_ENTRY_LOCK); + + if (version == 0) { + sl_log_error(LOG_TAG, "schedule_entry_lock Command Class Version not found"); + } + + return version; +} +/////////////////////////////////////////////////////////////////////////////// +// Resolution functions +/////////////////////////////////////////////////////////////////////////////// +//static sl_status_t zwave_command_class_schedule_entry_lock_get( +// attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +//{ +// return frame_generator.generate_no_args_frame(schedule_entry_lock_GET, +// frame, +// frame_length); +//} + +// static sl_status_t zwave_command_class_schedule_entry_lock_set( +// attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +// { +// try { +// attribute_store::attribute value_node(node); +// auto current_version = get_current_schedule_entry_lock_version(node); +// +// // Compute expected size for set frame +// const uint8_t expected_frame_size = 12; +// +// // Creating the frame +// frame_generator.initialize_frame(schedule_entry_lock_SET, +// frame, +// expected_frame_size); +// frame_generator.add_value(value_node, DESIRED_OR_REPORTED_ATTRIBUTE); +// frame_generator.validate_frame(frame_length); +// } catch (const std::exception &e) { +// sl_log_error(LOG_TAG, +// "Error while generating schedule_entry_lock Set frame : %s", +// e.what()); +// return SL_STATUS_FAIL; +// } +// +// return SL_STATUS_OK; +//} + +/////////////////////////////////////////////////////////////////////////////// +// Frame parsing functions +/////////////////////////////////////////////////////////////////////////////// +//static sl_status_t zwave_command_class_schedule_entry_lock_handle_report( +// const zwave_controller_connection_info_t *connection_info, +// const uint8_t *frame_data, +// uint16_t frame_length) +//{ +// // Setup +// attribute_store::attribute endpoint_node( +// zwave_command_class_get_endpoint_node(connection_info)); +// auto current_version = get_current_schedule_entry_lock_version(endpoint_node); +// +// sl_log_debug(LOG_TAG, "schedule_entry_lock Report frame received"); +// +// // Compute expected size for report frame +// const uint8_t expected_size = 12; + +// // Parse the frame +// try { +// zwave_frame_parser parser(frame_data, frame_length); + +// if (!parser.is_frame_size_valid(expected_size)) { +// sl_log_error(LOG_TAG, +// "Invalid frame size for schedule_entry_lock Report frame"); +// return SL_STATUS_FAIL; +// } + +// } catch (const std::exception &e) { +// sl_log_error(LOG_TAG, +// "Error while parsing schedule_entry_lock Report frame : %s", +// e.what()); +// return SL_STATUS_FAIL; +// } +// return SL_STATUS_OK; +//} + +/////////////////////////////////////////////////////////////////////////////// +// Incoming commands handler +/////////////////////////////////////////////////////////////////////////////// +sl_status_t zwave_command_class_schedule_entry_lock_control_handler( + const zwave_controller_connection_info_t *connection_info, + const uint8_t *frame_data, + uint16_t frame_length) +{ + // Frame too short, it should have not come here. + if (frame_length <= COMMAND_INDEX) { + return SL_STATUS_NOT_SUPPORTED; + } + + switch (frame_data[COMMAND_INDEX]) { + // case schedule_entry_lock_REPORT: + // return zwave_command_class_schedule_entry_lock_handle_report(connection_info, + // frame_data, + // frame_length); + default: + return SL_STATUS_NOT_SUPPORTED; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Attribute Store callback functions +/////////////////////////////////////////////////////////////////////////////// +static void zwave_command_class_schedule_entry_lock_on_version_attribute_update( + attribute_store_node_t updated_node, attribute_store_change_t change) +{ + if (change == ATTRIBUTE_DELETED) { + return; + } + + // Confirm that we have a version attribute update + assert(ATTRIBUTE(VERSION) == attribute_store_get_node_type(updated_node)); + + attribute_store::attribute version_node(updated_node); + // Do not create the attributes until we are sure of the version + zwave_cc_version_t supporting_node_version = 0; + + // Wait for the version + if (!version_node.reported_exists()) { + return; + } + supporting_node_version = version_node.reported(); + + // Now we know we have a schedule_entry_lock supporting endpoint. + attribute_store::attribute endpoint_node + = version_node.first_parent(ATTRIBUTE_ENDPOINT_ID); + + // Create the schedule_entry_lock attributes + attribute_store::attribute userid_node = endpoint_node.emplace_node(ATTRIBUTE(USER_IDENTIFIER)); + + userid_node.emplace_node(ATTRIBUTE(ENABLED)); + + endpoint_node.emplace_node(ATTRIBUTE(ENABLE_ALL)); + + userid_node.emplace_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + + if (supporting_node_version >= 2) { + endpoint_node.emplace_node(ATTRIBUTE(HOUR_TZO)); + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// Public interface functions +/////////////////////////////////////////////////////////////////////////////// +sl_status_t zwave_command_class_schedule_entry_lock_init() +{ + // Attribute store callbacks + attribute_store_register_callback_by_type( + zwave_command_class_schedule_entry_lock_on_version_attribute_update, + ATTRIBUTE(VERSION)); + + // Attribute resolver rules + // attribute_resolver_register_rule(ATTRIBUTE(SLOTS_WEEK_DAY), NULL, &schedule_entry_lock_supported_get); + // attribute_resolver_register_rule(ATTRIBUTE(HOUR_TZO), &schedule_entry_lock_time_offset_set, &schedule_entry_lock_time_offset_get); + // attribute_resolver_register_rule(ATTRIBUTE(ENABLED), &schedule_entry_lock_enable_set, NULL); + // attribute_resolver_register_rule(ATTRIBUTE(ENABLE_ALL), &schedule_entry_lock_enable_set, NULL); + + // The support side of things: Register our handler to the Z-Wave CC framework: + zwave_command_handler_t handler = {}; + handler.support_handler = NULL; + handler.control_handler = &zwave_command_class_schedule_entry_lock_control_handler; + // Not supported, so this does not really matter + handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NETWORK_SCHEME; + handler.manual_security_validation = false; + handler.command_class = COMMAND_CLASS_SCHEDULE_ENTRY_LOCK; + handler.version = SCHEDULE_ENTRY_LOCK_VERSION_V3; + handler.command_class_name = "schedule_entry_lock"; + handler.comments = ""; + + zwave_command_handler_register_handler(handler); + + return SL_STATUS_OK; +} diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.h new file mode 100644 index 000000000..0fcc09428 --- /dev/null +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * # 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_schedule_entry_lock + * @brief TODO: Write brief for zwave_command_class_schedule_entry_lock + * + * TODO: Write component description for zwave_command_class_schedule_entry_lock + * + * @{ + */ + +#ifndef ZWAVE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_H +#define ZWAVE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_H + +#include "sl_status.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief This function initialize the schedule Entry Lock Command Class handler + * + * @return SL_STATUS_OK on success, any other error code for an error. + */ +sl_status_t zwave_command_class_schedule_entry_lock_init(); + +#ifdef __cplusplus +} +#endif + +#endif //ZWAVE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_H +/** @} end zwave_command_class_schedule_entry_lock */ 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 a20c668f3..ec3db086d 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 @@ -59,6 +59,7 @@ #include "zwave_command_class_indicator_control.h" #include "zwave_command_class_manufacturer_specific_control.h" #include "zwave_command_class_humidity_control_mode.h" +#include "zwave_command_class_schedule_entry_lock.h" #include "zwave_command_class_protocol.h" // Generic includes @@ -114,6 +115,7 @@ sl_status_t zwave_command_classes_init() status |= zwave_command_class_scene_controller_configuration_control_init(); status |= zwave_command_class_security_0_init(); status |= zwave_command_class_security_2_init(); + status |= zwave_command_class_schedule_entry_lock_init(); status |= zwave_command_class_sound_switch_init(); status |= zwave_command_class_supervision_init(); status |= zwave_command_class_switch_color_init(); From 0b89159fe1340eb0eb41afdb98a3ec835c965637 Mon Sep 17 00:00:00 2001 From: Thirupathi S Date: Tue, 17 Sep 2024 13:13:38 +0000 Subject: [PATCH 08/12] UIC-3438: dot dot mapper setup for schedule entry lock CC Merge in UIC/uic from feature/UIC-3438-dotdot-mapper-Setup-Schedule-Entry-Lock-CC to feature/UIC-3271-Schedule-Entry-Lock-CC --- ...schedulelockentry_to_schedulelockentry.uam | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 applications/zpc/components/dotdot_mapper/rules/Unifyschedulelockentry_to_schedulelockentry.uam diff --git a/applications/zpc/components/dotdot_mapper/rules/Unifyschedulelockentry_to_schedulelockentry.uam b/applications/zpc/components/dotdot_mapper/rules/Unifyschedulelockentry_to_schedulelockentry.uam new file mode 100644 index 000000000..22932a0a5 --- /dev/null +++ b/applications/zpc/components/dotdot_mapper/rules/Unifyschedulelockentry_to_schedulelockentry.uam @@ -0,0 +1,125 @@ +// Schedule Entry Lock All Command Class +def zwSLOTS_WEEK_DAY 0x4E05 +def zwSLOTS_YEAR_DAY 0x4E06 +def zwSIGN_TZO 0x4E1B +def zwHOUR_TZO 0x4E1C +def zwMINUTE_TZO 0x4E1D +def zwDST_OFFSET_SIGN 0x4E1E +def zwDST_OFFSET_MINUTE 0x4E1F +def zwNUMBER_OF_SLOTS_DAILY_REPEATING 0x4E20 + +// Unify Schedule Entry Lock Cluster +def zbSLOTS_WEEK_DAY 0xFD210001 +def zbSLOTS_YEAR_DAY 0xFD210002 +def zbSIGN_TZO 0xFD210003 +def zbHOUR_TZO 0xFD210004 +def zbMINUTE_TZO 0xFD210005 +def zbDST_OFFSET_SIGN 0xFD210006 +def zbDST_OFFSET_MINUTE 0xFD210007 +def zbNUMBER_OF_SLOTS_DAILY_REPEATING 0xFD210008 + +def zwave_no_schedule_entry_lock (e'zwSLOTS_WEEK_DAY == 0) +def zwave_no_schedule_entry_lock_v2 (e'zwHOUR_TZO == 0) + +scope 0 { + + // Linking attributes zwave -> zigbee + r'zwSLOTS_WEEK_DAY = + if (zwave_no_schedule_entry_lock) undefined + r'zbSLOTS_WEEK_DAY + d'zwSLOTS_WEEK_DAY = + if (zwave_no_schedule_entry_lock) undefined + d'zbSLOTS_WEEK_DAY + r'zwSLOTS_YEAR_DAY = + if (zwave_no_schedule_entry_lock) undefined + r'zbSLOTS_YEAR_DAY + d'zwSLOTS_YEAR_DAY = + if (zwave_no_schedule_entry_lock) undefined + d'zbSLOTS_YEAR_DAY + r'zwSIGN_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zbSIGN_TZO + d'zwSIGN_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zbSIGN_TZO + r'zwHOUR_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zbHOUR_TZO + d'zwHOUR_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zbHOUR_TZO + r'zwMINUTE_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zbMINUTE_TZO + d'zwMINUTE_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zbMINUTE_TZO + r'zwDST_OFFSET_SIGN = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zbDST_OFFSET_SIGN + d'zwDST_OFFSET_SIGN = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zbDST_OFFSET_SIGN + r'zwDST_OFFSET_MINUTE = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zbDST_OFFSET_MINUTE + d'zwDST_OFFSET_MINUTE = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zbDST_OFFSET_MINUTE + r'zwNUMBER_OF_SLOTS_DAILY_REPEATING = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zbNUMBER_OF_SLOTS_DAILY_REPEATING + d'zwNUMBER_OF_SLOTS_DAILY_REPEATING = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zbNUMBER_OF_SLOTS_DAILY_REPEATING + + // Linking attributes zigbee -> zwave + r'zbSLOTS_WEEK_DAY = + if (zwave_no_schedule_entry_lock) undefined + r'zwSLOTS_WEEK_DAY + d'zbSLOTS_WEEK_DAY = + if (zwave_no_schedule_entry_lock) undefined + d'zwSLOTS_WEEK_DAY + r'zbSLOTS_YEAR_DAY = + if (zwave_no_schedule_entry_lock) undefined + r'zwSLOTS_YEAR_DAY + d'zbSLOTS_YEAR_DAY = + if (zwave_no_schedule_entry_lock) undefined + d'zwSLOTS_YEAR_DAY + r'zbSIGN_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zwSIGN_TZO + d'zbSIGN_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zwSIGN_TZO + r'zbHOUR_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zwHOUR_TZO + d'zbHOUR_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zwHOUR_TZO + r'zbMINUTE_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zwMINUTE_TZO + d'zbMINUTE_TZO = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zwMINUTE_TZO + r'zbDST_OFFSET_SIGN = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zwDST_OFFSET_SIGN + d'zbDST_OFFSET_SIGN = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zwDST_OFFSET_SIGN + r'zbDST_OFFSET_MINUTE = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zwDST_OFFSET_MINUTE + d'zbDST_OFFSET_MINUTE = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zwDST_OFFSET_MINUTE + r'zbNUMBER_OF_SLOTS_DAILY_REPEATING = + if (zwave_no_schedule_entry_lock_v2) undefined + r'zwNUMBER_OF_SLOTS_DAILY_REPEATING + d'zbNUMBER_OF_SLOTS_DAILY_REPEATING = + if (zwave_no_schedule_entry_lock_v2) undefined + d'zwNUMBER_OF_SLOTS_DAILY_REPEATING +} From a67bef4dca44a69c2389fa17649f250f99ddc714 Mon Sep 17 00:00:00 2001 From: Thirupathi S Date: Wed, 18 Sep 2024 11:03:50 +0000 Subject: [PATCH 09/12] UIC-3436: Attribute resolver rules ScheduleEntryLock CC Merge in UIC/uic from feature/UIC-3436-Attribute-resolver-rules-ScheduleEntryLock-CC to feature/UIC-3271-Schedule-Entry-Lock-CC --- .../zpc_attribute_store_type_registration.cpp | 40 +- ...wave_command_class_schedule_entry_lock.cpp | 431 ++++++++++++++++-- 2 files changed, 404 insertions(+), 67 deletions(-) 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 121fbb924..dc191cf3d 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 @@ -521,27 +521,27 @@ static const std::vector attribute_schema = { {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, "Schedule Entry Lock User Identifier", ATTRIBUTE_ENDPOINT_ID, U16_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_ENABLED, "Schedule Entry Lock Enable", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_ENABLE_ALL, "Schedule Entry Lock All Set Enable", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY, "Number Of Slots Week Day", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY, "Number Of Slots Year Day", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SET_ACTION, "Week Day Schedule Set Action", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY, "Number Of Slots Week Day", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY, "Number Of Slots Year Day", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, "Week Day Schedule Slot ID", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_DAY_OF_WEEK, "Week Day Schedule Day Of Week", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_START_HOUR, "Week Day Schedule Start Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_START_MINUTE, "Week Day Schedule Start Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_STOP_HOUR, "Week Day Schedule Stop Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_STOP_MINUTE, "Week Day Schedule Stop Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SET_ACTION, "Year Day Schedule Set Action", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, "Year Day Schedule Slot ID", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_YEAR, "Year Day Schedule Start Year", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_MONTH, "Year Day Schedule Start Month", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_DAY, "Year Day Schedule Start Day", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_HOUR, "Year Day Schedule Start Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_MINUTE, "Year Day Schedule Start Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_YEAR, "Year Day Schedule Stop Year", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_MONTH, "Year Day Schedule Stop Month", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_DAY, "Year Day Schedule Stop Day", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_HOUR, "Year Day Schedule Stop Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_MINUTE, "Year Day Schedule Stop Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SET_ACTION, "Week Day Schedule Set Action", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_DAY_OF_WEEK, "Week Day Schedule Day Of Week", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_START_HOUR, "Week Day Schedule Start Hour", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_START_MINUTE, "Week Day Schedule Start Minute", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_STOP_HOUR, "Week Day Schedule Stop Hour", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_STOP_MINUTE, "Week Day Schedule Stop Minute", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, "Year Day Schedule Slot ID", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SET_ACTION, "Year Day Schedule Set Action", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_YEAR, "Year Day Schedule Start Year", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_MONTH, "Year Day Schedule Start Month", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_DAY, "Year Day Schedule Start Day", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_HOUR, "Year Day Schedule Start Hour", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_START_MINUTE, "Year Day Schedule Start Minute", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_YEAR, "Year Day Schedule Stop Year", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_MONTH, "Year Day Schedule Stop Month", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_DAY, "Year Day Schedule Stop Day", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_HOUR, "Year Day Schedule Stop Hour", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_STOP_MINUTE, "Year Day Schedule Stop Minute", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_YEAR_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SIGN_TZO, "Schedule Entry Lock Sign TZO", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_HOUR_TZO, "Schedule Entry Lock Hour TZO", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp index 0320e0d82..23dba81df 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp @@ -45,23 +45,26 @@ // Log tag constexpr char LOG_TAG[] = "zwave_command_class_schedule_entry_lock"; - // Cpp helpers namespace { -const zwave_frame_generator frame_generator(COMMAND_CLASS_SCHEDULE_ENTRY_LOCK); //NOSONAR - false positive since it is warped in a namespace +zwave_frame_generator frame_generator( + COMMAND_CLASS_SCHEDULE_ENTRY_LOCK); //NOSONAR - false positive since it is warped in a namespace } /////////////////////////////////////////////////////////////////////////////// // Helper functions /////////////////////////////////////////////////////////////////////////////// -zwave_cc_version_t get_current_schedule_entry_lock_version(attribute_store_node_t node) +zwave_cc_version_t + get_current_schedule_entry_lock_version(attribute_store_node_t node) { - zwave_cc_version_t version - = zwave_command_class_get_version_from_node(node, COMMAND_CLASS_SCHEDULE_ENTRY_LOCK); + zwave_cc_version_t version = zwave_command_class_get_version_from_node( + node, + COMMAND_CLASS_SCHEDULE_ENTRY_LOCK); if (version == 0) { - sl_log_error(LOG_TAG, "schedule_entry_lock Command Class Version not found"); + sl_log_error(LOG_TAG, + "schedule_entry_lock Command Class Version not found"); } return version; @@ -69,39 +72,344 @@ zwave_cc_version_t get_current_schedule_entry_lock_version(attribute_store_node_ /////////////////////////////////////////////////////////////////////////////// // Resolution functions /////////////////////////////////////////////////////////////////////////////// -//static sl_status_t zwave_command_class_schedule_entry_lock_get( -// attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) -//{ -// return frame_generator.generate_no_args_frame(schedule_entry_lock_GET, -// frame, -// frame_length); -//} +static sl_status_t zwave_command_class_schedule_entry_lock_get( + attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +{ + if (attribute_store_get_node_type(node) == ATTRIBUTE(SLOTS_WEEK_DAY)) { + return frame_generator.generate_no_args_frame( + SCHEDULE_ENTRY_TYPE_SUPPORTED_GET, + frame, + frame_length); + } -// static sl_status_t zwave_command_class_schedule_entry_lock_set( -// attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) -// { -// try { -// attribute_store::attribute value_node(node); -// auto current_version = get_current_schedule_entry_lock_version(node); -// -// // Compute expected size for set frame -// const uint8_t expected_frame_size = 12; -// -// // Creating the frame -// frame_generator.initialize_frame(schedule_entry_lock_SET, -// frame, -// expected_frame_size); -// frame_generator.add_value(value_node, DESIRED_OR_REPORTED_ATTRIBUTE); -// frame_generator.validate_frame(frame_length); -// } catch (const std::exception &e) { -// sl_log_error(LOG_TAG, -// "Error while generating schedule_entry_lock Set frame : %s", -// e.what()); -// return SL_STATUS_FAIL; -// } -// -// return SL_STATUS_OK; -//} + return SL_STATUS_INVALID_TYPE; +} + +static sl_status_t zwave_command_class_schedule_entry_lock_time_offset_get( + attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +{ + if (attribute_store_get_node_type(node) == ATTRIBUTE(HOUR_TZO)) { + return frame_generator.generate_no_args_frame( + SCHEDULE_ENTRY_LOCK_TIME_OFFSET_GET_V2, + frame, + frame_length); + } + return SL_STATUS_INVALID_TYPE; +} + +static sl_status_t zwave_command_class_schedule_entry_lock_week_day_get( + attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +{ + if (attribute_store_get_node_type(node) + == ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)) { + try { + // Retrieve the node attributes + attribute_store::attribute weekday_schedule_slotid_node(node); + auto userid_node + = weekday_schedule_slotid_node.first_parent(ATTRIBUTE(USER_IDENTIFIER)); + + // Compute expected size for the set frame + const uint8_t expected_frame_size = 4; + + // Initialize the frame for Schedule Entry Lock Time Offset Set command + frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_WEEK_DAY_GET, + frame, + expected_frame_size); + frame_generator.add_value(userid_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(weekday_schedule_slotid_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + // Validate the constructed frame and set the frame length + frame_generator.validate_frame(frame_length); + } catch (const std::exception &e) { + // Log any error that occurs during the frame generation process + sl_log_error(LOG_TAG, + "Error while generating Schedule Entry Lock Set frame: %s", + e.what()); + return SL_STATUS_FAIL; + } + } + return SL_STATUS_OK; +} + +static sl_status_t zwave_command_class_schedule_entry_lock_year_day_get( + attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +{ + if (attribute_store_get_node_type(node) + == ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)) { + try { + // Retrieve the node attributes + attribute_store::attribute yearday_schedule_slotid_node(node); + auto userid_node + = yearday_schedule_slotid_node.first_parent(ATTRIBUTE(USER_IDENTIFIER)); + + // Compute expected size for the set frame + const uint8_t expected_frame_size = 4; + + // Initialize the frame for Schedule Entry Lock Time Offset Set command + frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_YEAR_DAY_GET, + frame, + expected_frame_size); + frame_generator.add_value(userid_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_slotid_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + // Validate the constructed frame and set the frame length + frame_generator.validate_frame(frame_length); + } catch (const std::exception &e) { + // Log any error that occurs during the frame generation process + sl_log_error(LOG_TAG, + "Error while generating Schedule Entry Lock Set frame: %s", + e.what()); + return SL_STATUS_FAIL; + } + } + return SL_STATUS_OK; +} + +static sl_status_t zwave_command_class_schedule_entry_lock_time_offset_set( + attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +{ + try { + // Retrieve the node attributes + attribute_store::attribute hour_tzo_node(node); + auto endpoint_node = hour_tzo_node.parent(); + auto minute_tzo_node = endpoint_node.child_by_type(ATTRIBUTE(MINUTE_TZO)); + auto sign_hour_tzo_node = endpoint_node.child_by_type(ATTRIBUTE(HOUR_TZO)); + auto minute_offset_dst_node + = endpoint_node.child_by_type(ATTRIBUTE(DST_OFFSET_SIGN)); + auto sign_offset_dst_node + = endpoint_node.child_by_type(ATTRIBUTE(DST_OFFSET_MINUTE)); + + // Compute expected size for the set frame + const uint8_t expected_frame_size = 5; + + // Initialize the frame for Schedule Entry Lock Time Offset Set command + frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_TIME_OFFSET_SET_V2, + frame, + expected_frame_size); + + // Create a vector for the values to be shifted into the frame + frame_generator.add_shifted_values( + {{.left_shift = 7, // Sign TZO (1 bit) + .node = sign_hour_tzo_node, + .node_value_state = DESIRED_OR_REPORTED_ATTRIBUTE}, + {.left_shift = 0, // Hour TZO (7 bits) + .node = hour_tzo_node, + .node_value_state = DESIRED_OR_REPORTED_ATTRIBUTE}}); + frame_generator.add_value(minute_tzo_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_shifted_values( + {{.left_shift = 7, // Sign Offset DST (1 bit) + .node = sign_offset_dst_node, + .node_value_state = DESIRED_OR_REPORTED_ATTRIBUTE}, + {.left_shift = 0, // Minute Offset DST (7 bits) + .node = minute_offset_dst_node, + .node_value_state = DESIRED_OR_REPORTED_ATTRIBUTE}}); + + // Validate the constructed frame and set the frame length + frame_generator.validate_frame(frame_length); + + } catch (const std::exception &e) { + // Log any error that occurs during the frame generation process + sl_log_error(LOG_TAG, + "Error while generating Schedule Entry Lock Set frame: %s", + e.what()); + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +static sl_status_t zwave_command_class_schedule_entry_lock_enable_set( + attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +{ + try { + attribute_store::attribute enable_node(node); + auto userid_node = enable_node.parent(); + + // Compute expected size for set frame + const uint8_t expected_frame_size = 4; + + // Creating the frame + frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_ENABLE_SET, + frame, + expected_frame_size); + frame_generator.add_value(userid_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(enable_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.validate_frame(frame_length); + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +static sl_status_t zwave_command_class_schedule_entry_lock_enable_all_set( + attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +{ + try { + attribute_store::attribute value_node(node); + + // Compute expected size for set frame + const uint8_t expected_frame_size = 3; + + // Creating the frame + frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_ENABLE_ALL_SET, + frame, + expected_frame_size); + frame_generator.add_value(value_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.validate_frame(frame_length); + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +static sl_status_t zwave_command_class_schedule_entry_lock_week_day_set( + attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +{ + try { + attribute_store::attribute weekday_schedule_set_action_node(node); + auto userid_node = weekday_schedule_set_action_node.first_parent( + ATTRIBUTE(USER_IDENTIFIER)); + auto weekday_schedule_slotid_node + = weekday_schedule_set_action_node.parent(); + auto weekday_schedule_dayofweek_node + = weekday_schedule_slotid_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_DAY_OF_WEEK)); + auto weekday_schedule_starthour_node + = weekday_schedule_slotid_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_START_HOUR)); + auto weekday_schedule_startminute_node + = weekday_schedule_slotid_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_START_MINUTE)); + auto weekday_schedule_stophour_node + = weekday_schedule_slotid_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_HOUR)); + auto weekday_schedule_stopminute_node + = weekday_schedule_slotid_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_MINUTE)); + + // Compute expected size for set frame + const uint8_t expected_frame_size = 10; + + // Creating the frame + frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_WEEK_DAY_SET, + frame, + expected_frame_size); + frame_generator.add_value(weekday_schedule_set_action_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(userid_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(weekday_schedule_slotid_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(weekday_schedule_dayofweek_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(weekday_schedule_starthour_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(weekday_schedule_startminute_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(weekday_schedule_stophour_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(weekday_schedule_stopminute_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.validate_frame(frame_length); + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +static sl_status_t zwave_command_class_schedule_entry_lock_year_day_set( + attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +{ + try { + attribute_store::attribute yearday_schedule_set_action_node(node); + auto userid_node = yearday_schedule_set_action_node.first_parent( + ATTRIBUTE(USER_IDENTIFIER)); + auto yearday_schedule_slotid_node + = yearday_schedule_set_action_node.parent(); + auto yearday_schedule_startyear_node + = yearday_schedule_slotid_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR)); + auto yearday_schedule_startmonth_node + = yearday_schedule_slotid_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH)); + auto yearday_schedule_startday_node + = yearday_schedule_slotid_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY)); + auto yearday_schedule_starthour_node + = yearday_schedule_slotid_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR)); + auto yearday_schedule_startminute_node + = yearday_schedule_slotid_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE)); + auto yearday_schedule_stopyear_node + = yearday_schedule_slotid_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR)); + auto yearday_schedule_stopmonth_node + = yearday_schedule_slotid_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH)); + auto yearday_schedule_stopday_node + = yearday_schedule_slotid_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY)); + auto yearday_schedule_stophour_node + = yearday_schedule_slotid_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR)); + auto yearday_schedule_stopminute_node + = yearday_schedule_slotid_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE)); + + // Compute expected size for set frame + const uint8_t expected_frame_size = 15; + + // Creating the frame + frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_YEAR_DAY_SET, + frame, + expected_frame_size); + frame_generator.add_value(yearday_schedule_set_action_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(userid_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_slotid_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_startyear_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_startmonth_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_startday_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_starthour_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_startminute_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_stopyear_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_stopmonth_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_stopday_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_stophour_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_stopminute_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.validate_frame(frame_length); + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} /////////////////////////////////////////////////////////////////////////////// // Frame parsing functions @@ -188,10 +496,11 @@ static void zwave_command_class_schedule_entry_lock_on_version_attribute_update( // Now we know we have a schedule_entry_lock supporting endpoint. attribute_store::attribute endpoint_node - = version_node.first_parent(ATTRIBUTE_ENDPOINT_ID); + = version_node.first_parent(ATTRIBUTE_ENDPOINT_ID); // Create the schedule_entry_lock attributes - attribute_store::attribute userid_node = endpoint_node.emplace_node(ATTRIBUTE(USER_IDENTIFIER)); + attribute_store::attribute userid_node + = endpoint_node.emplace_node(ATTRIBUTE(USER_IDENTIFIER)); userid_node.emplace_node(ATTRIBUTE(ENABLED)); @@ -202,7 +511,6 @@ static void zwave_command_class_schedule_entry_lock_on_version_attribute_update( if (supporting_node_version >= 2) { endpoint_node.emplace_node(ATTRIBUTE(HOUR_TZO)); } - } /////////////////////////////////////////////////////////////////////////////// @@ -216,17 +524,46 @@ sl_status_t zwave_command_class_schedule_entry_lock_init() ATTRIBUTE(VERSION)); // Attribute resolver rules - // attribute_resolver_register_rule(ATTRIBUTE(SLOTS_WEEK_DAY), NULL, &schedule_entry_lock_supported_get); - // attribute_resolver_register_rule(ATTRIBUTE(HOUR_TZO), &schedule_entry_lock_time_offset_set, &schedule_entry_lock_time_offset_get); - // attribute_resolver_register_rule(ATTRIBUTE(ENABLED), &schedule_entry_lock_enable_set, NULL); - // attribute_resolver_register_rule(ATTRIBUTE(ENABLE_ALL), &schedule_entry_lock_enable_set, NULL); + attribute_resolver_register_rule( + ATTRIBUTE(SLOTS_WEEK_DAY), + NULL, + &zwave_command_class_schedule_entry_lock_get); + attribute_resolver_register_rule( + ATTRIBUTE(HOUR_TZO), + &zwave_command_class_schedule_entry_lock_time_offset_set, + &zwave_command_class_schedule_entry_lock_time_offset_get); + attribute_resolver_register_rule( + ATTRIBUTE(ENABLED), + &zwave_command_class_schedule_entry_lock_enable_set, + NULL); + attribute_resolver_register_rule( + ATTRIBUTE(ENABLE_ALL), + &zwave_command_class_schedule_entry_lock_enable_all_set, + NULL); + attribute_resolver_register_rule( + ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION), + &zwave_command_class_schedule_entry_lock_week_day_set, + NULL); + attribute_resolver_register_rule( + ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION), + &zwave_command_class_schedule_entry_lock_year_day_set, + NULL); + attribute_resolver_register_rule( + ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID), + NULL, + &zwave_command_class_schedule_entry_lock_week_day_get); + attribute_resolver_register_rule( + ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID), + NULL, + &zwave_command_class_schedule_entry_lock_year_day_get); // The support side of things: Register our handler to the Z-Wave CC framework: zwave_command_handler_t handler = {}; handler.support_handler = NULL; - handler.control_handler = &zwave_command_class_schedule_entry_lock_control_handler; + handler.control_handler + = &zwave_command_class_schedule_entry_lock_control_handler; // Not supported, so this does not really matter - handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NETWORK_SCHEME; + handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NETWORK_SCHEME; handler.manual_security_validation = false; handler.command_class = COMMAND_CLASS_SCHEDULE_ENTRY_LOCK; handler.version = SCHEDULE_ENTRY_LOCK_VERSION_V3; From 2243fc1c15dc7518cc43956d391029dbc9ed751a Mon Sep 17 00:00:00 2001 From: Thirupathi S Date: Wed, 25 Sep 2024 13:15:55 +0000 Subject: [PATCH 10/12] UIC-3494:dotdot command handlers in ZPC ScheduleEntryLock CC Merge in UIC/uic from feature/UIC-3494-dotdot-command-handlers-in-ZPC-ScheduleEntryLock-CC to feature/UIC-3271-Schedule-Entry-Lock-CC --- .../zcl_cluster_servers/CMakeLists.txt | 1 + .../src/schedule_entry_lock_server.cpp | 478 ++++++++++++++++++ .../src/schedule_entry_lock_server.h | 35 ++ .../src/zcl_cluster_servers.cpp | 2 + .../zpc_attribute_store_type_registration.cpp | 2 +- .../zwave_command_classes/CMakeLists.txt | 1 + ...wave_command_class_schedule_entry_lock.cpp | 187 +++++-- 7 files changed, 665 insertions(+), 41 deletions(-) create mode 100644 applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp create mode 100644 applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.h diff --git a/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt b/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt index 41a947535..3ae54aba8 100644 --- a/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt +++ b/applications/zpc/components/zcl_cluster_servers/CMakeLists.txt @@ -11,6 +11,7 @@ add_library( src/humidity_control_cluster_server.c src/user_code_cluster_server.cpp src/fan_control_cluster_server.c + src/schedule_entry_lock_server.cpp src/zcl_binding_cluster_server.cpp src/zcl_cluster_servers.cpp src/zcl_cluster_servers_helpers.cpp diff --git a/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp b/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp new file mode 100644 index 000000000..b58e54917 --- /dev/null +++ b/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp @@ -0,0 +1,478 @@ +/****************************************************************************** + * # 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 "zwave_command_class_schedule_entry_lock.h" +#include "zwave_command_classes_utils.h" +#include "schedule_entry_lock_server.h" + +// Generic includes +#include +#include + +// Includes from other ZPC Components +#include "zwave_command_class_indices.h" +#include "zwave_command_handler.h" +#include "zpc_attribute_store_network_helper.h" +#include "attribute_store_defined_attribute_types.h" +#include "ZW_classcmd.h" + +// Includes from other Unify Components +#include "dotdot_mqtt.h" +#include "dotdot_mqtt_generated_commands.h" +#include "attribute_store_helper.h" +#include "attribute_resolver.h" +#include "attribute_timeouts.h" +#include "sl_log.h" + +// Cpp include +#include "attribute.hpp" +#include "zwave_frame_generator.hpp" +#include "zwave_frame_parser.hpp" + +// Attribute macro, shortening those long defines for attribute types: +#define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_##type + +// Log tag +constexpr char LOG_TAG[] = "zwave_command_class_schedule_entry_lock"; + +/////////////////////////////////////////////////////////////////////////////// +// helper functions +////////////////////////////////////////////////////////////////////////////// +attribute_store::attribute get_user_id_node(const dotdot_unid_t &unid, + dotdot_endpoint_id_t endpoint, + uint8_t user_identifier) +{ + attribute_store::attribute base_id_node + = attribute_store_network_helper_get_node_id_node(unid); + attribute_store::attribute endpoint_node + = base_id_node.child_by_type_and_value(ATTRIBUTE_ENDPOINT_ID, endpoint); + auto user_id_node + = endpoint_node.child_by_type_and_value(ATTRIBUTE(USER_IDENTIFIER), + user_identifier); + + return user_id_node; +} + +sl_status_t + zwave_command_class_check_ep_support(const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint) +{ + attribute_store::attribute base_id_node + = attribute_store_network_helper_get_node_id_node(unid); + attribute_store::attribute endpoint_node + = base_id_node.child_by_type_and_value<>(ATTRIBUTE_ENDPOINT_ID, endpoint); + + // If both attribute are not defined, we definitely doesn't support this Command Class + if (!endpoint_node.child_by_type(ATTRIBUTE(SLOTS_WEEK_DAY)).is_valid() && + !endpoint_node.child_by_type(ATTRIBUTE(HOUR_TZO)).is_valid()) { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// Helper function to set the desired values based on the attribute map. +static sl_status_t helper_set_desired_values( + attribute_store::attribute base_node, + const std::map &attribute_map) +{ + try { + for (const auto &[attribute, value]: attribute_map) { + auto child_node = base_node.emplace_node(attribute); + child_node.set_desired(value); + } + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// commands handling callbacks +////////////////////////////////////////////////////////////////////////////// + +static sl_status_t zwave_command_class_schedule_entry_lock_enable_set_callback( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, + uint8_t user_identifier, + uint8_t enabled) +{ + if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { + return zwave_command_class_check_ep_support(unid, endpoint); + } + try { + auto user_id_node = get_user_id_node(unid, endpoint, user_identifier); + user_id_node.child_by_type(ATTRIBUTE(ENABLED)) + .set_desired(enabled); + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} + +static sl_status_t + zwave_command_class_schedule_entry_lock_enable_all_set_callback( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, + uint8_t enabled) +{ + if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { + return zwave_command_class_check_ep_support(unid, endpoint); + } + try { + attribute_store::attribute base_id_node + = attribute_store_network_helper_get_node_id_node(unid); + attribute_store::attribute endpoint_node + = base_id_node.child_by_type_and_value(ATTRIBUTE_ENDPOINT_ID, endpoint); + endpoint_node.child_by_type(ATTRIBUTE(ENABLED)) + .set_desired<>(enabled); + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} + +static sl_status_t + zwave_command_class_schedule_entry_lock_week_day_set_callback( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, + uint8_t set_action, + uint8_t user_identifier, + uint8_t schedule_slotid, + uint8_t day_of_week, + uint8_t start_hour, + uint8_t start_minute, + uint8_t stop_hour, + uint8_t stop_minute) +{ + if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { + return zwave_command_class_check_ep_support(unid, endpoint); + } + try { + auto user_id_node = get_user_id_node(unid, endpoint, user_identifier); + auto slot_id_node = user_id_node.child_by_type_and_value( + ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID), + schedule_slotid); + + const std::map attribute_map + = {{ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION), set_action}, + {ATTRIBUTE(WEEK_DAY_SCHEDULE_DAY_OF_WEEK), day_of_week}, + {ATTRIBUTE(WEEK_DAY_SCHEDULE_START_HOUR), start_hour}, + {ATTRIBUTE(WEEK_DAY_SCHEDULE_START_MINUTE), start_minute}, + {ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_HOUR), stop_hour}, + {ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_MINUTE), stop_minute}}; + return helper_set_desired_values(slot_id_node, attribute_map); + + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame : %s", + e.what()); + return SL_STATUS_FAIL; + } +} + +static sl_status_t + zwave_command_class_schedule_entry_lock_week_day_get_callback( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, + uint8_t user_identifier, + uint8_t schedule_slotid) +{ + if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { + return zwave_command_class_check_ep_support(unid, endpoint); + } + + try { + auto user_id_node = get_user_id_node(unid, endpoint, user_identifier); + auto slot_id_node = user_id_node.child_by_type_and_value(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID), + schedule_slotid); + auto set_action_node = slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION)); + set_action_node.clear_reported(); + + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while retrieving schedule_entry_lock: %s", + e.what()); + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} + +static sl_status_t + zwave_command_class_schedule_entry_lock_year_day_set_callback( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, + uint8_t set_action, + uint8_t user_identifier, + uint8_t schedule_slotid, + uint8_t start_year, + uint8_t start_day, + uint8_t start_hour, + uint8_t start_minute, + uint8_t stop_year, + uint8_t stop_day, + uint8_t stop_hour, + uint8_t stop_minute) +{ + if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { + return zwave_command_class_check_ep_support(unid, endpoint); + } + + try { + auto user_id_node = get_user_id_node(unid, endpoint, user_identifier); + auto slot_id_node = user_id_node.child_by_type_and_value( + ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID), + schedule_slotid); + + const std::map attribute_map + = {{ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION), set_action}, + {ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR), start_year}, + {ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY), start_day}, + {ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR), start_hour}, + {ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE), start_minute}, + {ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR), stop_year}, + {ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY), stop_day}, + {ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR), stop_hour}, + {ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE), stop_minute}}; + + return helper_set_desired_values(slot_id_node, attribute_map); + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame: %s", + e.what()); + return SL_STATUS_FAIL; + } +} + +static sl_status_t + zwave_command_class_schedule_entry_lock_year_day_get_callback( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, + uint8_t user_identifier, + uint8_t schedule_slotid) +{ + if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { + return zwave_command_class_check_ep_support(unid, endpoint); + } + try { + auto user_id_node = get_user_id_node(unid, endpoint, user_identifier); + auto slot_id_node = user_id_node.child_by_type_and_value(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID), + schedule_slotid); + auto set_action_node = slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION)); + set_action_node.clear_reported(); + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} + +static sl_status_t + zwave_command_class_schedule_entry_lock_daily_repeating_set_callback( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, + uint8_t set_action, + uint8_t user_identifier, + uint8_t schedule_slotid, + uint8_t week_day_bitmask, + uint8_t start_hour, + uint8_t start_minute, + uint8_t duration_hour, + uint8_t duration_minute) +{ + try { + auto user_id_node = get_user_id_node(unid, endpoint, user_identifier); + auto slot_id_node = user_id_node.child_by_type_and_value( + ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID), + schedule_slotid); + + const std::map attribute_map + = {{ATTRIBUTE(DAILY_REPEATING_SET_ACTION), set_action}, + {ATTRIBUTE(DAILY_REPEATING_WEEK_DAY), week_day_bitmask}, + {ATTRIBUTE(DAILY_REPEATING_START_HOUR), start_hour}, + {ATTRIBUTE(DAILY_REPEATING_START_MINUTE), start_minute}, + {ATTRIBUTE(DAILY_REPEATING_DURATION_HOUR), duration_hour}, + {ATTRIBUTE(DAILY_REPEATING_DURATION_MINUTE), duration_minute}}; + + return helper_set_desired_values(slot_id_node, attribute_map); + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame: %s", + e.what()); + return SL_STATUS_FAIL; + } +} + +static sl_status_t + zwave_command_class_schedule_entry_lock_daily_repeating_get_callback( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, + uint8_t user_identifier, + uint8_t schedule_slotid) +{ + if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { + return zwave_command_class_check_ep_support(unid, endpoint); + } + + try { + attribute_store::attribute base_id_node + = attribute_store_network_helper_get_node_id_node(unid); + attribute_store::attribute endpoint_node + = base_id_node.child_by_type_and_value(ATTRIBUTE_ENDPOINT_ID, endpoint); + auto user_id_node + = endpoint_node.child_by_type_and_value(ATTRIBUTE(USER_IDENTIFIER), + user_identifier); + auto slot_id_node = user_id_node.child_by_type_and_value(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID), + schedule_slotid); + auto set_action_node = slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_SET_ACTION)); + set_action_node.clear_reported(); + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} + +sl_status_t zwave_command_class_schedule_entry_lock_write_attributes_callback( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, + uic_mqtt_dotdot_unify_schedule_entry_lock_state_t lock_state, + uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t updated_lock_state) +{ + if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { + return zwave_command_class_check_ep_support(unid, endpoint); + } + + std::map attributes_to_update; + + if (updated_lock_state.slots_week_day) { + attributes_to_update + [DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY] + = lock_state.slots_week_day; + } + + if (updated_lock_state.slots_year_day) { + attributes_to_update + [DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY] + = lock_state.slots_year_day; + } + + if (updated_lock_state.signtzo) { + attributes_to_update[DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO] + = lock_state.signtzo; + } + + if (updated_lock_state.hourtzo) { + attributes_to_update[DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO] + = lock_state.hourtzo; + } + + if (updated_lock_state.minutetzo) { + attributes_to_update + [DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO] + = lock_state.minutetzo; + } + + if (updated_lock_state.dst_offset_sign) { + attributes_to_update + [DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN] + = lock_state.dst_offset_sign; + } + + if (updated_lock_state.dst_offset_minute) { + attributes_to_update + [DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE] + = lock_state.dst_offset_minute; + } + + if (updated_lock_state.number_of_slots_daily_repeating) { + attributes_to_update + [DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING] + = lock_state.number_of_slots_daily_repeating; + } + + attribute_store::attribute base_id_node + = attribute_store_network_helper_get_node_id_node(unid); + attribute_store::attribute endpoint_node + = base_id_node.child_by_type_and_value(ATTRIBUTE_ENDPOINT_ID, endpoint); + + for (const auto &[attribute_id, value]: attributes_to_update) { + attribute_store::attribute attribute_node + = endpoint_node.emplace_node(attribute_id); + attribute_node.set_desired<>(value); + sl_log_debug(LOG_TAG, + "write callback set desired attribute %d", + attribute_id); + } + + return SL_STATUS_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// Init and teardown functions. +////////////////////////////////////////////////////////////////////////////// +sl_status_t schedule_entry_lock_cluster_server_init(void) +{ + sl_log_debug(LOG_TAG, "Schedule entry lock cluster server initialization"); + + uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_set( + zwave_command_class_schedule_entry_lock_enable_set_callback); + + uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_set( + zwave_command_class_schedule_entry_lock_enable_all_set_callback); + + uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_set( + zwave_command_class_schedule_entry_lock_week_day_set_callback); + + uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_set( + zwave_command_class_schedule_entry_lock_week_day_get_callback); + + uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_set( + zwave_command_class_schedule_entry_lock_year_day_set_callback); + + uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_set( + zwave_command_class_schedule_entry_lock_year_day_get_callback); + + uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_set( + zwave_command_class_schedule_entry_lock_daily_repeating_set_callback); + + uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_set( + zwave_command_class_schedule_entry_lock_daily_repeating_get_callback); + + uic_mqtt_dotdot_set_unify_schedule_entry_lock_write_attributes_callback( + zwave_command_class_schedule_entry_lock_write_attributes_callback); + + return SL_STATUS_OK; +} diff --git a/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.h b/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.h new file mode 100644 index 000000000..6ace59d39 --- /dev/null +++ b/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.h @@ -0,0 +1,35 @@ +/****************************************************************************** + * # 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 SCHEDULE_ENTRY_LOCK_SERVER_H +#define SCHEDULE_ENTRY_LOCK_SERVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the schedule entry lock cluster server + * + * @returns true on success + * @returns false on failure + * + */ +sl_status_t schedule_entry_lock_cluster_server_init(void); + +#ifdef __cplusplus +} +#endif + +#endif //SCHEDULE_ENTRY_LOCK_SERVER_H +/** @} end schedule_entry_lock_server */ diff --git a/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp b/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp index 736b3d7f3..b735453cb 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp +++ b/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers.cpp @@ -20,6 +20,7 @@ #include "user_code_cluster_server.h" #include "fan_control_cluster_server.h" #include "multilevel_sensor_cluster_server.h" +#include "schedule_entry_lock_server.h" //Includes from other components #include "attribute_store.h" @@ -44,6 +45,7 @@ sl_status_t zcl_cluster_servers_init() init_status |= user_code_cluster_server_init(); init_status |= fan_control_cluster_server_init(); init_status |= multilevel_sensor_cluster_server_init(); + init_status |= schedule_entry_lock_cluster_server_init(); return init_status; } 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 dc191cf3d..a9b7d3c90 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 @@ -524,7 +524,7 @@ static const std::vector attribute_schema = { {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY, "Number Of Slots Week Day", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY, "Number Of Slots Year Day", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, "Week Day Schedule Slot ID", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SET_ACTION, "Week Day Schedule Set Action", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SET_ACTION, "Week Day Schedule Set Action", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_DAY_OF_WEEK, "Week Day Schedule Day Of Week", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_START_HOUR, "Week Day Schedule Start Hour", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_START_MINUTE, "Week Day Schedule Start Minute", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_WEEK_DAY_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, diff --git a/applications/zpc/components/zwave_command_classes/CMakeLists.txt b/applications/zpc/components/zwave_command_classes/CMakeLists.txt index 99c75db5f..5da8521c4 100644 --- a/applications/zpc/components/zwave_command_classes/CMakeLists.txt +++ b/applications/zpc/components/zwave_command_classes/CMakeLists.txt @@ -41,6 +41,7 @@ add_library( src/zwave_command_class_scene_activation_control.c src/zwave_command_class_scene_actuator_configuration_control.c src/zwave_command_class_scene_controller_configuration_control.c + src/zwave_command_class_schedule_entry_lock.cpp src/zwave_command_class_security_0.c src/zwave_command_class_security_2.c src/zwave_command_class_supervision.c diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp index 23dba81df..15092db2b 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp @@ -104,9 +104,9 @@ static sl_status_t zwave_command_class_schedule_entry_lock_week_day_get( == ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)) { try { // Retrieve the node attributes - attribute_store::attribute weekday_schedule_slotid_node(node); - auto userid_node - = weekday_schedule_slotid_node.first_parent(ATTRIBUTE(USER_IDENTIFIER)); + attribute_store::attribute weekday_schedule_slot_id_node(node); + auto user_id_node + = weekday_schedule_slot_id_node.first_parent(ATTRIBUTE(USER_IDENTIFIER)); // Compute expected size for the set frame const uint8_t expected_frame_size = 4; @@ -115,8 +115,8 @@ static sl_status_t zwave_command_class_schedule_entry_lock_week_day_get( frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_WEEK_DAY_GET, frame, expected_frame_size); - frame_generator.add_value(userid_node, DESIRED_OR_REPORTED_ATTRIBUTE); - frame_generator.add_value(weekday_schedule_slotid_node, + frame_generator.add_value(user_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(weekday_schedule_slot_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); // Validate the constructed frame and set the frame length frame_generator.validate_frame(frame_length); @@ -138,9 +138,9 @@ static sl_status_t zwave_command_class_schedule_entry_lock_year_day_get( == ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)) { try { // Retrieve the node attributes - attribute_store::attribute yearday_schedule_slotid_node(node); - auto userid_node - = yearday_schedule_slotid_node.first_parent(ATTRIBUTE(USER_IDENTIFIER)); + attribute_store::attribute yearday_schedule_slot_id_node(node); + auto user_id_node + = yearday_schedule_slot_id_node.first_parent(ATTRIBUTE(USER_IDENTIFIER)); // Compute expected size for the set frame const uint8_t expected_frame_size = 4; @@ -149,8 +149,8 @@ static sl_status_t zwave_command_class_schedule_entry_lock_year_day_get( frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_YEAR_DAY_GET, frame, expected_frame_size); - frame_generator.add_value(userid_node, DESIRED_OR_REPORTED_ATTRIBUTE); - frame_generator.add_value(yearday_schedule_slotid_node, + frame_generator.add_value(user_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_slot_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); // Validate the constructed frame and set the frame length frame_generator.validate_frame(frame_length); @@ -165,6 +165,41 @@ static sl_status_t zwave_command_class_schedule_entry_lock_year_day_get( return SL_STATUS_OK; } +static sl_status_t zwave_command_class_schedule_entry_lock_daily_repeating_get( + attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +{ + if (attribute_store_get_node_type(node) + == ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID)) { + try { + // Retrieve the node attributes + attribute_store::attribute dailyrepeating_schedule_slot_id_node(node); + auto user_id_node + = dailyrepeating_schedule_slot_id_node.first_parent(ATTRIBUTE(USER_IDENTIFIER)); + + // Compute expected size for the set frame + const uint8_t expected_frame_size = 4; + + // Initialize the frame for Schedule Entry Lock Time Offset Set command + frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_YEAR_DAY_GET, + frame, + expected_frame_size); + frame_generator.add_value(user_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(dailyrepeating_schedule_slot_id_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + + // Validate the constructed frame and set the frame length + frame_generator.validate_frame(frame_length); + } catch (const std::exception &e) { + // Log any error that occurs during the frame generation process + sl_log_error(LOG_TAG, + "Error while generating Schedule Entry Lock Set frame: %s", + e.what()); + return SL_STATUS_FAIL; + } + } + return SL_STATUS_OK; +} + static sl_status_t zwave_command_class_schedule_entry_lock_time_offset_set( attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) { @@ -223,7 +258,7 @@ static sl_status_t zwave_command_class_schedule_entry_lock_enable_set( { try { attribute_store::attribute enable_node(node); - auto userid_node = enable_node.parent(); + auto user_id_node = enable_node.parent(); // Compute expected size for set frame const uint8_t expected_frame_size = 4; @@ -232,7 +267,7 @@ static sl_status_t zwave_command_class_schedule_entry_lock_enable_set( frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_ENABLE_SET, frame, expected_frame_size); - frame_generator.add_value(userid_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(user_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); frame_generator.add_value(enable_node, DESIRED_OR_REPORTED_ATTRIBUTE); frame_generator.validate_frame(frame_length); } catch (const std::exception &e) { @@ -275,24 +310,24 @@ static sl_status_t zwave_command_class_schedule_entry_lock_week_day_set( { try { attribute_store::attribute weekday_schedule_set_action_node(node); - auto userid_node = weekday_schedule_set_action_node.first_parent( + auto user_id_node = weekday_schedule_set_action_node.first_parent( ATTRIBUTE(USER_IDENTIFIER)); - auto weekday_schedule_slotid_node + auto weekday_schedule_slot_id_node = weekday_schedule_set_action_node.parent(); auto weekday_schedule_dayofweek_node - = weekday_schedule_slotid_node.child_by_type( + = weekday_schedule_slot_id_node.child_by_type( ATTRIBUTE(WEEK_DAY_SCHEDULE_DAY_OF_WEEK)); auto weekday_schedule_starthour_node - = weekday_schedule_slotid_node.child_by_type( + = weekday_schedule_slot_id_node.child_by_type( ATTRIBUTE(WEEK_DAY_SCHEDULE_START_HOUR)); auto weekday_schedule_startminute_node - = weekday_schedule_slotid_node.child_by_type( + = weekday_schedule_slot_id_node.child_by_type( ATTRIBUTE(WEEK_DAY_SCHEDULE_START_MINUTE)); auto weekday_schedule_stophour_node - = weekday_schedule_slotid_node.child_by_type( + = weekday_schedule_slot_id_node.child_by_type( ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_HOUR)); auto weekday_schedule_stopminute_node - = weekday_schedule_slotid_node.child_by_type( + = weekday_schedule_slot_id_node.child_by_type( ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_MINUTE)); // Compute expected size for set frame @@ -304,8 +339,8 @@ static sl_status_t zwave_command_class_schedule_entry_lock_week_day_set( expected_frame_size); frame_generator.add_value(weekday_schedule_set_action_node, DESIRED_OR_REPORTED_ATTRIBUTE); - frame_generator.add_value(userid_node, DESIRED_OR_REPORTED_ATTRIBUTE); - frame_generator.add_value(weekday_schedule_slotid_node, + frame_generator.add_value(user_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(weekday_schedule_slot_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); frame_generator.add_value(weekday_schedule_dayofweek_node, DESIRED_OR_REPORTED_ATTRIBUTE); @@ -333,39 +368,39 @@ static sl_status_t zwave_command_class_schedule_entry_lock_year_day_set( { try { attribute_store::attribute yearday_schedule_set_action_node(node); - auto userid_node = yearday_schedule_set_action_node.first_parent( + auto user_id_node = yearday_schedule_set_action_node.first_parent( ATTRIBUTE(USER_IDENTIFIER)); - auto yearday_schedule_slotid_node + auto yearday_schedule_slot_id_node = yearday_schedule_set_action_node.parent(); auto yearday_schedule_startyear_node - = yearday_schedule_slotid_node.child_by_type( + = yearday_schedule_slot_id_node.child_by_type( ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR)); auto yearday_schedule_startmonth_node - = yearday_schedule_slotid_node.child_by_type( + = yearday_schedule_slot_id_node.child_by_type( ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH)); auto yearday_schedule_startday_node - = yearday_schedule_slotid_node.child_by_type( + = yearday_schedule_slot_id_node.child_by_type( ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY)); auto yearday_schedule_starthour_node - = yearday_schedule_slotid_node.child_by_type( + = yearday_schedule_slot_id_node.child_by_type( ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR)); auto yearday_schedule_startminute_node - = yearday_schedule_slotid_node.child_by_type( + = yearday_schedule_slot_id_node.child_by_type( ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE)); auto yearday_schedule_stopyear_node - = yearday_schedule_slotid_node.child_by_type( + = yearday_schedule_slot_id_node.child_by_type( ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR)); auto yearday_schedule_stopmonth_node - = yearday_schedule_slotid_node.child_by_type( + = yearday_schedule_slot_id_node.child_by_type( ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH)); auto yearday_schedule_stopday_node - = yearday_schedule_slotid_node.child_by_type( + = yearday_schedule_slot_id_node.child_by_type( ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY)); auto yearday_schedule_stophour_node - = yearday_schedule_slotid_node.child_by_type( + = yearday_schedule_slot_id_node.child_by_type( ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR)); auto yearday_schedule_stopminute_node - = yearday_schedule_slotid_node.child_by_type( + = yearday_schedule_slot_id_node.child_by_type( ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE)); // Compute expected size for set frame @@ -377,8 +412,8 @@ static sl_status_t zwave_command_class_schedule_entry_lock_year_day_set( expected_frame_size); frame_generator.add_value(yearday_schedule_set_action_node, DESIRED_OR_REPORTED_ATTRIBUTE); - frame_generator.add_value(userid_node, DESIRED_OR_REPORTED_ATTRIBUTE); - frame_generator.add_value(yearday_schedule_slotid_node, + frame_generator.add_value(user_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(yearday_schedule_slot_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); frame_generator.add_value(yearday_schedule_startyear_node, DESIRED_OR_REPORTED_ATTRIBUTE); @@ -411,6 +446,70 @@ static sl_status_t zwave_command_class_schedule_entry_lock_year_day_set( return SL_STATUS_OK; } +static sl_status_t zwave_command_class_schedule_entry_lock_daily_repeating_set( + attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) +{ + try { + attribute_store::attribute dailyrepeating_schedule_set_action_node(node); + auto user_id_node = dailyrepeating_schedule_set_action_node.first_parent( + ATTRIBUTE(USER_IDENTIFIER)); + auto dailyrepeating_schedule_slot_id_node + = dailyrepeating_schedule_set_action_node.parent(); + auto number_of_slot_node + = dailyrepeating_schedule_slot_id_node.child_by_type( + ATTRIBUTE(NUMBER_OF_SLOTS_DAILY_REPEATING)); + auto dailyrepeating_weekday_node + = dailyrepeating_schedule_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_WEEK_DAY)); + auto dailyrepeating_starthour_node + = dailyrepeating_schedule_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_START_HOUR)); + auto dailyrepeating_startminute_node + = dailyrepeating_schedule_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_START_MINUTE)); + auto dailyrepeating_durationhour_node + = dailyrepeating_schedule_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_DURATION_HOUR)); + auto dailyrepeating_durationminute_node + = dailyrepeating_schedule_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_DURATION_MINUTE)); + + // Compute expected size for set frame + const uint8_t expected_frame_size = 10; + + // Creating the frame + frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_YEAR_DAY_SET, + frame, + expected_frame_size); + frame_generator.add_value(dailyrepeating_schedule_set_action_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(user_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(dailyrepeating_schedule_slot_id_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(number_of_slot_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(dailyrepeating_weekday_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(dailyrepeating_starthour_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(dailyrepeating_startminute_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(dailyrepeating_durationhour_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.add_value(dailyrepeating_durationminute_node, + DESIRED_OR_REPORTED_ATTRIBUTE); + frame_generator.validate_frame(frame_length); + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while generating schedule_entry_lock Set frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + + /////////////////////////////////////////////////////////////////////////////// // Frame parsing functions /////////////////////////////////////////////////////////////////////////////// @@ -499,14 +598,14 @@ static void zwave_command_class_schedule_entry_lock_on_version_attribute_update( = version_node.first_parent(ATTRIBUTE_ENDPOINT_ID); // Create the schedule_entry_lock attributes - attribute_store::attribute userid_node + attribute_store::attribute user_id_node = endpoint_node.emplace_node(ATTRIBUTE(USER_IDENTIFIER)); - userid_node.emplace_node(ATTRIBUTE(ENABLED)); + user_id_node.emplace_node(ATTRIBUTE(ENABLED)); endpoint_node.emplace_node(ATTRIBUTE(ENABLE_ALL)); - userid_node.emplace_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + endpoint_node.emplace_node(ATTRIBUTE(SLOTS_WEEK_DAY)); if (supporting_node_version >= 2) { endpoint_node.emplace_node(ATTRIBUTE(HOUR_TZO)); @@ -549,13 +648,21 @@ sl_status_t zwave_command_class_schedule_entry_lock_init() &zwave_command_class_schedule_entry_lock_year_day_set, NULL); attribute_resolver_register_rule( - ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID), + ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION), + &zwave_command_class_schedule_entry_lock_daily_repeating_set, + NULL); + attribute_resolver_register_rule( + ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION), NULL, &zwave_command_class_schedule_entry_lock_week_day_get); attribute_resolver_register_rule( - ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID), + ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION), NULL, &zwave_command_class_schedule_entry_lock_year_day_get); + attribute_resolver_register_rule( + ATTRIBUTE(DAILY_REPEATING_SET_ACTION), + NULL, + &zwave_command_class_schedule_entry_lock_daily_repeating_get); // The support side of things: Register our handler to the Z-Wave CC framework: zwave_command_handler_t handler = {}; From 39ab46591d943bc48172fe1a983bc8fe7c190ac8 Mon Sep 17 00:00:00 2001 From: Thirupathi S Date: Sat, 28 Sep 2024 04:18:17 +0000 Subject: [PATCH 11/12] UIC-3437: Report callback Schedule Entry Lock CC Merge in UIC/uic from feature/UIC-3437-Report-callback-Schedule-Entry-Lock-CC to feature/UIC-3271-Schedule-Entry-Lock-CC --- .../schedule_entry_lock_server.h | 28 ++ .../src/schedule_entry_lock_server.cpp | 119 ++++- .../zwave_command_classes/CMakeLists.txt | 1 + ...wave_command_class_schedule_entry_lock.cpp | 405 +++++++++++++++--- 4 files changed, 491 insertions(+), 62 deletions(-) rename applications/zpc/components/zcl_cluster_servers/{src => include}/schedule_entry_lock_server.h (57%) diff --git a/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.h b/applications/zpc/components/zcl_cluster_servers/include/schedule_entry_lock_server.h similarity index 57% rename from applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.h rename to applications/zpc/components/zcl_cluster_servers/include/schedule_entry_lock_server.h index 6ace59d39..cfcf0ae7d 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.h +++ b/applications/zpc/components/zcl_cluster_servers/include/schedule_entry_lock_server.h @@ -14,6 +14,18 @@ #ifndef SCHEDULE_ENTRY_LOCK_SERVER_H #define SCHEDULE_ENTRY_LOCK_SERVER_H +// Includes from other Unify Components +#include "dotdot_mqtt.h" +#include "dotdot_mqtt_generated_commands.h" +#include "attribute_store_helper.h" +#include "attribute_resolver.h" +#include "attribute_timeouts.h" +#include "sl_log.h" + +// Cpp include +#include "zwave_frame_generator.hpp" +#include "zwave_frame_parser.hpp" + #ifdef __cplusplus extern "C" { #endif @@ -27,6 +39,22 @@ extern "C" { */ sl_status_t schedule_entry_lock_cluster_server_init(void); +sl_status_t zwave_command_class_publish_generated_week_day_report_command( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + attribute_store_node_t endpoint_node); + +sl_status_t zwave_command_class_publish_generated_year_day_report_command( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + attribute_store_node_t endpoint_node); + +sl_status_t + zwave_command_class_publish_generated_daily_repeating_report_command( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + attribute_store_node_t endpoint_node); + #ifdef __cplusplus } #endif diff --git a/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp b/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp index b58e54917..b83646338 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp +++ b/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp @@ -26,18 +26,8 @@ #include "attribute_store_defined_attribute_types.h" #include "ZW_classcmd.h" -// Includes from other Unify Components -#include "dotdot_mqtt.h" -#include "dotdot_mqtt_generated_commands.h" -#include "attribute_store_helper.h" -#include "attribute_resolver.h" -#include "attribute_timeouts.h" -#include "sl_log.h" - -// Cpp include #include "attribute.hpp" -#include "zwave_frame_generator.hpp" -#include "zwave_frame_parser.hpp" + // Attribute macro, shortening those long defines for attribute types: #define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_##type @@ -230,10 +220,12 @@ static sl_status_t uint8_t user_identifier, uint8_t schedule_slotid, uint8_t start_year, + uint8_t start_month, uint8_t start_day, uint8_t start_hour, uint8_t start_minute, uint8_t stop_year, + uint8_t stop_month, uint8_t stop_day, uint8_t stop_hour, uint8_t stop_minute) @@ -251,10 +243,12 @@ static sl_status_t const std::map attribute_map = {{ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION), set_action}, {ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR), start_year}, + {ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH), start_month}, {ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY), start_day}, {ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR), start_hour}, {ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE), start_minute}, {ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR), stop_year}, + {ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH), stop_month}, {ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY), stop_day}, {ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR), stop_hour}, {ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE), stop_minute}}; @@ -440,6 +434,109 @@ sl_status_t zwave_command_class_schedule_entry_lock_write_attributes_callback( return SL_STATUS_OK; } +sl_status_t zwave_command_class_publish_generated_week_day_report_command(dotdot_unid_t unid, dotdot_endpoint_id_t endpoint, attribute_store_node_t ep_node){ + attribute_store::attribute endpoint_node(ep_node); + + uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t fields; + attribute_store::attribute user_id_node + = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); + attribute_store::attribute week_day_slot_id_node + = user_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)); + attribute_store::attribute day_of_week_node + = week_day_slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_DAY_OF_WEEK)); + attribute_store::attribute start_hour_node + = week_day_slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_START_HOUR)); + attribute_store::attribute start_minute_node + = week_day_slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_START_MINUTE)); + attribute_store::attribute stop_hour_node + = week_day_slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_HOUR)); + attribute_store::attribute stop_minute_node + = week_day_slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_MINUTE)); + fields.user_identifier = user_id_node.reported(); + fields.schedule_slotid = week_day_slot_id_node.reported(); + fields.day_of_week = day_of_week_node.reported(); + fields.start_hour = start_hour_node.reported(); + fields.start_minute = start_minute_node.reported(); + fields.stop_hour = stop_hour_node.reported(); + fields.stop_minute = stop_minute_node.reported(); + uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_week_day_report_command(unid, endpoint, &fields); + return SL_STATUS_OK; +} + +sl_status_t zwave_command_class_publish_generated_year_day_report_command(dotdot_unid_t unid, dotdot_endpoint_id_t endpoint, attribute_store_node_t ep_node){ + attribute_store::attribute endpoint_node(ep_node); + + uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t fields; + attribute_store::attribute user_id_node + = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); + attribute_store::attribute year_day_slot_id_node + = user_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)); + attribute_store::attribute start_year_node + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR)); + attribute_store::attribute start_month_node + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH)); + attribute_store::attribute start_day_node + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY)); + attribute_store::attribute start_hour_node + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR)); + attribute_store::attribute start_minute_node + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE)); + attribute_store::attribute stop_year_node + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR)); + attribute_store::attribute stop_month_node + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH)); + attribute_store::attribute stop_day_node + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY)); + attribute_store::attribute stop_hour_node + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR)); + attribute_store::attribute stop_minute_node + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE)); + fields.user_identifier = user_id_node.reported(); + fields.schedule_slotid = year_day_slot_id_node.reported(); + fields.start_year = start_year_node.reported(); + fields.start_month = start_month_node.reported(); + fields.start_day= start_day_node.reported(); + fields.start_hour = start_hour_node.reported(); + fields.start_minute = start_minute_node.reported(); + fields.stop_year = stop_year_node.reported(); + fields.stop_month = stop_month_node.reported(); + fields.stop_day= stop_day_node.reported(); + fields.stop_hour = stop_hour_node.reported(); + fields.stop_minute = stop_minute_node.reported(); + + uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_year_day_report_command(unid, endpoint, &fields); + return SL_STATUS_OK; +} + +sl_status_t zwave_command_class_publish_generated_daily_repeating_report_command(dotdot_unid_t unid, dotdot_endpoint_id_t endpoint, attribute_store_node_t ep_node){ + attribute_store::attribute endpoint_node(ep_node); + + uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t fields; + attribute_store::attribute user_id_node + = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); + attribute_store::attribute daily_repeating_slot_id_node + = user_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID)); + attribute_store::attribute week_day_node + = daily_repeating_slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_WEEK_DAY)); + attribute_store::attribute start_hour_node + = daily_repeating_slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_START_HOUR)); + attribute_store::attribute start_minute_node + = daily_repeating_slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_START_MINUTE)); + attribute_store::attribute duartion_hour_node + = daily_repeating_slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_DURATION_HOUR)); + attribute_store::attribute duration_minute_node + = daily_repeating_slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_DURATION_MINUTE)); + fields.user_identifier = user_id_node.reported(); + fields.schedule_slotid = daily_repeating_slot_id_node.reported(); + fields.week_day_bitmask = week_day_node.reported(); + fields.start_hour = start_hour_node.reported(); + fields.start_minute = start_minute_node.reported(); + fields.duration_hour= duartion_hour_node.reported(); + fields.duration_minute = duration_minute_node.reported(); + uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_daily_repeating_report_command(unid, endpoint, &fields); + return SL_STATUS_OK; +} + /////////////////////////////////////////////////////////////////////////////// // Init and teardown functions. ////////////////////////////////////////////////////////////////////////////// diff --git a/applications/zpc/components/zwave_command_classes/CMakeLists.txt b/applications/zpc/components/zwave_command_classes/CMakeLists.txt index 5da8521c4..a6c67d948 100644 --- a/applications/zpc/components/zwave_command_classes/CMakeLists.txt +++ b/applications/zpc/components/zwave_command_classes/CMakeLists.txt @@ -129,6 +129,7 @@ target_link_libraries(zwave_command_classes zpc_utils zpc_scripts unify + zcl_cluster_servers zwave_definitions) if(BUILD_TESTING) diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp index 15092db2b..a9f57b6a8 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp @@ -13,6 +13,7 @@ // Includes from this component #include "zwave_command_class_schedule_entry_lock.h" #include "zwave_command_classes_utils.h" +#include "schedule_entry_lock_server.h" // Generic includes #include @@ -69,6 +70,7 @@ zwave_cc_version_t return version; } + /////////////////////////////////////////////////////////////////////////////// // Resolution functions /////////////////////////////////////////////////////////////////////////////// @@ -105,8 +107,8 @@ static sl_status_t zwave_command_class_schedule_entry_lock_week_day_get( try { // Retrieve the node attributes attribute_store::attribute weekday_schedule_slot_id_node(node); - auto user_id_node - = weekday_schedule_slot_id_node.first_parent(ATTRIBUTE(USER_IDENTIFIER)); + auto user_id_node = weekday_schedule_slot_id_node.first_parent( + ATTRIBUTE(USER_IDENTIFIER)); // Compute expected size for the set frame const uint8_t expected_frame_size = 4; @@ -139,8 +141,8 @@ static sl_status_t zwave_command_class_schedule_entry_lock_year_day_get( try { // Retrieve the node attributes attribute_store::attribute yearday_schedule_slot_id_node(node); - auto user_id_node - = yearday_schedule_slot_id_node.first_parent(ATTRIBUTE(USER_IDENTIFIER)); + auto user_id_node = yearday_schedule_slot_id_node.first_parent( + ATTRIBUTE(USER_IDENTIFIER)); // Compute expected size for the set frame const uint8_t expected_frame_size = 4; @@ -173,16 +175,17 @@ static sl_status_t zwave_command_class_schedule_entry_lock_daily_repeating_get( try { // Retrieve the node attributes attribute_store::attribute dailyrepeating_schedule_slot_id_node(node); - auto user_id_node - = dailyrepeating_schedule_slot_id_node.first_parent(ATTRIBUTE(USER_IDENTIFIER)); + auto user_id_node = dailyrepeating_schedule_slot_id_node.first_parent( + ATTRIBUTE(USER_IDENTIFIER)); // Compute expected size for the set frame const uint8_t expected_frame_size = 4; // Initialize the frame for Schedule Entry Lock Time Offset Set command - frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_YEAR_DAY_GET, - frame, - expected_frame_size); + frame_generator.initialize_frame( + SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_GET_V3, + frame, + expected_frame_size); frame_generator.add_value(user_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); frame_generator.add_value(dailyrepeating_schedule_slot_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); @@ -478,7 +481,7 @@ static sl_status_t zwave_command_class_schedule_entry_lock_daily_repeating_set( const uint8_t expected_frame_size = 10; // Creating the frame - frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_YEAR_DAY_SET, + frame_generator.initialize_frame(SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SET_V3, frame, expected_frame_size); frame_generator.add_value(dailyrepeating_schedule_set_action_node, @@ -509,43 +512,324 @@ static sl_status_t zwave_command_class_schedule_entry_lock_daily_repeating_set( return SL_STATUS_OK; } - /////////////////////////////////////////////////////////////////////////////// // Frame parsing functions /////////////////////////////////////////////////////////////////////////////// -//static sl_status_t zwave_command_class_schedule_entry_lock_handle_report( -// const zwave_controller_connection_info_t *connection_info, -// const uint8_t *frame_data, -// uint16_t frame_length) -//{ -// // Setup -// attribute_store::attribute endpoint_node( -// zwave_command_class_get_endpoint_node(connection_info)); -// auto current_version = get_current_schedule_entry_lock_version(endpoint_node); -// -// sl_log_debug(LOG_TAG, "schedule_entry_lock Report frame received"); -// -// // Compute expected size for report frame -// const uint8_t expected_size = 12; - -// // Parse the frame -// try { -// zwave_frame_parser parser(frame_data, frame_length); - -// if (!parser.is_frame_size_valid(expected_size)) { -// sl_log_error(LOG_TAG, -// "Invalid frame size for schedule_entry_lock Report frame"); -// return SL_STATUS_FAIL; -// } - -// } catch (const std::exception &e) { -// sl_log_error(LOG_TAG, -// "Error while parsing schedule_entry_lock Report frame : %s", -// e.what()); -// return SL_STATUS_FAIL; -// } -// return SL_STATUS_OK; -//} +static sl_status_t + zwave_command_class_schedule_entry_lock_type_supported_report( + const zwave_controller_connection_info_t *connection_info, + const uint8_t *frame_data, + uint16_t frame_length) +{ + // Setup + attribute_store::attribute endpoint_node( + zwave_command_class_get_endpoint_node(connection_info)); + auto current_version = get_current_schedule_entry_lock_version(endpoint_node); + + sl_log_debug(LOG_TAG, "schedule_entry_lock Report frame received"); + + // Compute expected size for report frame + const uint8_t expected_size = 5; + + // Parse the frame + try { + zwave_frame_parser parser(frame_data, frame_length); + + if (!parser.is_frame_size_valid(expected_size)) { + sl_log_error(LOG_TAG, + "Invalid frame size for schedule_entry_lock Report frame"); + return SL_STATUS_FAIL; + } + + attribute_store::attribute week_day_node + = endpoint_node.child_by_type(ATTRIBUTE(SLOTS_WEEK_DAY)); + parser.read_byte(week_day_node); + attribute_store::attribute year_day_node + = endpoint_node.child_by_type(ATTRIBUTE(SLOTS_YEAR_DAY)); + parser.read_byte(year_day_node); + + if (current_version >= 3) { + attribute_store::attribute number_of_slot_daily_repeating_node + = endpoint_node.child_by_type( + ATTRIBUTE(NUMBER_OF_SLOTS_DAILY_REPEATING)); + parser.read_byte(number_of_slot_daily_repeating_node); + } + + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while parsing schedule_entry_lock Report frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} + +static sl_status_t zwave_command_class_schedule_entry_lock_week_day_report( + const zwave_controller_connection_info_t *connection_info, + const uint8_t *frame_data, + uint16_t frame_length) +{ + unid_t unid; + dotdot_endpoint_id_t endpoint; + + // Setup + attribute_store::attribute endpoint_node( + zwave_command_class_get_endpoint_node(connection_info)); + + sl_log_debug(LOG_TAG, "schedule_entry_lock Report frame received"); + + // Compute expected size for report frame + const uint8_t expected_size = 9; + + // Parse the frame + try { + zwave_frame_parser parser(frame_data, frame_length); + + if (!parser.is_frame_size_valid(expected_size)) { + sl_log_error(LOG_TAG, + "Invalid frame size for schedule_entry_lock Report frame"); + return SL_STATUS_FAIL; + } + + attribute_store::attribute user_id_node + = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); + parser.read_byte(user_id_node); + attribute_store::attribute week_day_slot_id_node + = user_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)); + parser.read_byte(week_day_slot_id_node); + attribute_store::attribute day_of_week_node + = week_day_slot_id_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_DAY_OF_WEEK)); + parser.read_byte(day_of_week_node); + attribute_store::attribute start_hour_node + = week_day_slot_id_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_START_HOUR)); + parser.read_byte(start_hour_node); + attribute_store::attribute start_minute_node + = week_day_slot_id_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_START_MINUTE)); + parser.read_byte(start_minute_node); + attribute_store::attribute stop_hour_node + = week_day_slot_id_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_HOUR)); + parser.read_byte(stop_hour_node); + attribute_store::attribute stop_minute_node + = week_day_slot_id_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_MINUTE)); + parser.read_byte(stop_minute_node); + attribute_store_network_helper_get_unid_from_node(endpoint_node, unid); + endpoint = endpoint_node.reported(); + zwave_command_class_publish_generated_week_day_report_command( + unid, + endpoint, + endpoint_node); + + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while parsing schedule_entry_lock Report frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} + +static sl_status_t zwave_command_class_schedule_entry_lock_year_day_report( + const zwave_controller_connection_info_t *connection_info, + const uint8_t *frame_data, + uint16_t frame_length) +{ + unid_t unid; + dotdot_endpoint_id_t endpoint; + + // Setup + attribute_store::attribute endpoint_node( + zwave_command_class_get_endpoint_node(connection_info)); + + sl_log_debug(LOG_TAG, "schedule_entry_lock Report frame received"); + + // Compute expected size for report frame + const uint8_t expected_size = 14; + + // Parse the frame + try { + zwave_frame_parser parser(frame_data, frame_length); + + if (!parser.is_frame_size_valid(expected_size)) { + sl_log_error(LOG_TAG, + "Invalid frame size for schedule_entry_lock Report frame"); + return SL_STATUS_FAIL; + } + + attribute_store::attribute user_id_node + = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); + parser.read_byte(user_id_node); + attribute_store::attribute year_day_slot_id_node + = user_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)); + parser.read_byte(year_day_slot_id_node); + attribute_store::attribute start_year_node + = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR)); + parser.read_byte(start_year_node); + attribute_store::attribute start_month_node + = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH)); + parser.read_byte(start_month_node); + attribute_store::attribute start_day_node + = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY)); + parser.read_byte(start_day_node); + attribute_store::attribute start_hour_node + = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR)); + parser.read_byte(start_hour_node); + attribute_store::attribute start_minute_node + = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE)); + parser.read_byte(start_minute_node); + attribute_store::attribute stop_year_node + = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR)); + parser.read_byte(stop_year_node); + attribute_store::attribute stop_month_node + = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH)); + parser.read_byte(stop_month_node); + attribute_store::attribute stop_day_node + = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY)); + parser.read_byte(stop_day_node); + attribute_store::attribute stop_hour_node + = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR)); + parser.read_byte(stop_hour_node); + attribute_store::attribute stop_minute_node + = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE)); + parser.read_byte(stop_minute_node); + attribute_store_network_helper_get_unid_from_node(endpoint_node, unid); + endpoint = endpoint_node.reported(); + zwave_command_class_publish_generated_year_day_report_command( + unid, + endpoint, + endpoint_node); + + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while parsing schedule_entry_lock Report frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} + +static sl_status_t zwave_command_class_schedule_entry_lock_time_offset_report( + const zwave_controller_connection_info_t *connection_info, + const uint8_t *frame_data, + uint16_t frame_length) +{ + // Setup + attribute_store::attribute endpoint_node( + zwave_command_class_get_endpoint_node(connection_info)); + + sl_log_debug(LOG_TAG, "schedule_entry_lock Report frame received"); + + // Compute expected size for report frame + const uint8_t expected_size = 5; + + // Parse the frame + try { + zwave_frame_parser parser(frame_data, frame_length); + + if (!parser.is_frame_size_valid(expected_size)) { + sl_log_error(LOG_TAG, + "Invalid frame size for schedule_entry_lock Report frame"); + return SL_STATUS_FAIL; + } + + attribute_store::attribute sign_tzo_node + = endpoint_node.child_by_type(ATTRIBUTE(SIGN_TZO)); + parser.read_byte(sign_tzo_node); + attribute_store::attribute hour_tzo_node + = endpoint_node.child_by_type(ATTRIBUTE(HOUR_TZO)); + parser.read_byte(hour_tzo_node); + attribute_store::attribute minute_tzo_node + = endpoint_node.child_by_type(ATTRIBUTE(MINUTE_TZO)); + parser.read_byte(minute_tzo_node); + attribute_store::attribute dst_offset_sign_node + = endpoint_node.child_by_type(ATTRIBUTE(DST_OFFSET_SIGN)); + parser.read_byte(dst_offset_sign_node); + attribute_store::attribute dst_offset_minute_node + = endpoint_node.child_by_type(ATTRIBUTE(DST_OFFSET_MINUTE)); + parser.read_byte(dst_offset_minute_node); + + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while parsing schedule_entry_lock Report frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} + +static sl_status_t + zwave_command_class_schedule_entry_lock_daily_repeating_report( + const zwave_controller_connection_info_t *connection_info, + const uint8_t *frame_data, + uint16_t frame_length) +{ + unid_t unid; + dotdot_endpoint_id_t endpoint; + + // Setup + attribute_store::attribute endpoint_node( + zwave_command_class_get_endpoint_node(connection_info)); + + sl_log_debug(LOG_TAG, "schedule_entry_lock Report frame received"); + + // Compute expected size for report frame + const uint8_t expected_size = 9; + + // Parse the frame + try { + zwave_frame_parser parser(frame_data, frame_length); + + if (!parser.is_frame_size_valid(expected_size)) { + sl_log_error(LOG_TAG, + "Invalid frame size for schedule_entry_lock Report frame"); + return SL_STATUS_FAIL; + } + + attribute_store::attribute user_id_node + = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); + parser.read_byte(user_id_node); + attribute_store::attribute daily_repeating_slot_id_node + = user_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)); + parser.read_byte(daily_repeating_slot_id_node); + attribute_store::attribute week_day_node + = daily_repeating_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_WEEK_DAY)); + parser.read_byte(week_day_node); + attribute_store::attribute start_hour_node + = daily_repeating_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_START_HOUR)); + parser.read_byte(start_hour_node); + attribute_store::attribute start_minute_node + = daily_repeating_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_START_MINUTE)); + parser.read_byte(start_minute_node); + attribute_store::attribute duration_hour_node + = daily_repeating_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_DURATION_HOUR)); + parser.read_byte(duration_hour_node); + attribute_store::attribute duration_minute_node + = daily_repeating_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_DURATION_MINUTE)); + parser.read_byte(duration_minute_node); + attribute_store_network_helper_get_unid_from_node(endpoint_node, unid); + endpoint = endpoint_node.reported(); + zwave_command_class_publish_generated_daily_repeating_report_command( + unid, + endpoint, + endpoint_node); + + } catch (const std::exception &e) { + sl_log_error(LOG_TAG, + "Error while parsing schedule_entry_lock Report frame : %s", + e.what()); + return SL_STATUS_FAIL; + } + return SL_STATUS_OK; +} /////////////////////////////////////////////////////////////////////////////// // Incoming commands handler @@ -559,17 +843,36 @@ sl_status_t zwave_command_class_schedule_entry_lock_control_handler( if (frame_length <= COMMAND_INDEX) { return SL_STATUS_NOT_SUPPORTED; } - switch (frame_data[COMMAND_INDEX]) { - // case schedule_entry_lock_REPORT: - // return zwave_command_class_schedule_entry_lock_handle_report(connection_info, - // frame_data, - // frame_length); + case SCHEDULE_ENTRY_TYPE_SUPPORTED_REPORT: + return zwave_command_class_schedule_entry_lock_type_supported_report( + connection_info, + frame_data, + frame_length); + case SCHEDULE_ENTRY_LOCK_WEEK_DAY_REPORT: + return zwave_command_class_schedule_entry_lock_week_day_report( + connection_info, + frame_data, + frame_length); + case SCHEDULE_ENTRY_LOCK_YEAR_DAY_REPORT: + return zwave_command_class_schedule_entry_lock_year_day_report( + connection_info, + frame_data, + frame_length); + case SCHEDULE_ENTRY_LOCK_TIME_OFFSET_REPORT_V2: + return zwave_command_class_schedule_entry_lock_time_offset_report( + connection_info, + frame_data, + frame_length); + case SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_REPORT_V3: + return zwave_command_class_schedule_entry_lock_daily_repeating_report( + connection_info, + frame_data, + frame_length); default: return SL_STATUS_NOT_SUPPORTED; } } - /////////////////////////////////////////////////////////////////////////////// // Attribute Store callback functions /////////////////////////////////////////////////////////////////////////////// @@ -648,7 +951,7 @@ sl_status_t zwave_command_class_schedule_entry_lock_init() &zwave_command_class_schedule_entry_lock_year_day_set, NULL); attribute_resolver_register_rule( - ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION), + ATTRIBUTE(DAILY_REPEATING_SET_ACTION), &zwave_command_class_schedule_entry_lock_daily_repeating_set, NULL); attribute_resolver_register_rule( From de5870b9e5b086c849efddf24ed2151ecccc1bf3 Mon Sep 17 00:00:00 2001 From: Thirupathi S Date: Tue, 8 Oct 2024 04:53:21 +0000 Subject: [PATCH 12/12] Unit test cases for schedule entry lock cc Merge in UIC/uic from feature/UIC-3439-Unit-Test-Schedule-Entry-Lock-CC to feature/UIC-3271-Schedule-Entry-Lock-CC --- .../include/schedule_entry_lock_server.h | 7 + .../src/schedule_entry_lock_server.cpp | 309 ++++---- .../zcl_cluster_servers/test/CMakeLists.txt | 17 +- .../test/schedule_entry_lock_server_test.cpp | 524 ++++++++++++++ .../zpc_attribute_store_type_registration.cpp | 8 +- ...wave_command_class_schedule_entry_lock.cpp | 81 +-- ...command_class_schedule_entry_lock_test.cpp | 662 ++++++++++++++++++ 7 files changed, 1430 insertions(+), 178 deletions(-) create mode 100644 applications/zpc/components/zcl_cluster_servers/test/schedule_entry_lock_server_test.cpp create mode 100644 applications/zpc/components/zwave_command_classes/test/zwave_command_class_schedule_entry_lock_test.cpp diff --git a/applications/zpc/components/zcl_cluster_servers/include/schedule_entry_lock_server.h b/applications/zpc/components/zcl_cluster_servers/include/schedule_entry_lock_server.h index cfcf0ae7d..acb4f0b51 100644 --- a/applications/zpc/components/zcl_cluster_servers/include/schedule_entry_lock_server.h +++ b/applications/zpc/components/zcl_cluster_servers/include/schedule_entry_lock_server.h @@ -55,6 +55,13 @@ sl_status_t dotdot_endpoint_id_t endpoint, attribute_store_node_t endpoint_node); +sl_status_t zwave_command_class_schedule_entry_lock_write_attributes_callback( + const dotdot_unid_t unid, + const dotdot_endpoint_id_t endpoint, + uic_mqtt_dotdot_callback_call_type_t call_type, + uic_mqtt_dotdot_unify_schedule_entry_lock_state_t lock_state, + uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t updated_lock_state); + #ifdef __cplusplus } #endif diff --git a/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp b/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp index b83646338..9b706861e 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp +++ b/applications/zpc/components/zcl_cluster_servers/src/schedule_entry_lock_server.cpp @@ -28,7 +28,6 @@ #include "attribute.hpp" - // Attribute macro, shortening those long defines for attribute types: #define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_##type @@ -62,10 +61,10 @@ sl_status_t attribute_store::attribute endpoint_node = base_id_node.child_by_type_and_value<>(ATTRIBUTE_ENDPOINT_ID, endpoint); - // If both attribute are not defined, we definitely doesn't support this Command Class - if (!endpoint_node.child_by_type(ATTRIBUTE(SLOTS_WEEK_DAY)).is_valid() && - !endpoint_node.child_by_type(ATTRIBUTE(HOUR_TZO)).is_valid()) { - return SL_STATUS_FAIL; + // If both attribute are not defined, we definitely doesn't support this Command Class + if (!endpoint_node.child_by_type(ATTRIBUTE(SLOTS_WEEK_DAY)).is_valid() + && !endpoint_node.child_by_type(ATTRIBUTE(HOUR_TZO)).is_valid()) { + return SL_STATUS_FAIL; } return SL_STATUS_OK; @@ -82,9 +81,7 @@ static sl_status_t helper_set_desired_values( child_node.set_desired(value); } } catch (const std::exception &e) { - sl_log_error(LOG_TAG, - "Error while generating schedule_entry_lock Set frame : %s", - e.what()); + sl_log_error(LOG_TAG, "Error while setting desired values : %s", e.what()); return SL_STATUS_FAIL; } return SL_STATUS_OK; @@ -106,11 +103,10 @@ static sl_status_t zwave_command_class_schedule_entry_lock_enable_set_callback( } try { auto user_id_node = get_user_id_node(unid, endpoint, user_identifier); - user_id_node.child_by_type(ATTRIBUTE(ENABLED)) - .set_desired(enabled); + user_id_node.child_by_type(ATTRIBUTE(ENABLED)).set_desired(enabled); } catch (const std::exception &e) { sl_log_error(LOG_TAG, - "Error while generating schedule_entry_lock Set frame : %s", + "Error while generating schedule_entry_lock enable Set : %s", e.what()); return SL_STATUS_FAIL; } @@ -132,12 +128,12 @@ static sl_status_t = attribute_store_network_helper_get_node_id_node(unid); attribute_store::attribute endpoint_node = base_id_node.child_by_type_and_value(ATTRIBUTE_ENDPOINT_ID, endpoint); - endpoint_node.child_by_type(ATTRIBUTE(ENABLED)) - .set_desired<>(enabled); + endpoint_node.child_by_type(ATTRIBUTE(ENABLE_ALL)).set_desired<>(enabled); } catch (const std::exception &e) { - sl_log_error(LOG_TAG, - "Error while generating schedule_entry_lock Set frame : %s", - e.what()); + sl_log_error( + LOG_TAG, + "Error while generating schedule_entry_lock enable all Set : %s", + e.what()); return SL_STATUS_FAIL; } return SL_STATUS_OK; @@ -177,7 +173,7 @@ static sl_status_t } catch (const std::exception &e) { sl_log_error(LOG_TAG, - "Error while generating schedule_entry_lock Set frame : %s", + "Error while generating schedule_entry_lock week day Set : %s", e.what()); return SL_STATUS_FAIL; } @@ -197,14 +193,16 @@ static sl_status_t try { auto user_id_node = get_user_id_node(unid, endpoint, user_identifier); - auto slot_id_node = user_id_node.child_by_type_and_value(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID), - schedule_slotid); - auto set_action_node = slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION)); + auto slot_id_node = user_id_node.child_by_type_and_value( + ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID), + schedule_slotid); + auto set_action_node + = slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION)); set_action_node.clear_reported(); } catch (const std::exception &e) { sl_log_error(LOG_TAG, - "Error while retrieving schedule_entry_lock: %s", + "Error while retrieving schedule_entry_lock weekday get: %s", e.what()); return SL_STATUS_FAIL; } @@ -256,7 +254,7 @@ static sl_status_t return helper_set_desired_values(slot_id_node, attribute_map); } catch (const std::exception &e) { sl_log_error(LOG_TAG, - "Error while generating schedule_entry_lock Set frame: %s", + "Error while generating schedule_entry_lock yearday set: %s", e.what()); return SL_STATUS_FAIL; } @@ -275,13 +273,15 @@ static sl_status_t } try { auto user_id_node = get_user_id_node(unid, endpoint, user_identifier); - auto slot_id_node = user_id_node.child_by_type_and_value(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID), - schedule_slotid); - auto set_action_node = slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION)); + auto slot_id_node = user_id_node.child_by_type_and_value( + ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID), + schedule_slotid); + auto set_action_node + = slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION)); set_action_node.clear_reported(); } catch (const std::exception &e) { sl_log_error(LOG_TAG, - "Error while generating schedule_entry_lock Set frame : %s", + "Error while generating schedule_entry_lock yearday get : %s", e.what()); return SL_STATUS_FAIL; } @@ -302,6 +302,9 @@ static sl_status_t uint8_t duration_hour, uint8_t duration_minute) { + if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { + return zwave_command_class_check_ep_support(unid, endpoint); + } try { auto user_id_node = get_user_id_node(unid, endpoint, user_identifier); auto slot_id_node = user_id_node.child_by_type_and_value( @@ -318,9 +321,10 @@ static sl_status_t return helper_set_desired_values(slot_id_node, attribute_map); } catch (const std::exception &e) { - sl_log_error(LOG_TAG, - "Error while generating schedule_entry_lock Set frame: %s", - e.what()); + sl_log_error( + LOG_TAG, + "Error while generating schedule_entry_lock daily repeating Set: %s", + e.what()); return SL_STATUS_FAIL; } } @@ -345,14 +349,17 @@ static sl_status_t auto user_id_node = endpoint_node.child_by_type_and_value(ATTRIBUTE(USER_IDENTIFIER), user_identifier); - auto slot_id_node = user_id_node.child_by_type_and_value(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID), - schedule_slotid); - auto set_action_node = slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_SET_ACTION)); + auto slot_id_node = user_id_node.child_by_type_and_value( + ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID), + schedule_slotid); + auto set_action_node + = slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_SET_ACTION)); set_action_node.clear_reported(); } catch (const std::exception &e) { - sl_log_error(LOG_TAG, - "Error while generating schedule_entry_lock Set frame : %s", - e.what()); + sl_log_error( + LOG_TAG, + "Error while generating schedule_entry_lock daily repeating Set : %s", + e.what()); return SL_STATUS_FAIL; } return SL_STATUS_OK; @@ -427,114 +434,160 @@ sl_status_t zwave_command_class_schedule_entry_lock_write_attributes_callback( = endpoint_node.emplace_node(attribute_id); attribute_node.set_desired<>(value); sl_log_debug(LOG_TAG, - "write callback set desired attribute %d", - attribute_id); + "write callback set desired attribute %u %u", + attribute_id, + attribute_node); } return SL_STATUS_OK; } -sl_status_t zwave_command_class_publish_generated_week_day_report_command(dotdot_unid_t unid, dotdot_endpoint_id_t endpoint, attribute_store_node_t ep_node){ +sl_status_t zwave_command_class_publish_generated_week_day_report_command( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + attribute_store_node_t ep_node) +{ attribute_store::attribute endpoint_node(ep_node); - uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t fields; - attribute_store::attribute user_id_node - = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); - attribute_store::attribute week_day_slot_id_node - = user_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)); - attribute_store::attribute day_of_week_node - = week_day_slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_DAY_OF_WEEK)); - attribute_store::attribute start_hour_node - = week_day_slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_START_HOUR)); - attribute_store::attribute start_minute_node - = week_day_slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_START_MINUTE)); - attribute_store::attribute stop_hour_node - = week_day_slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_HOUR)); - attribute_store::attribute stop_minute_node - = week_day_slot_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_MINUTE)); - fields.user_identifier = user_id_node.reported(); - fields.schedule_slotid = week_day_slot_id_node.reported(); - fields.day_of_week = day_of_week_node.reported(); - fields.start_hour = start_hour_node.reported(); - fields.start_minute = start_minute_node.reported(); - fields.stop_hour = stop_hour_node.reported(); - fields.stop_minute = stop_minute_node.reported(); - uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_week_day_report_command(unid, endpoint, &fields); - return SL_STATUS_OK; + uic_mqtt_dotdot_unify_schedule_entry_lock_command_week_day_report_fields_t + fields; + attribute_store::attribute user_id_node + = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); + attribute_store::attribute week_day_slot_id_node + = user_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)); + attribute_store::attribute day_of_week_node + = week_day_slot_id_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_DAY_OF_WEEK)); + attribute_store::attribute start_hour_node + = week_day_slot_id_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_START_HOUR)); + attribute_store::attribute start_minute_node + = week_day_slot_id_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_START_MINUTE)); + attribute_store::attribute stop_hour_node + = week_day_slot_id_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_HOUR)); + attribute_store::attribute stop_minute_node + = week_day_slot_id_node.child_by_type( + ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_MINUTE)); + fields.user_identifier = user_id_node.reported(); + fields.schedule_slotid = week_day_slot_id_node.reported(); + fields.day_of_week = day_of_week_node.reported(); + fields.start_hour = start_hour_node.reported(); + fields.start_minute = start_minute_node.reported(); + fields.stop_hour = stop_hour_node.reported(); + fields.stop_minute = stop_minute_node.reported(); + uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_week_day_report_command( + unid, + endpoint, + &fields); + return SL_STATUS_OK; } -sl_status_t zwave_command_class_publish_generated_year_day_report_command(dotdot_unid_t unid, dotdot_endpoint_id_t endpoint, attribute_store_node_t ep_node){ +sl_status_t zwave_command_class_publish_generated_year_day_report_command( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + attribute_store_node_t ep_node) +{ attribute_store::attribute endpoint_node(ep_node); - uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t fields; - attribute_store::attribute user_id_node - = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); - attribute_store::attribute year_day_slot_id_node - = user_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)); - attribute_store::attribute start_year_node - = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR)); - attribute_store::attribute start_month_node - = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH)); - attribute_store::attribute start_day_node - = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY)); - attribute_store::attribute start_hour_node - = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR)); - attribute_store::attribute start_minute_node - = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE)); - attribute_store::attribute stop_year_node - = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR)); - attribute_store::attribute stop_month_node - = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH)); - attribute_store::attribute stop_day_node - = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY)); - attribute_store::attribute stop_hour_node - = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR)); - attribute_store::attribute stop_minute_node - = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE)); - fields.user_identifier = user_id_node.reported(); - fields.schedule_slotid = year_day_slot_id_node.reported(); - fields.start_year = start_year_node.reported(); - fields.start_month = start_month_node.reported(); - fields.start_day= start_day_node.reported(); - fields.start_hour = start_hour_node.reported(); - fields.start_minute = start_minute_node.reported(); - fields.stop_year = stop_year_node.reported(); - fields.stop_month = stop_month_node.reported(); - fields.stop_day= stop_day_node.reported(); - fields.stop_hour = stop_hour_node.reported(); - fields.stop_minute = stop_minute_node.reported(); - - uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_year_day_report_command(unid, endpoint, &fields); - return SL_STATUS_OK; + uic_mqtt_dotdot_unify_schedule_entry_lock_command_year_day_report_fields_t + fields; + attribute_store::attribute user_id_node + = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); + attribute_store::attribute year_day_slot_id_node + = user_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)); + attribute_store::attribute start_year_node + = year_day_slot_id_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR)); + attribute_store::attribute start_month_node + = year_day_slot_id_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH)); + attribute_store::attribute start_day_node + = year_day_slot_id_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY)); + attribute_store::attribute start_hour_node + = year_day_slot_id_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR)); + attribute_store::attribute start_minute_node + = year_day_slot_id_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE)); + attribute_store::attribute stop_year_node + = year_day_slot_id_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR)); + attribute_store::attribute stop_month_node + = year_day_slot_id_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH)); + attribute_store::attribute stop_day_node + = year_day_slot_id_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY)); + attribute_store::attribute stop_hour_node + = year_day_slot_id_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR)); + attribute_store::attribute stop_minute_node + = year_day_slot_id_node.child_by_type( + ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE)); + fields.user_identifier = user_id_node.reported(); + fields.schedule_slotid = year_day_slot_id_node.reported(); + fields.start_year = start_year_node.reported(); + fields.start_month = start_month_node.reported(); + fields.start_day = start_day_node.reported(); + fields.start_hour = start_hour_node.reported(); + fields.start_minute = start_minute_node.reported(); + fields.stop_year = stop_year_node.reported(); + fields.stop_month = stop_month_node.reported(); + fields.stop_day = stop_day_node.reported(); + fields.stop_hour = stop_hour_node.reported(); + fields.stop_minute = stop_minute_node.reported(); + + uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_year_day_report_command( + unid, + endpoint, + &fields); + return SL_STATUS_OK; } -sl_status_t zwave_command_class_publish_generated_daily_repeating_report_command(dotdot_unid_t unid, dotdot_endpoint_id_t endpoint, attribute_store_node_t ep_node){ +sl_status_t + zwave_command_class_publish_generated_daily_repeating_report_command( + dotdot_unid_t unid, + dotdot_endpoint_id_t endpoint, + attribute_store_node_t ep_node) +{ attribute_store::attribute endpoint_node(ep_node); - uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t fields; - attribute_store::attribute user_id_node - = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); - attribute_store::attribute daily_repeating_slot_id_node - = user_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID)); - attribute_store::attribute week_day_node - = daily_repeating_slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_WEEK_DAY)); - attribute_store::attribute start_hour_node - = daily_repeating_slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_START_HOUR)); - attribute_store::attribute start_minute_node - = daily_repeating_slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_START_MINUTE)); - attribute_store::attribute duartion_hour_node - = daily_repeating_slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_DURATION_HOUR)); - attribute_store::attribute duration_minute_node - = daily_repeating_slot_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_DURATION_MINUTE)); - fields.user_identifier = user_id_node.reported(); - fields.schedule_slotid = daily_repeating_slot_id_node.reported(); - fields.week_day_bitmask = week_day_node.reported(); - fields.start_hour = start_hour_node.reported(); - fields.start_minute = start_minute_node.reported(); - fields.duration_hour= duartion_hour_node.reported(); - fields.duration_minute = duration_minute_node.reported(); - uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_daily_repeating_report_command(unid, endpoint, &fields); - return SL_STATUS_OK; + uic_mqtt_dotdot_unify_schedule_entry_lock_command_daily_repeating_report_fields_t + fields; + attribute_store::attribute user_id_node + = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); + attribute_store::attribute daily_repeating_slot_id_node + = user_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID)); + attribute_store::attribute week_day_node + = daily_repeating_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_WEEK_DAY)); + attribute_store::attribute start_hour_node + = daily_repeating_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_START_HOUR)); + attribute_store::attribute start_minute_node + = daily_repeating_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_START_MINUTE)); + attribute_store::attribute duartion_hour_node + = daily_repeating_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_DURATION_HOUR)); + attribute_store::attribute duration_minute_node + = daily_repeating_slot_id_node.child_by_type( + ATTRIBUTE(DAILY_REPEATING_DURATION_MINUTE)); + fields.user_identifier = user_id_node.reported(); + fields.schedule_slotid = daily_repeating_slot_id_node.reported(); + fields.week_day_bitmask = week_day_node.reported(); + fields.start_hour = start_hour_node.reported(); + fields.start_minute = start_minute_node.reported(); + fields.duration_hour = duartion_hour_node.reported(); + fields.duration_minute = duration_minute_node.reported(); + uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_daily_repeating_report_command( + unid, + endpoint, + &fields); + return SL_STATUS_OK; } /////////////////////////////////////////////////////////////////////////////// diff --git a/applications/zpc/components/zcl_cluster_servers/test/CMakeLists.txt b/applications/zpc/components/zcl_cluster_servers/test/CMakeLists.txt index a5142592a..d330362dc 100644 --- a/applications/zpc/components/zcl_cluster_servers/test/CMakeLists.txt +++ b/applications/zpc/components/zcl_cluster_servers/test/CMakeLists.txt @@ -88,6 +88,21 @@ target_add_unittest( uic_contiki_stub unify) +# Schedule entry lock server test +target_add_unittest( + zcl_cluster_servers + NAME + schedule_entry_lock_server_test + SOURCES + schedule_entry_lock_server_test.cpp + DEPENDS + zpc_attribute_store_test_helper + uic_dotdot_mqtt_mock + unify_dotdot_attribute_store + zpc_attribute_store_network_helper_mock + zwave_command_class_test_helpers + ) + # User Code Cluster Server test target_add_unittest( zcl_cluster_servers @@ -126,4 +141,4 @@ target_add_unittest( DEPENDS zpc_attribute_store_test_helper uic_dotdot_mqtt_mock - unify_dotdot_attribute_store) \ No newline at end of file + unify_dotdot_attribute_store) diff --git a/applications/zpc/components/zcl_cluster_servers/test/schedule_entry_lock_server_test.cpp b/applications/zpc/components/zcl_cluster_servers/test/schedule_entry_lock_server_test.cpp new file mode 100644 index 000000000..4cf3ad045 --- /dev/null +++ b/applications/zpc/components/zcl_cluster_servers/test/schedule_entry_lock_server_test.cpp @@ -0,0 +1,524 @@ +/****************************************************************************** + * # License + * Copyright 2022 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 "schedule_entry_lock_server.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 "zpc_attribute_store_network_helper.h" + +// ZPC Components +#include "zwave_unid.h" +#include "zwave_command_class_schedule_entry_lock.h" +#include "zwave_command_class_test_helper.hpp" + +// Test helpers +#include "zpc_attribute_store_test_helper.h" + +// Attribute macro, shortening those long defines for attribute types: +#define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_##type +using namespace zwave_command_class_test_helper; + +extern "C" { + +// Mock helper +#include "dotdot_mqtt_mock.h" +#include "dotdot_mqtt_generated_commands_mock.h" +#include "zpc_attribute_store_network_helper_mock.h" +#include "attribute_store_defined_attribute_types.h" +#include "unify_dotdot_attribute_store.h" + +// private variables + +static uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t enable_set = NULL; +static uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t enable_all_set = NULL; +static uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t week_day_set = NULL; +static uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t week_day_get = NULL; +static uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t year_day_set = NULL; +static uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t year_day_get = NULL; +static uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t daily_repeating_set = NULL; +static uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t daily_repeating_get = NULL; +static uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t write_attributes_callback = NULL; + +void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_set_stub(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_t callback,int cmock_num_calls){ + enable_set = callback; +} + +void uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_set_stub(const uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_t callback,int cmock_num_calls){ + enable_all_set = callback; +} + +void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_set_stub(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_t callback,int cmock_num_calls) +{ + week_day_set = callback; +} + +void uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_set_stub(const uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_t callback,int cmock_num_calls) +{ + week_day_get = callback; +} + +void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_set_stub(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_t callback,int cmock_num_calls) +{ + year_day_set = callback; +} + +void uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_set_stub(const uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_t callback,int cmock_num_calls) +{ + year_day_get = callback; +} + +void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_set_stub(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_t callback,int cmock_num_calls){ + daily_repeating_set = callback; +} + +void uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_set_stub(const uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_t callback,int cmock_num_calls){ + daily_repeating_get = callback; +} + +void uic_mqtt_dotdot_set_unify_schedule_entry_lock_write_attributes_callback_stub(const uic_mqtt_dotdot_unify_schedule_entry_lock_write_attributes_callback_t callback, int cmock_num_calls){ + write_attributes_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_schedule_entry_lock_enable_set_callback_set_Stub( + &uic_mqtt_dotdot_unify_schedule_entry_lock_enable_set_callback_set_stub); + + uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_set_Stub( + &uic_mqtt_dotdot_unify_schedule_entry_lock_enable_all_set_callback_set_stub); + + uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_set_Stub( + &uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_set_callback_set_stub); + + uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_set_Stub( + &uic_mqtt_dotdot_unify_schedule_entry_lock_week_day_get_callback_set_stub); + + uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_set_Stub( + &uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_set_callback_set_stub); + + uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_set_Stub( + &uic_mqtt_dotdot_unify_schedule_entry_lock_year_day_get_callback_set_stub); + + uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_set_Stub( + &uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_set_callback_set_stub); + + uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_set_Stub( + &uic_mqtt_dotdot_unify_schedule_entry_lock_daily_repeating_get_callback_set_stub); + + uic_mqtt_dotdot_set_unify_schedule_entry_lock_write_attributes_callback_Stub( + &uic_mqtt_dotdot_set_unify_schedule_entry_lock_write_attributes_callback_stub); + + // Call init + TEST_ASSERT_EQUAL(SL_STATUS_OK, schedule_entry_lock_cluster_server_init()); +} + +/// Called after each and every test +void tearDown() +{ + attribute_store_delete_node(attribute_store_get_root()); +} + +void test_schedule_entry_lock_enable_set() +{ + TEST_ASSERT_NOT_NULL(enable_set); + uint8_t user_id = 3; + uint8_t enabled = 1; + + attribute_store::attribute ep_node_id(endpoint_id_node); + + auto user_id_node = ep_node_id.emplace_node(ATTRIBUTE(USER_IDENTIFIER)); + user_id_node.emplace_node(ATTRIBUTE(ENABLED)); + user_id_node.set_reported(user_id); + ep_node_id.emplace_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + ep_node_id.emplace_node(ATTRIBUTE(HOUR_TZO)); + + attribute_store_network_helper_get_node_id_node_IgnoreAndReturn(node_id_node); + + // Support check + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + enable_set(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, + user_id, + enabled)); + + // Test callback + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + enable_set(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, + user_id, + enabled)); +} + +void test_schedule_entry_lock_enable_all_set(){ + TEST_ASSERT_NOT_NULL(enable_all_set); + uint8_t enabled = 1; + attribute_store::attribute ep_node_id(endpoint_id_node); + ep_node_id.emplace_node(ATTRIBUTE(ENABLE_ALL)); + ep_node_id.emplace_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + ep_node_id.emplace_node(ATTRIBUTE(HOUR_TZO)); + + + attribute_store_network_helper_get_node_id_node_IgnoreAndReturn(node_id_node); + + // Support check + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + enable_all_set(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, + enabled)); + + // Test callback + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + enable_all_set(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, + enabled)); + +} + +void test_schedule_entry_lock_week_day_set(){ + TEST_ASSERT_NOT_NULL(week_day_set); + uint8_t set_action = 1; + uint8_t user_identifier = 1; + uint8_t schedule_slotid = 1; + uint8_t day_of_week = 2; + uint8_t start_hour = 2; + uint8_t start_minute = 3; + uint8_t stop_hour = 3; + uint8_t stop_minute = 4; + + attribute_store::attribute ep_node_id(endpoint_id_node); + auto user_id_node = ep_node_id.emplace_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node = user_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)); + user_id_node.set_reported(user_identifier); + slot_id_node.set_reported(schedule_slotid); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION)); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_DAY_OF_WEEK)); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_START_HOUR)); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_START_MINUTE)); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_HOUR)); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_MINUTE)); + + ep_node_id.emplace_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + ep_node_id.emplace_node(ATTRIBUTE(HOUR_TZO)); + + attribute_store_network_helper_get_node_id_node_IgnoreAndReturn(node_id_node); + + // Support check + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + week_day_set(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, + set_action,user_identifier,schedule_slotid,day_of_week,start_hour,start_minute,stop_hour,stop_minute)); + + // Test callback + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + week_day_set(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, + set_action,user_identifier,schedule_slotid,day_of_week,start_hour,start_minute,stop_hour,stop_minute)); +} + +void test_schedule_entry_lock_week_day_get(){ + TEST_ASSERT_NOT_NULL(week_day_get); + uint8_t user_identifier = 1; + uint8_t schedule_slotid = 1; + + attribute_store::attribute ep_node_id(endpoint_id_node); + auto user_id_node = ep_node_id.emplace_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node = user_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)); + user_id_node.set_reported(user_identifier); + slot_id_node.set_reported(schedule_slotid); + ep_node_id.emplace_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + ep_node_id.emplace_node(ATTRIBUTE(HOUR_TZO)); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION)); + + attribute_store_network_helper_get_node_id_node_IgnoreAndReturn(node_id_node); + + // Support check + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + week_day_get(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, + user_identifier,schedule_slotid)); + + // Test callback + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + week_day_get(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, + user_identifier,schedule_slotid)); +} + +void test_schedule_entry_lock_year_day_set(){ + TEST_ASSERT_NOT_NULL(year_day_set); + uint8_t set_action = 1; + uint8_t user_identifier = 1; + uint8_t schedule_slotid = 1; + uint8_t start_year = 2; + uint8_t start_day = 2; + uint8_t start_month = 2; + uint8_t start_hour = 2; + uint8_t start_minute = 3; + uint8_t stop_year = 3; + uint8_t stop_month = 3; + uint8_t stop_hour = 4; + uint8_t stop_day = 4; + uint8_t stop_minute = 4; + + attribute_store::attribute ep_node_id(endpoint_id_node); + auto user_id_node = ep_node_id.emplace_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node = user_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)); + user_id_node.set_reported(user_identifier); + slot_id_node.set_reported(schedule_slotid); + ep_node_id.emplace_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + ep_node_id.emplace_node(ATTRIBUTE(HOUR_TZO)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE)); + + attribute_store_network_helper_get_node_id_node_IgnoreAndReturn(node_id_node); + + // Support check + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + year_day_set(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, + set_action,user_identifier,schedule_slotid,start_year,start_day,start_hour,start_month,start_minute,stop_year,stop_month,stop_day,stop_hour,stop_minute)); + + // Test callback + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + year_day_set(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, + set_action,user_identifier,schedule_slotid,start_year,start_day,start_hour,start_month,start_minute,stop_year,stop_month,stop_day,stop_hour,stop_minute)); + +} + +void test_schedule_entry_lock_year_day_get(){ + TEST_ASSERT_NOT_NULL(year_day_get); + uint8_t user_identifier = 1; + uint8_t schedule_slotid = 1; + + attribute_store::attribute ep_node_id(endpoint_id_node); + auto user_id_node = ep_node_id.emplace_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node = user_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)); + user_id_node.set_reported(user_identifier); + slot_id_node.set_reported(schedule_slotid); + ep_node_id.emplace_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + ep_node_id.emplace_node(ATTRIBUTE(HOUR_TZO)); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION)); + + attribute_store_network_helper_get_node_id_node_IgnoreAndReturn(node_id_node); + + // Support check + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + year_day_get(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, + user_identifier,schedule_slotid)); + + // Test callback + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + year_day_get(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, + user_identifier,schedule_slotid)); + +} + + +void test_schedule_entry_lock_daily_repeating_set(){ + TEST_ASSERT_NOT_NULL(daily_repeating_set); + uint8_t set_action = 1; + uint8_t user_identifier = 1; + uint8_t schedule_slotid = 1; + uint8_t week_day_bitmask = 2; + uint8_t start_hour = 2; + uint8_t start_minute = 3; + uint8_t duration_hour = 3; + uint8_t duration_minute = 4; + + attribute_store::attribute ep_node_id(endpoint_id_node); + auto user_id_node = ep_node_id.emplace_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node = user_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID)); + user_id_node.set_reported(user_identifier); + slot_id_node.set_reported(schedule_slotid); + ep_node_id.emplace_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + ep_node_id.emplace_node(ATTRIBUTE(HOUR_TZO)); + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_SET_ACTION)); + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_WEEK_DAY)); + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_START_HOUR)); + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_START_MINUTE)); + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_DURATION_HOUR)); + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_DURATION_MINUTE)); + + attribute_store_network_helper_get_node_id_node_IgnoreAndReturn(node_id_node); + + // Support check + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + daily_repeating_set(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, + set_action,user_identifier,schedule_slotid,week_day_bitmask,start_hour,start_minute,duration_hour,duration_minute)); + + // Test callback + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + daily_repeating_set(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, + set_action,user_identifier,schedule_slotid,week_day_bitmask,start_hour,start_minute,duration_hour,duration_minute)); +} + +void test_schedule_entry_lock_daily_repeating_get(){ + TEST_ASSERT_NOT_NULL(daily_repeating_get); + uint8_t user_identifier = 1; + uint8_t schedule_slotid = 1; + + attribute_store::attribute ep_node_id(endpoint_id_node); + auto user_id_node = ep_node_id.emplace_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node = user_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID)); + user_id_node.set_reported(user_identifier); + slot_id_node.set_reported(schedule_slotid); + ep_node_id.emplace_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + ep_node_id.emplace_node(ATTRIBUTE(HOUR_TZO)); + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_SET_ACTION)); + + attribute_store_network_helper_get_node_id_node_IgnoreAndReturn(node_id_node); + + // Support check + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + daily_repeating_get(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK, + user_identifier,schedule_slotid)); + + // Test callback + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + daily_repeating_get(supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, + user_identifier,schedule_slotid)); +} + +void test_schedule_entry_lock_write_attributes_callback() +{ + TEST_ASSERT_NOT_NULL(write_attributes_callback); + + attribute_store_network_helper_get_node_id_node_IgnoreAndReturn(node_id_node); + + // Define the lock state with sample values + uic_mqtt_dotdot_unify_schedule_entry_lock_state_t lock_state = {}; + lock_state.slots_week_day = 1; + lock_state.slots_year_day = 2; + lock_state.signtzo = 3; + lock_state.hourtzo = 4; + lock_state.minutetzo = 5; + lock_state.dst_offset_sign = 6; + lock_state.dst_offset_minute = 7; + lock_state.number_of_slots_daily_repeating = 8; + + // Define the updated state to indicate which attributes are updated + uic_mqtt_dotdot_unify_schedule_entry_lock_updated_state_t updated_lock_state = {}; + updated_lock_state.slots_week_day = true; + updated_lock_state.slots_year_day = true; + updated_lock_state.signtzo = true; + updated_lock_state.hourtzo = true; + updated_lock_state.minutetzo = true; + updated_lock_state.dst_offset_sign = true; + updated_lock_state.dst_offset_minute = true; + updated_lock_state.number_of_slots_daily_repeating = true; + + // Mock attribute nodes for testing each field + attribute_store::attribute ep_node_id(endpoint_id_node); + auto slots_week_day_node = ep_node_id.emplace_node(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_WEEK_DAY); + auto slots_year_day_node = ep_node_id.emplace_node(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SLOTS_YEAR_DAY); + auto signtzo_node = ep_node_id.emplace_node(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_SIGNTZO); + auto hourtzo_node = ep_node_id.emplace_node(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_HOURTZO); + auto minutetzo_node = ep_node_id.emplace_node(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_MINUTETZO); + auto dst_offset_sign_node = ep_node_id.emplace_node(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_SIGN); + auto dst_offset_minute_node = ep_node_id.emplace_node(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_DST_OFFSET_MINUTE); + auto number_of_slots_daily_repeating_node = ep_node_id.emplace_node(DOTDOT_ATTRIBUTE_ID_UNIFY_SCHEDULE_ENTRY_LOCK_NUMBER_OF_SLOTS_DAILY_REPEATING); + + uic_mqtt_dotdot_set_unify_schedule_entry_lock_write_attributes_callback_Ignore(); + // Run the callback + write_attributes_callback( + supporting_node_unid, + endpoint_id, + UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL, + lock_state, + updated_lock_state + ); + + // Test the desired values set by the callback + TEST_ASSERT_EQUAL_UINT8(lock_state.slots_week_day, slots_week_day_node.desired()); + TEST_ASSERT_EQUAL_UINT8(lock_state.slots_year_day, slots_year_day_node.desired()); + TEST_ASSERT_EQUAL_UINT8(lock_state.signtzo, signtzo_node.desired()); + TEST_ASSERT_EQUAL_UINT8(lock_state.hourtzo, hourtzo_node.desired()); + TEST_ASSERT_EQUAL_UINT8(lock_state.minutetzo, minutetzo_node.desired()); + TEST_ASSERT_EQUAL_UINT8(lock_state.dst_offset_sign, dst_offset_sign_node.desired()); + TEST_ASSERT_EQUAL_UINT8(lock_state.dst_offset_minute, dst_offset_minute_node.desired()); + TEST_ASSERT_EQUAL_UINT8(lock_state.number_of_slots_daily_repeating, number_of_slots_daily_repeating_node.desired()); +} + +} // extern "C" 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 a9b7d3c90..064366c71 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 @@ -553,10 +553,10 @@ static const std::vector attribute_schema = { {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SET_ACTION, "Daily Repeating Set Action", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, "Daily Repeating Slot ID", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_USER_IDENTIFIER, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_WEEK_DAY, "Daily Repeating Week Day", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_START_HOUR, "Daily Repeating Start Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_START_MINUTE, "Daily Repeating Start Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_DURATION_HOUR, "Daily Repeating Duration Hour", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, - {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_DURATION_MINUTE, "Daily Repeating Duration Minute", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_START_HOUR, "Daily Repeating Start Hour", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_START_MINUTE, "Daily Repeating Start Minute", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_DURATION_HOUR, "Daily Repeating Duration Hour", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_DURATION_MINUTE, "Daily Repeating Duration Minute", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE}, //DoorLock Command Class attributes {ATTRIBUTE_DOOR_LOCK_CONFIGURATION_OPERATION_TYPE, "Door Lock Configuration Operation Type", ATTRIBUTE_ENDPOINT_ID, I32_STORAGE_TYPE }, diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp index a9f57b6a8..19fb0f6a0 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_schedule_entry_lock.cpp @@ -103,10 +103,11 @@ static sl_status_t zwave_command_class_schedule_entry_lock_week_day_get( attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) { if (attribute_store_get_node_type(node) - == ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)) { + == ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION)) { try { // Retrieve the node attributes - attribute_store::attribute weekday_schedule_slot_id_node(node); + attribute_store::attribute weekday_schedule_set_action_node(node); + auto weekday_schedule_slot_id_node = weekday_schedule_set_action_node.parent(); auto user_id_node = weekday_schedule_slot_id_node.first_parent( ATTRIBUTE(USER_IDENTIFIER)); @@ -137,10 +138,11 @@ static sl_status_t zwave_command_class_schedule_entry_lock_year_day_get( attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) { if (attribute_store_get_node_type(node) - == ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)) { + == ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION)) { try { // Retrieve the node attributes - attribute_store::attribute yearday_schedule_slot_id_node(node); + attribute_store::attribute yearday_schedule_set_action_node(node); + auto yearday_schedule_slot_id_node = yearday_schedule_set_action_node.parent(); auto user_id_node = yearday_schedule_slot_id_node.first_parent( ATTRIBUTE(USER_IDENTIFIER)); @@ -171,10 +173,11 @@ static sl_status_t zwave_command_class_schedule_entry_lock_daily_repeating_get( attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) { if (attribute_store_get_node_type(node) - == ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID)) { + == ATTRIBUTE(DAILY_REPEATING_SET_ACTION)) { try { // Retrieve the node attributes - attribute_store::attribute dailyrepeating_schedule_slot_id_node(node); + attribute_store::attribute dailyrepeating_schedule_set_action_node(node); + auto dailyrepeating_schedule_slot_id_node = dailyrepeating_schedule_set_action_node.parent(); auto user_id_node = dailyrepeating_schedule_slot_id_node.first_parent( ATTRIBUTE(USER_IDENTIFIER)); @@ -189,7 +192,6 @@ static sl_status_t zwave_command_class_schedule_entry_lock_daily_repeating_get( frame_generator.add_value(user_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); frame_generator.add_value(dailyrepeating_schedule_slot_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); - // Validate the constructed frame and set the frame length frame_generator.validate_frame(frame_length); } catch (const std::exception &e) { @@ -211,10 +213,10 @@ static sl_status_t zwave_command_class_schedule_entry_lock_time_offset_set( attribute_store::attribute hour_tzo_node(node); auto endpoint_node = hour_tzo_node.parent(); auto minute_tzo_node = endpoint_node.child_by_type(ATTRIBUTE(MINUTE_TZO)); - auto sign_hour_tzo_node = endpoint_node.child_by_type(ATTRIBUTE(HOUR_TZO)); - auto minute_offset_dst_node - = endpoint_node.child_by_type(ATTRIBUTE(DST_OFFSET_SIGN)); + auto sign_tzo_node = endpoint_node.child_by_type(ATTRIBUTE(SIGN_TZO)); auto sign_offset_dst_node + = endpoint_node.child_by_type(ATTRIBUTE(DST_OFFSET_SIGN)); + auto minute_offset_dst_node = endpoint_node.child_by_type(ATTRIBUTE(DST_OFFSET_MINUTE)); // Compute expected size for the set frame @@ -228,7 +230,7 @@ static sl_status_t zwave_command_class_schedule_entry_lock_time_offset_set( // Create a vector for the values to be shifted into the frame frame_generator.add_shifted_values( {{.left_shift = 7, // Sign TZO (1 bit) - .node = sign_hour_tzo_node, + .node = sign_tzo_node, .node_value_state = DESIRED_OR_REPORTED_ATTRIBUTE}, {.left_shift = 0, // Hour TZO (7 bits) .node = hour_tzo_node, @@ -458,9 +460,6 @@ static sl_status_t zwave_command_class_schedule_entry_lock_daily_repeating_set( ATTRIBUTE(USER_IDENTIFIER)); auto dailyrepeating_schedule_slot_id_node = dailyrepeating_schedule_set_action_node.parent(); - auto number_of_slot_node - = dailyrepeating_schedule_slot_id_node.child_by_type( - ATTRIBUTE(NUMBER_OF_SLOTS_DAILY_REPEATING)); auto dailyrepeating_weekday_node = dailyrepeating_schedule_slot_id_node.child_by_type( ATTRIBUTE(DAILY_REPEATING_WEEK_DAY)); @@ -489,8 +488,6 @@ static sl_status_t zwave_command_class_schedule_entry_lock_daily_repeating_set( frame_generator.add_value(user_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); frame_generator.add_value(dailyrepeating_schedule_slot_id_node, DESIRED_OR_REPORTED_ATTRIBUTE); - frame_generator.add_value(number_of_slot_node, - DESIRED_OR_REPORTED_ATTRIBUTE); frame_generator.add_value(dailyrepeating_weekday_node, DESIRED_OR_REPORTED_ATTRIBUTE); frame_generator.add_value(dailyrepeating_starthour_node, @@ -667,34 +664,34 @@ static sl_status_t zwave_command_class_schedule_entry_lock_year_day_report( = user_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)); parser.read_byte(year_day_slot_id_node); attribute_store::attribute start_year_node - = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR)); + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR)); parser.read_byte(start_year_node); attribute_store::attribute start_month_node - = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH)); + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH)); parser.read_byte(start_month_node); attribute_store::attribute start_day_node - = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY)); + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY)); parser.read_byte(start_day_node); attribute_store::attribute start_hour_node - = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR)); + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR)); parser.read_byte(start_hour_node); attribute_store::attribute start_minute_node - = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE)); + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE)); parser.read_byte(start_minute_node); attribute_store::attribute stop_year_node - = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR)); + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR)); parser.read_byte(stop_year_node); attribute_store::attribute stop_month_node - = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH)); + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH)); parser.read_byte(stop_month_node); attribute_store::attribute stop_day_node - = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY)); + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY)); parser.read_byte(stop_day_node); attribute_store::attribute stop_hour_node - = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR)); + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR)); parser.read_byte(stop_hour_node); attribute_store::attribute stop_minute_node - = endpoint_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE)); + = year_day_slot_id_node.child_by_type(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE)); parser.read_byte(stop_minute_node); attribute_store_network_helper_get_unid_from_node(endpoint_node, unid); endpoint = endpoint_node.reported(); @@ -738,19 +735,25 @@ static sl_status_t zwave_command_class_schedule_entry_lock_time_offset_report( attribute_store::attribute sign_tzo_node = endpoint_node.child_by_type(ATTRIBUTE(SIGN_TZO)); - parser.read_byte(sign_tzo_node); attribute_store::attribute hour_tzo_node = endpoint_node.child_by_type(ATTRIBUTE(HOUR_TZO)); - parser.read_byte(hour_tzo_node); + std::vector data_first_byte = { + {.bitmask = SCHEDULE_ENTRY_LOCK_TIME_OFFSET_REPORT_LEVEL_SIGN_TZO_BIT_MASK_V2, .destination_node = sign_tzo_node}, + {.bitmask = SCHEDULE_ENTRY_LOCK_TIME_OFFSET_REPORT_LEVEL_HOUR_TZO_MASK_V2, .destination_node = hour_tzo_node} + }; + parser.read_byte_with_bitmask(data_first_byte); attribute_store::attribute minute_tzo_node = endpoint_node.child_by_type(ATTRIBUTE(MINUTE_TZO)); parser.read_byte(minute_tzo_node); attribute_store::attribute dst_offset_sign_node = endpoint_node.child_by_type(ATTRIBUTE(DST_OFFSET_SIGN)); - parser.read_byte(dst_offset_sign_node); attribute_store::attribute dst_offset_minute_node = endpoint_node.child_by_type(ATTRIBUTE(DST_OFFSET_MINUTE)); - parser.read_byte(dst_offset_minute_node); + std::vector data_third_byte = { + {.bitmask = SCHEDULE_ENTRY_LOCK_TIME_OFFSET_REPORT_LEVEL2_SIGN_OFFSET_DST_BIT_MASK_V2, .destination_node = dst_offset_sign_node}, + {.bitmask = SCHEDULE_ENTRY_LOCK_TIME_OFFSET_REPORT_LEVEL2_MINUTE_OFFSET_DST_MASK_V2, .destination_node = dst_offset_minute_node} + }; + parser.read_byte_with_bitmask(data_third_byte); } catch (const std::exception &e) { sl_log_error(LOG_TAG, @@ -793,7 +796,7 @@ static sl_status_t = endpoint_node.child_by_type(ATTRIBUTE(USER_IDENTIFIER)); parser.read_byte(user_id_node); attribute_store::attribute daily_repeating_slot_id_node - = user_id_node.child_by_type(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)); + = user_id_node.child_by_type(ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID)); parser.read_byte(daily_repeating_slot_id_node); attribute_store::attribute week_day_node = daily_repeating_slot_id_node.child_by_type( @@ -945,26 +948,14 @@ sl_status_t zwave_command_class_schedule_entry_lock_init() attribute_resolver_register_rule( ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION), &zwave_command_class_schedule_entry_lock_week_day_set, - NULL); - attribute_resolver_register_rule( - ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION), - &zwave_command_class_schedule_entry_lock_year_day_set, - NULL); - attribute_resolver_register_rule( - ATTRIBUTE(DAILY_REPEATING_SET_ACTION), - &zwave_command_class_schedule_entry_lock_daily_repeating_set, - NULL); - attribute_resolver_register_rule( - ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION), - NULL, &zwave_command_class_schedule_entry_lock_week_day_get); attribute_resolver_register_rule( ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION), - NULL, + &zwave_command_class_schedule_entry_lock_year_day_set, &zwave_command_class_schedule_entry_lock_year_day_get); attribute_resolver_register_rule( ATTRIBUTE(DAILY_REPEATING_SET_ACTION), - NULL, + &zwave_command_class_schedule_entry_lock_daily_repeating_set, &zwave_command_class_schedule_entry_lock_daily_repeating_get); // The support side of things: Register our handler to the Z-Wave CC framework: diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_schedule_entry_lock_test.cpp b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_schedule_entry_lock_test.cpp new file mode 100644 index 000000000..ff2c2a233 --- /dev/null +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_schedule_entry_lock_test.cpp @@ -0,0 +1,662 @@ +/****************************************************************************** + * # 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. + * + *****************************************************************************/ +// Base class +#include "zwave_command_class_schedule_entry_lock.h" +#include "zwave_command_classes_utils.h" +#include "unity.h" + +// Generic includes +#include + +// Unify +#include "datastore.h" +#include "attribute_store.h" +#include "attribute_store_fixt.h" +// Interface includes +#include "ZW_classcmd.h" + +// ZPC includes +#include "attribute_store_defined_attribute_types.h" +#include "zpc_attribute_store_type_registration.h" +#include "sl_log.h" + +// Test helpers +#include "zwave_command_class_test_helper.hpp" + +constexpr uint8_t SCHEDULE_ENTRY_LOCK_ENABLE = 0x01; +constexpr uint8_t SCHEDULE_ENTRY_LOCK_DISABLE = 0x00; +constexpr uint8_t SCHEDULE_ENTRY_LOCK_ERASE_SLOT = 0; +constexpr uint8_t SCHEDULE_ENTRY_LOCK_MODIFY_SLOT = 1; + +// Attribute macro, shortening those long defines for attribute types: +#define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_##type + +using namespace zwave_command_class_test_helper; + +extern "C" { + +// Mock helper +#include "dotdot_mqtt_mock.h" +#include "dotdot_mqtt_generated_commands_mock.h" +#include "zpc_attribute_store_network_helper_mock.h" + +/// 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; +} + +// Tested command class handler +const zwave_struct_handler_args command_class_handler + = {.command_class_id = COMMAND_CLASS_SCHEDULE_ENTRY_LOCK, + .supported_version = SCHEDULE_ENTRY_LOCK_VERSION_V3}; +// Get Set function map +const resolver_function_map attribute_bindings + = {{ATTRIBUTE(SLOTS_WEEK_DAY), {SCHEDULE_ENTRY_TYPE_SUPPORTED_GET, 0}}, + {ATTRIBUTE(HOUR_TZO), + {SCHEDULE_ENTRY_LOCK_TIME_OFFSET_GET_V2, + SCHEDULE_ENTRY_LOCK_TIME_OFFSET_SET_V2}}, + {ATTRIBUTE(ENABLED), {0, SCHEDULE_ENTRY_LOCK_ENABLE_SET}}, + {ATTRIBUTE(ENABLE_ALL), {0, SCHEDULE_ENTRY_LOCK_ENABLE_ALL_SET}}, + {ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION), + {SCHEDULE_ENTRY_LOCK_WEEK_DAY_GET, SCHEDULE_ENTRY_LOCK_WEEK_DAY_SET}}, + {ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION), + {SCHEDULE_ENTRY_LOCK_YEAR_DAY_GET, SCHEDULE_ENTRY_LOCK_YEAR_DAY_SET}}, + {ATTRIBUTE(DAILY_REPEATING_SET_ACTION), + {SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_GET_V3, + SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SET_V3}}}; + +/// Called before each and every test +void setUp() +{ + zwave_setUp(command_class_handler, + &zwave_command_class_schedule_entry_lock_init, + attribute_bindings); +} + +void test_switch_all_interview_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + // Verify that we have the correct node(s) + auto user_id_node = helper_test_and_get_node(ATTRIBUTE(USER_IDENTIFIER)); + helper_test_node_exists(ATTRIBUTE(SLOTS_WEEK_DAY)); + helper_test_node_exists(ATTRIBUTE(HOUR_TZO)); + helper_test_node_exists(ATTRIBUTE(ENABLED), user_id_node); + helper_test_node_exists(ATTRIBUTE(ENABLE_ALL)); +} + +void test_schedule_entry_lock_get_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto slot_week_day_node = helper_test_and_get_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + + helper_test_get_set_frame_happy_case(SCHEDULE_ENTRY_TYPE_SUPPORTED_GET, + slot_week_day_node); +} + +void test_schedule_entry_lock_time_offset_get_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto hour_tzo_node = helper_test_and_get_node(ATTRIBUTE(HOUR_TZO)); + + helper_test_get_set_frame_happy_case(SCHEDULE_ENTRY_LOCK_TIME_OFFSET_GET_V2, + hour_tzo_node); +} + +void test_schedule_entry_lock_week_day_get_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto user_id_node = helper_test_and_get_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node + = user_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)); + auto set_action_node + = slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION)); + + uint8_t user_id = 0x01; + uint8_t slot_id = 0x02; + + zwave_frame week_day_get; + week_day_get.add(user_id); + week_day_get.add(slot_id); + + user_id_node.set_reported(user_id); + slot_id_node.set_reported(slot_id); + + helper_test_get_set_frame_happy_case(SCHEDULE_ENTRY_LOCK_WEEK_DAY_GET, + set_action_node, + week_day_get); +} + +void test_schedule_entry_lock_year_day_get_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto user_id_node = helper_test_and_get_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node + = user_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)); + auto set_action_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION)); + + uint8_t user_id = 0x01; + uint8_t slot_id = 0x02; + + zwave_frame year_day_get; + year_day_get.add(user_id); + year_day_get.add(slot_id); + + user_id_node.set_reported(user_id); + slot_id_node.set_reported(slot_id); + + helper_test_get_set_frame_happy_case(SCHEDULE_ENTRY_LOCK_YEAR_DAY_GET, + set_action_node, + year_day_get); +} + +void test_schedule_entry_lock_daily_repeating_get_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto user_id_node = helper_test_and_get_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node + = user_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID)); + auto set_action_node + = slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_SET_ACTION)); + + uint8_t user_id = 0x01; + uint8_t slot_id = 0x02; + + zwave_frame daily_repeating_get; + daily_repeating_get.add(user_id); + daily_repeating_get.add(slot_id); + + user_id_node.set_reported(user_id); + slot_id_node.set_reported(slot_id); + + helper_test_get_set_frame_happy_case( + SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_GET_V3, + set_action_node, + daily_repeating_get); +} + +void test_schedule_entry_lock_enable_set_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto user_id_node = helper_test_and_get_node(ATTRIBUTE(USER_IDENTIFIER)); + auto enable_node = user_id_node.emplace_node(ATTRIBUTE(ENABLED)); + uint8_t enable = 0x01; + + zwave_frame enable_set; + enable_set.add(enable); + enable_set.add(SCHEDULE_ENTRY_LOCK_ENABLE); + + // Test with desired value + user_id_node.set_reported(enable); + enable_node.set_desired(SCHEDULE_ENTRY_LOCK_ENABLE); + + helper_test_get_set_frame_happy_case(SCHEDULE_ENTRY_LOCK_ENABLE_SET, + enable_node, + enable_set); +} + +void test_schedule_entry_lock_enable_all_set_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto enable_all_node = helper_test_and_get_node(ATTRIBUTE(ENABLE_ALL)); + + // Test with desired value + enable_all_node.set_desired(SCHEDULE_ENTRY_LOCK_ENABLE); + helper_test_get_set_frame_happy_case(SCHEDULE_ENTRY_LOCK_ENABLE_ALL_SET, + enable_all_node, + {SCHEDULE_ENTRY_LOCK_ENABLE}); +} + +void test_schedule_entry_lock_week_day_set_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto user_id_node = helper_test_and_get_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node + = user_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)); + auto set_action_node + = slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_SET_ACTION)); + + uint8_t set_action = 0x01; + uint8_t user_id = 0x02; + uint8_t slot_id = 0x03; + uint8_t day_of_week = 0x04; + uint8_t start_hour = 0x05; + uint8_t start_minute = 0x06; + uint8_t stop_hour = 0x07; + uint8_t stop_minute = 0x08; + + zwave_frame week_day_set; + week_day_set.add(set_action); + week_day_set.add(user_id); + week_day_set.add(slot_id); + week_day_set.add(day_of_week); + week_day_set.add(start_hour); + week_day_set.add(start_minute); + week_day_set.add(stop_hour); + week_day_set.add(stop_minute); + + set_action_node.set_reported(set_action); + user_id_node.set_reported(user_id); + slot_id_node.set_reported(slot_id); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_DAY_OF_WEEK)) + .set_reported(day_of_week); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_START_HOUR)) + .set_reported(start_hour); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_START_MINUTE)) + .set_reported(start_minute); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_HOUR)) + .set_reported(stop_hour); + slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_MINUTE)) + .set_reported(stop_minute); + + helper_test_get_set_frame_happy_case(SCHEDULE_ENTRY_LOCK_WEEK_DAY_SET, + set_action_node, + week_day_set); +} + +void test_schedule_entry_lock_year_day_set_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto user_id_node = helper_test_and_get_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node + = user_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)); + auto set_action_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_SET_ACTION)); + + uint8_t set_action = 0x01; + uint8_t user_id = 0x02; + uint8_t slot_id = 0x03; + uint8_t start_year = 0x04; + uint8_t start_month = 0x05; + uint8_t start_day = 0x06; + uint8_t start_hour = 0x07; + uint8_t start_minute = 0x08; + uint8_t stop_year = 0x09; + uint8_t stop_month = 0x0a; + uint8_t stop_day = 0x0b; + uint8_t stop_hour = 0x0c; + uint8_t stop_minute = 0x0d; + + zwave_frame year_day_set; + year_day_set.add(set_action); + year_day_set.add(user_id); + year_day_set.add(slot_id); + year_day_set.add(start_year); + year_day_set.add(start_month); + year_day_set.add(start_day); + year_day_set.add(start_hour); + year_day_set.add(start_minute); + year_day_set.add(stop_year); + year_day_set.add(stop_month); + year_day_set.add(stop_day); + year_day_set.add(stop_hour); + year_day_set.add(stop_minute); + + set_action_node.set_reported(set_action); + user_id_node.set_reported(user_id); + slot_id_node.set_reported(slot_id); + + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR)) + .set_reported(start_year); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH)) + .set_reported(start_month); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY)) + .set_reported(start_day); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR)) + .set_reported(start_hour); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE)) + .set_reported(start_minute); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR)) + .set_reported(stop_year); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH)) + .set_reported(stop_month); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY)) + .set_reported(stop_day); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR)) + .set_reported(stop_hour); + slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE)) + .set_reported(stop_minute); + + helper_test_get_set_frame_happy_case(SCHEDULE_ENTRY_LOCK_YEAR_DAY_SET, + set_action_node, + year_day_set); +} + +void test_schedule_entry_lock_daily_repeating_set_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto user_id_node = helper_test_and_get_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node + = user_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID)); + auto set_action_node + = slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_SET_ACTION)); + + uint8_t set_action = 0x01; + uint8_t user_id = 0x02; + uint8_t slot_id = 0x03; + uint8_t week_day = 0x04; + uint8_t start_hour = 0x05; + uint8_t start_minute = 0x06; + uint8_t duration_hour = 0x07; + uint8_t duration_minute = 0x08; + + zwave_frame daily_repeating_set; + daily_repeating_set.add(set_action); + daily_repeating_set.add(user_id); + daily_repeating_set.add(slot_id); + daily_repeating_set.add(week_day); + daily_repeating_set.add(start_hour); + daily_repeating_set.add(start_minute); + daily_repeating_set.add(duration_hour); + daily_repeating_set.add(duration_minute); + + set_action_node.set_reported(set_action); + user_id_node.set_reported(user_id); + slot_id_node.set_reported(slot_id); + + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_WEEK_DAY)) + .set_reported(week_day); + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_START_HOUR)) + .set_reported(start_hour); + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_START_MINUTE)) + .set_reported(start_minute); + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_DURATION_HOUR)) + .set_reported(duration_hour); + slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_DURATION_MINUTE)) + .set_reported(duration_minute); + + helper_test_get_set_frame_happy_case( + SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SET_V3, + set_action_node, + daily_repeating_set); +} + +void test_schedule_entry_lock_time_offset_set_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto hour_tzo_node = helper_test_and_get_node(ATTRIBUTE(HOUR_TZO)); + auto endpoint_node = hour_tzo_node.parent(); + + // Set reported values for TZO and DST fields as per Z-Wave specs + hour_tzo_node.set_reported(15); // Hour TZO (7 bits) + + endpoint_node.emplace_node(ATTRIBUTE(SIGN_TZO)) + .set_reported(1); // Sign TZO (1 bit, 0 for positive) + endpoint_node.emplace_node(ATTRIBUTE(MINUTE_TZO)) + .set_reported(0x00); // Minute TZO (7 bits) + + endpoint_node.emplace_node(ATTRIBUTE(DST_OFFSET_SIGN)) + .set_reported(1); // DST Offset Sign (1 bit, 0 for positive) + endpoint_node.emplace_node(ATTRIBUTE(DST_OFFSET_MINUTE)) + .set_reported(15); // DST Offset Minute (7 bits) + + // Byte 1: Sign TZO (1 bit) + Hour TZO (7 bits) + // Byte 2: Minute TZO (7 bits) + // Byte 3: Sign Offset DST (1 bit) + Minute Offset DST (7 bits) + helper_test_get_set_frame_happy_case(SCHEDULE_ENTRY_LOCK_TIME_OFFSET_SET_V2, + hour_tzo_node, + {0b10001111, 0x00, 0b10001111}); +} + +void test_schedule_entry_lock_type_supported_report_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + auto slot_week_day_node = helper_test_and_get_node(ATTRIBUTE(SLOTS_WEEK_DAY)); + auto endpoint_node = slot_week_day_node.parent(); + auto slot_year_day_node + = endpoint_node.emplace_node(ATTRIBUTE(SLOTS_YEAR_DAY)); + auto slot_daily_repeating_node + = endpoint_node.emplace_node(ATTRIBUTE(NUMBER_OF_SLOTS_DAILY_REPEATING)); + uint8_t slot_week_day = 0x01; + uint8_t slot_year_day = 0x02; + uint8_t slot_daily_repeating = 0x03; + + zwave_frame type_supported_report; + type_supported_report.add(slot_week_day); + type_supported_report.add(slot_year_day); + type_supported_report.add(slot_daily_repeating); + + attribute_store_network_helper_get_endpoint_node_IgnoreAndReturn( + cpp_endpoint_id_node); + helper_test_report_frame(SCHEDULE_ENTRY_TYPE_SUPPORTED_REPORT, + type_supported_report); + TEST_ASSERT_EQUAL(slot_week_day, slot_week_day_node.reported()); + TEST_ASSERT_EQUAL(slot_year_day, slot_year_day_node.reported()); + TEST_ASSERT_EQUAL(slot_daily_repeating, + slot_daily_repeating_node.reported()); +} + +void test_schedule_entry_lock_time_offset_report_report_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + + auto hour_tzo_node = helper_test_and_get_node(ATTRIBUTE(HOUR_TZO)); + auto endpoint_node = hour_tzo_node.parent(); + auto sign_tzo_node = endpoint_node.emplace_node(ATTRIBUTE(SIGN_TZO)); + auto minute_tzo_node = endpoint_node.emplace_node(ATTRIBUTE(MINUTE_TZO)); + auto dst_offset_sign_node + = endpoint_node.emplace_node(ATTRIBUTE(DST_OFFSET_SIGN)); + auto dst_offset_minute_node + = endpoint_node.emplace_node(ATTRIBUTE(DST_OFFSET_MINUTE)); + + attribute_store_network_helper_get_endpoint_node_IgnoreAndReturn( + cpp_endpoint_id_node); + + helper_test_report_frame(SCHEDULE_ENTRY_LOCK_TIME_OFFSET_REPORT_V2, + {0b10001111, 0x00, 0b10001111}); + TEST_ASSERT_EQUAL(1, sign_tzo_node.reported()); + TEST_ASSERT_EQUAL(15, hour_tzo_node.reported()); + TEST_ASSERT_EQUAL(0x00, minute_tzo_node.reported()); + TEST_ASSERT_EQUAL(1, dst_offset_sign_node.reported()); + TEST_ASSERT_EQUAL(15, dst_offset_minute_node.reported()); +} + +void test_schedule_entry_lock_week_day_report_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + auto user_id_node = helper_test_and_get_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node + = user_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_SLOT_ID)); + auto day_of_week_node + = slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_DAY_OF_WEEK)); + auto start_hour_node + = slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_START_HOUR)); + auto start_minute_node + = slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_START_MINUTE)); + auto stop_hour_node + = slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_HOUR)); + auto stop_minute_node + = slot_id_node.emplace_node(ATTRIBUTE(WEEK_DAY_SCHEDULE_STOP_MINUTE)); + + uint8_t user_id = 0x01; + uint8_t slot_id = 0x02; + uint8_t day_of_week = 0x03; + uint8_t start_hour = 0x04; + uint8_t start_minute = 0x05; + uint8_t stop_hour = 0x06; + uint8_t stop_minute = 0x07; + + zwave_frame week_day_set; + week_day_set.add(user_id); + week_day_set.add(slot_id); + week_day_set.add(day_of_week); + week_day_set.add(start_hour); + week_day_set.add(start_minute); + week_day_set.add(stop_hour); + week_day_set.add(stop_minute); + + attribute_store_network_helper_get_endpoint_node_IgnoreAndReturn( + cpp_endpoint_id_node); + attribute_store_network_helper_get_unid_from_node_IgnoreAndReturn( + cpp_endpoint_id_node); + uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_week_day_report_command_Ignore(); + + helper_test_report_frame(SCHEDULE_ENTRY_LOCK_WEEK_DAY_REPORT, week_day_set); + TEST_ASSERT_EQUAL(user_id, user_id_node.reported()); + TEST_ASSERT_EQUAL(slot_id, slot_id_node.reported()); + TEST_ASSERT_EQUAL(day_of_week, day_of_week_node.reported()); + TEST_ASSERT_EQUAL(start_hour, start_hour_node.reported()); + TEST_ASSERT_EQUAL(start_minute, start_minute_node.reported()); + TEST_ASSERT_EQUAL(stop_hour, stop_hour_node.reported()); + TEST_ASSERT_EQUAL(stop_minute, stop_minute_node.reported()); +} + +void test_schedule_entry_lock_year_day_report_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + auto user_id_node = helper_test_and_get_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node + = user_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_SLOT_ID)); + auto start_year_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_YEAR)); + auto start_month_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MONTH)); + auto start_day_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_DAY)); + auto start_hour_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_HOUR)); + auto start_minute_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_START_MINUTE)); + auto stop_year_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_YEAR)); + auto stop_month_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MONTH)); + auto stop_day_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_DAY)); + auto stop_hour_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_HOUR)); + auto stop_minute_node + = slot_id_node.emplace_node(ATTRIBUTE(YEAR_DAY_SCHEDULE_STOP_MINUTE)); + + uint8_t user_id = 0x01; + uint8_t slot_id = 0x02; + uint8_t start_year = 0x03; + uint8_t start_month = 0x04; + uint8_t start_day = 0x05; + uint8_t start_hour = 0x06; + uint8_t start_minute = 0x07; + uint8_t stop_year = 0x08; + uint8_t stop_month = 0x09; + uint8_t stop_day = 0x0a; + uint8_t stop_hour = 0x0b; + uint8_t stop_minute = 0x0c; + + zwave_frame year_day_set; + year_day_set.add(user_id); + year_day_set.add(slot_id); + year_day_set.add(start_year); + year_day_set.add(start_month); + year_day_set.add(start_day); + year_day_set.add(start_hour); + year_day_set.add(start_minute); + year_day_set.add(stop_year); + year_day_set.add(stop_month); + year_day_set.add(stop_day); + year_day_set.add(stop_hour); + year_day_set.add(stop_minute); + + attribute_store_network_helper_get_endpoint_node_IgnoreAndReturn( + cpp_endpoint_id_node); + attribute_store_network_helper_get_unid_from_node_IgnoreAndReturn( + cpp_endpoint_id_node); + uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_year_day_report_command_Ignore(); + helper_test_report_frame(SCHEDULE_ENTRY_LOCK_YEAR_DAY_REPORT, year_day_set); + TEST_ASSERT_EQUAL(user_id, user_id_node.reported()); + TEST_ASSERT_EQUAL(slot_id, slot_id_node.reported()); + TEST_ASSERT_EQUAL(start_year, start_year_node.reported()); + TEST_ASSERT_EQUAL(start_month, start_month_node.reported()); + TEST_ASSERT_EQUAL(start_day, start_day_node.reported()); + TEST_ASSERT_EQUAL(start_hour, start_hour_node.reported()); + TEST_ASSERT_EQUAL(start_minute, start_minute_node.reported()); + TEST_ASSERT_EQUAL(stop_year, stop_year_node.reported()); + TEST_ASSERT_EQUAL(stop_month, stop_month_node.reported()); + TEST_ASSERT_EQUAL(stop_day, stop_day_node.reported()); + TEST_ASSERT_EQUAL(stop_hour, stop_hour_node.reported()); + TEST_ASSERT_EQUAL(stop_minute, stop_minute_node.reported()); +} + +void test_schedule_entry_lock_daily_repeating_report_happy_case() +{ + helper_set_version(SCHEDULE_ENTRY_LOCK_VERSION_V3); + auto user_id_node = helper_test_and_get_node(ATTRIBUTE(USER_IDENTIFIER)); + auto slot_id_node + = user_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_SCHEDULE_SLOT_ID)); + auto week_day_node + = slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_WEEK_DAY)); + auto start_hour_node + = slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_START_HOUR)); + auto start_minute_node + = slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_START_MINUTE)); + auto duration_hour_node + = slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_DURATION_HOUR)); + auto duration_minute_node + = slot_id_node.emplace_node(ATTRIBUTE(DAILY_REPEATING_DURATION_MINUTE)); + + uint8_t user_id = 0x01; + uint8_t slot_id = 0x02; + uint8_t week_day = 0x03; + uint8_t start_hour = 0x04; + uint8_t start_minute = 0x05; + uint8_t duration_hour = 0x06; + uint8_t duration_minute = 0x07; + + zwave_frame daily_repeating_set; + daily_repeating_set.add(user_id); + daily_repeating_set.add(slot_id); + daily_repeating_set.add(week_day); + daily_repeating_set.add(start_hour); + daily_repeating_set.add(start_minute); + daily_repeating_set.add(duration_hour); + daily_repeating_set.add(duration_minute); + + attribute_store_network_helper_get_endpoint_node_IgnoreAndReturn( + cpp_endpoint_id_node); + attribute_store_network_helper_get_unid_from_node_IgnoreAndReturn( + cpp_endpoint_id_node); + uic_mqtt_dotdot_unify_schedule_entry_lock_publish_generated_daily_repeating_report_command_Ignore(); + + helper_test_report_frame(SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_REPORT_V3, + daily_repeating_set); + TEST_ASSERT_EQUAL(user_id, user_id_node.reported()); + TEST_ASSERT_EQUAL(slot_id, slot_id_node.reported()); + TEST_ASSERT_EQUAL(week_day, week_day_node.reported()); + TEST_ASSERT_EQUAL(start_hour, start_hour_node.reported()); + TEST_ASSERT_EQUAL(start_minute, start_minute_node.reported()); + TEST_ASSERT_EQUAL(duration_hour, duration_hour_node.reported()); + TEST_ASSERT_EQUAL(duration_minute, duration_minute_node.reported()); +} + +} // extern "C"