Skip to content

Commit 1ddf30c

Browse files
committed
Merge branch 'feature/timezone' into 'master'
esp_rmaker_time_sync: Add support for POSIX timezones See merge request app-frameworks/esp-rainmaker!155
2 parents 2e82d0a + 90354df commit 1ddf30c

11 files changed

+919
-9
lines changed

components/esp_rainmaker/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ set(core_srcs "src/core/esp_rmaker_core.c"
66
"src/core/esp_rmaker_node_config.c"
77
"src/core/esp_rmaker_client_data.c"
88
"src/core/esp_rmaker_time_sync.c"
9+
"src/core/esp_rmaker_timezone.c"
910
"src/core/esp_rmaker_storage.c"
1011
"src/core/esp_rmaker_user_mapping.pb-c.c"
1112
"src/core/esp_rmaker_utils.c"

components/esp_rainmaker/Kconfig.projbuild

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ menu "ESP RainMaker Config"
8585
default 1 if ESP_RMAKER_MQTT_PORT_443
8686
default 2 if ESP_RMAKER_MQTT_PORT_8883
8787

88+
config ESP_RMAKER_DEF_TIMEZONE
89+
string "Default Timezone"
90+
default ""
91+
help
92+
Default Timezone to use. Eg. "Asia/Shanghai", "America/Los_Angeles".
93+
Check documentation for complete list of valid values. This value
94+
will be used only if no timezone is set using the C APIs.
95+
8896
config ESP_RMAKER_SNTP_SERVER_NAME
8997
string "ESP RainMaker SNTP Server Name"
9098
default "pool.ntp.org"

components/esp_rainmaker/include/esp_rmaker_standard_params.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ extern "C"
4141
#define ESP_RMAKER_DEF_OTA_STATUS_NAME "status"
4242
#define ESP_RMAKER_DEF_OTA_INFO_NAME "info"
4343
#define ESP_RMAKER_DEF_OTA_URL_NAME "url"
44+
#define ESP_RMAKER_DEF_TIMEZONE_NAME "tz"
45+
#define ESP_RMAKER_DEF_TIMEZONE_POSIX_NAME "tz_posix"
4446

4547
/**
4648
* Create standard name param
@@ -216,6 +218,31 @@ esp_rmaker_param_t *esp_rmaker_ota_info_param_create(const char *param_name);
216218
*/
217219
esp_rmaker_param_t *esp_rmaker_ota_url_param_create(const char *param_name);
218220

221+
/**
222+
* Create standard Timezone param
223+
*
224+
* This will create the standard timezone parameter.
225+
*
226+
* @param[in] param_name Name of the parameter
227+
* @param[in] val Default Value of the parameter (Eg. "Asia/Shanghai"). Can be kept NULL.
228+
*
229+
* @return Parameter handle on success.
230+
* @return NULL in case of failures.
231+
*/
232+
esp_rmaker_param_t *esp_rmaker_timezone_param_create(const char *param_name, const char *val);
233+
234+
/**
235+
* Create standard POSIX Timezone param
236+
*
237+
* This will create the standard posix timezone parameter.
238+
*
239+
* @param[in] param_name Name of the parameter
240+
* @param[in] val Default Value of the parameter (Eg. "CST-8"). Can be kept NULL.
241+
*
242+
* @return Parameter handle on success.
243+
* @return NULL in case of failures.
244+
*/
245+
esp_rmaker_param_t *esp_rmaker_timezone_posix_param_create(const char *param_name, const char *val);
219246
#ifdef __cplusplus
220247
}
221248
#endif

components/esp_rainmaker/include/esp_rmaker_standard_services.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@ extern "C"
3737
*/
3838
esp_rmaker_device_t *esp_rmaker_ota_service_create(const char *serv_name, void *priv_data);
3939

