Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ 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
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(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
******************************************************************************
* 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

// 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

/**
* @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);

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);

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

#endif //SCHEDULE_ENTRY_LOCK_SERVER_H
/** @} end schedule_entry_lock_server */
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/******************************************************************************
* # License
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
******************************************************************************
* 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 <string>
#include <stdlib.h>
#include <vector>

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<attribute_store_type_t> 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<uint8_t>();

// 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<int32_t>();
}
// 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<uint8_t>(sensor_scale_node.reported<int32_t>());
}

// 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<uint32_t>(sensor_values_attributes.size()));

return SL_STATUS_OK;
}
Loading
Loading