Skip to content

Commit af84a42

Browse files
Thirsrinrzr
authored andcommitted
uic: zpc: UIC-3277:Time Parameters CC
(cherry picked from commit 320f92bf980778fcdb5f9dc4f97fba2b24233469) Forwarded: #11 Signed-off-by: Philippe Coval <philippe.coval@silabs.com>
1 parent 30afce6 commit af84a42

9 files changed

+525
-15
lines changed

applications/zpc/components/zwave_command_classes/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ add_library(
5252
src/zwave_command_class_thermostat_fan_state.c
5353
src/zwave_command_class_thermostat_setpoint.cpp
5454
src/zwave_command_class_thermostat_operating_state.c
55+
src/zwave_command_class_time_parameters.cpp
5556
src/zwave_command_class_time.c
5657
src/zwave_command_class_user_code.c
5758
src/zwave_command_class_version.c

applications/zpc/components/zwave_command_classes/platform/platform_date_time.h

+7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef PLATFORM_DATE_TIME_H
1515
#define PLATFORM_DATE_TIME_H
1616

17+
#include "sl_status.h"
1718
typedef struct {
1819
int sec; /* seconds after the minute [0-60] */
1920
int min; /* minutes after the hour [0-59] */
@@ -28,4 +29,10 @@ typedef struct {
2829
*/
2930
date_time_t platform_get_date_time();
3031

32+
/**
33+
* @brief platform abstraction for setting local system time.
34+
*/
35+
36+
sl_status_t platform_set_date_time(const date_time_t *new_time);
37+
3138
#endif
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,57 @@
11
#include "platform_date_time.h"
22
#include <time.h>
3+
#include <sys/time.h>
4+
5+
// Static variable to store time offset
6+
static time_t time_offset = 0;
37

48
date_time_t platform_get_date_time()
59
{
6-
date_time_t return_time = {0};
7-
time_t current_time = {0};
8-
struct tm local_time = {0};
10+
date_time_t return_time = {0};
11+
time_t current_time;
12+
current_time = time(NULL);
13+
14+
current_time += time_offset;
15+
struct tm *local_time = localtime(&current_time);
16+
17+
if (local_time == NULL) {
18+
return return_time;
19+
}
20+
21+
// Populate return_time with the adjusted values
22+
return_time.sec = local_time->tm_sec;
23+
return_time.min = local_time->tm_min;
24+
return_time.hour = local_time->tm_hour;
25+
return_time.day = local_time->tm_mday;
26+
return_time.mon = local_time->tm_mon;
27+
return_time.year = local_time->tm_year;
928

10-
time(&current_time);
11-
if (!localtime_r(&current_time, &local_time))
1229
return return_time;
30+
}
31+
32+
sl_status_t platform_set_date_time(const date_time_t *new_time)
33+
{
34+
struct tm tm = {0};
35+
36+
// Populate the tm structure with the values from new_time
37+
tm.tm_year = new_time->year; // tm_year is years since 1900
38+
tm.tm_mon = new_time->mon; // tm_mon is 0-11
39+
tm.tm_mday = new_time->day;
40+
tm.tm_hour = new_time->hour;
41+
tm.tm_min = new_time->min;
42+
tm.tm_sec = new_time->sec;
43+
44+
// Convert tm structure to time_t
45+
time_t time_in_secs = mktime(&tm);
46+
if (time_in_secs == (time_t)(-1)) {
47+
return SL_STATUS_FAIL;
48+
}
49+
50+
// Get the current system time
51+
time_t real_time_in_secs = time(NULL);
52+
53+
// Calculate the time offset
54+
time_offset = time_in_secs - real_time_in_secs;
1355

14-
return_time.sec = local_time.tm_sec;
15-
return_time.min = local_time.tm_min;
16-
return_time.hour = local_time.tm_hour;
17-
return_time.day = local_time.tm_mday;
18-
return_time.mon = local_time.tm_mon;
19-
return_time.year = local_time.tm_year;
20-
return return_time;
56+
return SL_STATUS_OK; // Return success status
2157
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/******************************************************************************
2+
* # License
3+
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
4+
******************************************************************************
5+
* The licensor of this software is Silicon Laboratories Inc. Your use of this
6+
* software is governed by the terms of Silicon Labs Master Software License
7+
* Agreement (MSLA) available at
8+
* www.silabs.com/about-us/legal/master-software-license-agreement. This
9+
* software is distributed to you in Source Code format and is governed by the
10+
* sections of the MSLA applicable to Source Code.
11+
*
12+
*****************************************************************************/
13+
14+
#include "zwave_command_class_time_parameters.h"
15+
#include "ZW_classcmd.h"
16+
#include "zwave_command_handler.h"
17+
#include "zwave_command_class_indices.h"
18+
#include "zwave_command_classes_utils.h"
19+
#include "assert.h"
20+
21+
#ifdef __cplusplus
22+
extern "C" {
23+
#endif
24+
25+
#include <time.h>
26+
#include "platform_date_time.h"
27+
28+
#include "zwave_controller_connection_info.h"
29+
#include "zwave_tx.h"
30+
31+
///////////////////////////////////////////////////////////////////////////////
32+
// Private functions, used to handle individual incoming commands.
33+
///////////////////////////////////////////////////////////////////////////////
34+
35+
/**
36+
* @brief Command handler for the Time parameters Get command.
37+
*
38+
* The Gateway will send return a Time Report frame containing
39+
* the current time (year, month, day, hours, minutes and seconds).
40+
*
41+
* @param connection_info Info about the connection properties of this frame.
42+
* @returns sl_status_t indicating the outcome of returning the time.
43+
*/
44+
static sl_status_t zwave_command_class_time_parameters_get(
45+
const zwave_controller_connection_info_t *connection_info)
46+
{
47+
if (connection_info && connection_info->local.is_multicast) {
48+
return SL_STATUS_OK;
49+
}
50+
51+
date_time_t time = platform_get_date_time();
52+
ZW_TIME_PARAMETERS_REPORT_FRAME report
53+
= {.cmdClass = COMMAND_CLASS_TIME_PARAMETERS,
54+
.cmd = TIME_PARAMETERS_REPORT,
55+
.year1 = static_cast<uint8_t>((time.year + 1900) >> 8), //MSB
56+
.year2 = static_cast<uint8_t>((time.year + 1900) & 0xFF), //LSB
57+
.month = static_cast<uint8_t>(time.mon + 1),
58+
.day = static_cast<uint8_t>(time.day),
59+
.hourUtc = static_cast<uint8_t>(time.hour & 0xF),
60+
.minuteUtc = static_cast<uint8_t>(time.min),
61+
.secondUtc = static_cast<uint8_t>(time.sec)};
62+
63+
return zwave_command_class_send_report(connection_info,
64+
sizeof(report),
65+
(uint8_t *)&report);
66+
}
67+
68+
sl_status_t
69+
zwave_command_class_time_parameters_set(const uint8_t *frame_data,
70+
uint16_t frame_length)
71+
{
72+
if (frame_length < sizeof(ZW_TIME_PARAMETERS_SET_FRAME)) {
73+
return SL_STATUS_FAIL;
74+
}
75+
76+
// Extract and parse the time from the frame data
77+
uint16_t year = (frame_data[2] << 8) | frame_data[3];
78+
uint8_t month = frame_data[4];
79+
uint8_t day = frame_data[5];
80+
uint8_t hour = frame_data[6];
81+
uint8_t minute = frame_data[7];
82+
uint8_t second = frame_data[8];
83+
84+
// Create a date_time_t structure and populate it
85+
date_time_t new_time;
86+
new_time.year = year - 1900;
87+
new_time.mon = month - 1;
88+
new_time.day = day;
89+
new_time.hour = hour;
90+
new_time.min = minute;
91+
new_time.sec = second;
92+
93+
// Update the system time
94+
if (platform_set_date_time(&new_time) != SL_STATUS_OK) {
95+
return SL_STATUS_FAIL;
96+
}
97+
98+
return SL_STATUS_OK;
99+
}
100+
101+
///////////////////////////////////////////////////////////////////////////////
102+
// Public interface functions
103+
///////////////////////////////////////////////////////////////////////////////
104+
sl_status_t zwave_command_class_time_parameters_support_handler(
105+
const zwave_controller_connection_info_t *connection_info,
106+
const uint8_t *frame_data,
107+
uint16_t frame_length)
108+
{
109+
if (frame_length <= COMMAND_INDEX) {
110+
return SL_STATUS_NOT_SUPPORTED;
111+
}
112+
113+
assert(frame_data[COMMAND_CLASS_INDEX] == COMMAND_CLASS_TIME_PARAMETERS);
114+
115+
switch (frame_data[COMMAND_INDEX]) {
116+
case TIME_PARAMETERS_GET:
117+
return zwave_command_class_time_parameters_get(connection_info);
118+
case TIME_PARAMETERS_SET:
119+
return zwave_command_class_time_parameters_set(frame_data, frame_length);
120+
121+
default:
122+
return SL_STATUS_NOT_SUPPORTED;
123+
}
124+
}
125+
126+
sl_status_t zwave_command_class_time_parameters_init()
127+
{
128+
zwave_command_handler_t handler = {0};
129+
handler.support_handler
130+
= &zwave_command_class_time_parameters_support_handler;
131+
handler.control_handler = NULL;
132+
handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NONE;
133+
handler.manual_security_validation = false;
134+
handler.command_class = COMMAND_CLASS_TIME_PARAMETERS;
135+
handler.version = TIME_PARAMETERS_VERSION;
136+
handler.command_class_name = "Time Parameters";
137+
138+
return zwave_command_handler_register_handler(handler);
139+
}
140+
141+
#ifdef __cplusplus
142+
}
143+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/******************************************************************************
2+
* # License
3+
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
4+
******************************************************************************
5+
* The licensor of this software is Silicon Laboratories Inc. Your use of this
6+
* software is governed by the terms of Silicon Labs Master Software License
7+
* Agreement (MSLA) available at
8+
* www.silabs.com/about-us/legal/master-software-license-agreement. This
9+
* software is distributed to you in Source Code format and is governed by the
10+
* sections of the MSLA applicable to Source Code.
11+
*
12+
*****************************************************************************/
13+
14+
#ifndef ZWAVE_COMMAND_CLASS_TIME_PARAMETERS_H
15+
#define ZWAVE_COMMAND_CLASS_TIME_PARAMETERS_H
16+
17+
#include "sl_status.h"
18+
19+
#ifdef __cplusplus
20+
extern "C" {
21+
#endif
22+
23+
#include "zwave_rx.h"
24+
25+
/**
26+
* @brief This function initialize the time parameters Command Class handler
27+
*
28+
* @return SL_STATUS_OK on success, any other error code for an error.
29+
*/
30+
sl_status_t zwave_command_class_time_parameters_init();
31+
32+
/**
33+
* @brief Handles incoming time parameters encapsulated commands
34+
*
35+
* @param connection_info Info about the connection properties of this frame.
36+
* @param frame_data The data payload of this frame.
37+
* @param frame_length The length of this frame.
38+
* @returns sl_status_t representing the outcome of receiving the frame
39+
* In case where the command is controlled, it should be set to SL_STATUS_OK,
40+
* even when encountering some parsing errors
41+
* In case where the command is supported, it should be set to the @ref sl_status_t
42+
* corresponding to the correct time Status code. Refer to @ref zwave_command_handler_t
43+
*/
44+
sl_status_t zwave_command_class_time_parameters_support_handler(
45+
const zwave_controller_connection_info_t *connection_info,
46+
const uint8_t *frame_data,
47+
uint16_t frame_length);
48+
49+
50+
/**
51+
* @brief Handles time parameters set commands
52+
*
53+
* @param frame_data The data payload of this frame.
54+
* @param frame_length The length of this frame.
55+
* @returns SL_STATUS_OK on success, any other error code for an error.
56+
*/
57+
58+
sl_status_t
59+
zwave_command_class_time_parameters_set(const uint8_t *frame_data,
60+
uint16_t frame_length);
61+
62+
#ifdef __cplusplus
63+
}
64+
#endif
65+
66+
#endif //ZWAVE_COMMAND_CLASS_TIME_PARAMETERS_H
67+
/** @} end zwave_command_class_time_parameters */

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

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "zwave_command_class_thermostat_operating_state.h"
4747
#include "zwave_command_class_version.h"
4848
#include "zwave_command_class_wake_up.h"
49+
#include "zwave_command_class_time_parameters.h"
4950
#include "zwave_command_class_time.h"
5051
#include "zwave_command_class_user_code.h"
5152
#include "zwave_command_class_basic.h"
@@ -119,6 +120,7 @@ sl_status_t zwave_command_classes_init()
119120
status |= zwave_command_class_thermostat_fan_state_init();
120121
status |= zwave_command_class_thermostat_setpoint_init();
121122
status |= zwave_command_class_thermostat_operating_state_init();
123+
status |= zwave_command_class_time_parameters_init();
122124
status |= zwave_command_class_time_init();
123125
status |= zwave_command_class_transport_service_init();
124126
status |= zwave_command_class_user_code_init();

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

+12-3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ target_add_unittest(
4646
zwave_command_class_test_helpers
4747
${MOCK_LIBS})
4848

49+
target_add_unittest(
50+
zwave_command_classes
51+
NAME
52+
zwave_command_class_time_parameters_test
53+
SOURCES
54+
zwave_command_class_time_parameters_test.c
55+
DEPENDS
56+
zwave_command_class_test_helpers
57+
${MOCK_LIBS})
58+
4959
target_add_unittest(
5060
zwave_command_classes
5161
NAME
@@ -796,7 +806,7 @@ target_add_unittest(
796806
uic_attribute_resolver_mock
797807
zpc_attribute_resolver_mock
798808
)
799-
809+
800810
# Humidity Control Mode test
801811
target_add_unittest(
802812
zwave_command_classes
@@ -841,5 +851,4 @@ target_add_unittest(
841851
uic_attribute_resolver_mock
842852
zpc_attribute_resolver_mock
843853
uic_dotdot_mqtt_mock)
844-
845-
854+

0 commit comments

Comments
 (0)