40+
/** Create a standard OTA service
41+
*
42+
* This creates an OTA service with the mandatory parameters. The default parameter names will be used.
43+
* Refer \ref esp_rmaker_standard_params.h for default names.
44+
*
45+
* @param[in] serv_name The unique service name
46+
* @param[in] timezone Default value of timezone string (Eg. "Asia/Shanghai"). Can be kept NULL.
47+
* @param[in] timezone_posix Default value of posix timezone string (Eg. "CST-8"). Can be kept NULL.
48+
* @param[in] priv_data (Optional) Private data associated with the service. This should stay
49+
* allocated throughout the lifetime of the service.
50+
*
51+
* @return service_handle on success.
52+
* @return NULL in case of any error.
53+
*/
54+
esp_rmaker_device_t *esp_rmaker_time_service_create(const char *serv_name, const char *timezone,
55+
const char *timezone_posix, void *priv_data);
56+
4057
#ifdef __cplusplus
4158
}
4259
#endif

components/esp_rainmaker/include/esp_rmaker_standard_types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ extern "C"
4141
#define ESP_RMAKER_PARAM_OTA_STATUS "esp.param.ota_status"
4242
#define ESP_RMAKER_PARAM_OTA_INFO "esp.param.ota_info"
4343
#define ESP_RMAKER_PARAM_OTA_URL "esp.param.ota_url"
44-
44+
#define ESP_RMAKER_PARAM_TIMEZONE "esp.param.tz"
45+
#define ESP_RMAKER_PARAM_TIMEZONE_POSIX "esp.param.tz_posix"
4546

4647
/********** STANDARD DEVICE TYPES **********/
4748

@@ -52,6 +53,7 @@ extern "C"
5253

5354
/********** STANDARD SERVICE TYPES **********/
5455
#define ESP_RMAKER_SERVICE_OTA "esp.service.ota"
56+
#define ESP_RMAKER_SERVICE_TIME "esp.service.time"
5557

5658
#ifdef __cplusplus
5759
}

components/esp_rainmaker/include/esp_rmaker_utils.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414
#pragma once
1515
#include <stdint.h>
16+
#include <sntp.h>
1617
#include <esp_err.h>
1718

1819
#ifdef __cplusplus
@@ -23,6 +24,12 @@ extern "C"
2324
typedef struct esp_rmaker_time_config {
2425
/** If not specified, then 'CONFIG_ESP_RMAKER_SNTP_SERVER_NAME' is used as the SNTP server. */
2526
char *sntp_server_name;
27+
/** Optional callback to invoke, whenever time is synchronised. This will be called
28+
* periodically as per the SNTP polling interval (which is 60min by default).
29+
* If kept NULL, the default callback will be invoked, which will just print the
30+
* current local time.
31+
*/
32+
sntp_sync_time_cb_t sync_time_cb;
2633
} esp_rmaker_time_config_t;
2734

2835
/** Reboot the chip after a delay
@@ -104,6 +111,64 @@ bool esp_rmaker_time_check(void);
104111
*/
105112
esp_err_t esp_rmaker_time_wait_for_sync(uint32_t ticks_to_wait);
106113

114+
/** Set POSIX timezone
115+
*
116+
* Set the timezone (TZ environment variable) as per the POSIX format
117+
* specified in the [GNU libc documentation](https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html).
118+
* Eg. For China: "CST-8"
119+
* For US Pacific Time (including daylight saving information): "PST8PDT,M3.2.0,M11.1.0"
120+
*
121+
* @param[in] tz_posix NULL terminated TZ POSIX string
122+
*
123+
* @return ESP_OK on success
124+
* @return error on failure
125+
*/
126+
esp_err_t esp_rmaker_time_set_timezone_posix(const char *tz_posix);
127+
128+
/** Set timezone location string
129+
*
130+
* Set the timezone as a user friendly location string.
131+
* Check [here](https://rainmaker.espressif.com/docs/time-service.html) for a list of valid values.
132+
*
133+
* Eg. For China: "Asia/Shanghai"
134+
* For US Pacific Time: "America/Los_Angeles"
135+
*
136+
* @note Setting timezone using this API internally also sets the POSIX timezone string.
137+
*
138+
* @param[in] tz NULL terminated Timezone location string
139+
*
140+
* @return ESP_OK on success
141+
* @return error on failure
142+
*/
143+
esp_err_t esp_rmaker_time_set_timezone(const char *tz);
144+
145+
/** Enable Timezone Service
146+
*
147+
* This enables the ESP RainMaker standard timezone service which can be used to set
148+
* timezone, either in POSIX or location string format. Please refer the specifications
149+
* for additional details.
150+
*
151+
* @return ESP_OK on success
152+
* @return error on failure
153+
*/
154+
esp_err_t esp_rmaker_timezone_service_enable(void);
155+
156+
/** Get printable local time string
157+
*
158+
* Get a printable local time string, with information of timezone and Daylight Saving.
159+
* Eg. "Tue Sep 1 09:04:38 2020 -0400[EDT], DST: Yes"
160+
* "Tue Sep 1 21:04:04 2020 +0800[CST], DST: No"
161+
*
162+
*
163+
* @param[out] buf Pointer to a pre-allocated buffer into which the time string will
164+
* be populated.
165+
* @param[in] buf_len Length of the above buffer.
166+
*
167+
* @return ESP_OK on success
168+
* @return error on failure
169+
*/
170+
esp_err_t esp_rmaker_get_local_time_str(char *buf, size_t buf_len);
171+
107172
#ifdef __cplusplus
108173
}
109174
#endif

components/esp_rainmaker/src/console/esp_rmaker_commands.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
#include <esp_rmaker_core.h>
3535
#include <esp_rmaker_user_mapping.h>
36+
#include <esp_rmaker_utils.h>
3637

3738
#include <esp_rmaker_console_internal.h>
3839

@@ -352,11 +353,61 @@ static void register_wifi_prov()
352353
esp_console_cmd_register(&cmd);
353354
}
354355

356+
static int local_time_cli_handler(int argc, char *argv[])
357+
{
358+
char local_time[64];
359+
if (esp_rmaker_get_local_time_str(local_time, sizeof(local_time)) == ESP_OK) {
360+
printf("%s: Current local time: %s\n", TAG, local_time);
361+
} else {
362+
printf("%s: Current local time (truncated): %s\n", TAG, local_time);
363+
}
364+
return ESP_OK;
365+
}
366+
367+
static int tz_set_cli_handler(int argc, char *argv[])
368+
{
369+
if (argc < 2) {
370+
printf("%s: Invalid Usage.\n", TAG);
371+
return ESP_ERR_INVALID_ARG;
372+
}
373+
if (strcmp(argv[1], "posix") == 0) {
374+
if (argv[2]) {
375+
esp_rmaker_time_set_timezone_posix(argv[2]);
376+
} else {
377+
printf("%s: Invalid Usage.\n", TAG);
378+
return ESP_ERR_INVALID_ARG;
379+
}
380+
} else {
381+
esp_rmaker_time_set_timezone(argv[1]);
382+
}
383+
return ESP_OK;
384+
}
385+
386+
static void register_time_commands()
387+
{
388+
const esp_console_cmd_t local_time_cmd = {
389+
.command = "local-time",
390+
.help = "Get the local time of device.",
391+
.func = &local_time_cli_handler,
392+
};
393+
ESP_LOGI(TAG, "Registering command: %s", local_time_cmd.command);
394+
esp_console_cmd_register(&local_time_cmd);
395+
396+
const esp_console_cmd_t tz_set_cmd = {
397+
.command = "tz-set",
398+
.help = "Set Timezone. Usage: tz-set [posix] <tz_string>.",
399+
.func = &tz_set_cli_handler,
400+
};
401+
ESP_LOGI(TAG, "Registering command: %s", tz_set_cmd.command);
402+
esp_console_cmd_register(&tz_set_cmd);
403+
}
404+
355405
void register_commands()
356406
{
357407
register_generic_debug_commands();
358408
register_reset_to_factory();
359409
register_user_node_mapping();
360410
register_get_node_id();
361411
register_wifi_prov();
412+
register_time_commands();
362413
}

0 commit comments

Comments
 (0)