mirror of
https://github.com/espressif/esp-rainmaker.git
synced 2026-01-15 04:18:10 +00:00
Merge branch 'feature/timezone' into 'master'
esp_rmaker_time_sync: Add support for POSIX timezones See merge request app-frameworks/esp-rainmaker!155
This commit is contained in:
@@ -6,6 +6,7 @@ set(core_srcs "src/core/esp_rmaker_core.c"
|
||||
"src/core/esp_rmaker_node_config.c"
|
||||
"src/core/esp_rmaker_client_data.c"
|
||||
"src/core/esp_rmaker_time_sync.c"
|
||||
"src/core/esp_rmaker_timezone.c"
|
||||
"src/core/esp_rmaker_storage.c"
|
||||
"src/core/esp_rmaker_user_mapping.pb-c.c"
|
||||
"src/core/esp_rmaker_utils.c"
|
||||
|
||||
@@ -85,6 +85,14 @@ menu "ESP RainMaker Config"
|
||||
default 1 if ESP_RMAKER_MQTT_PORT_443
|
||||
default 2 if ESP_RMAKER_MQTT_PORT_8883
|
||||
|
||||
config ESP_RMAKER_DEF_TIMEZONE
|
||||
string "Default Timezone"
|
||||
default ""
|
||||
help
|
||||
Default Timezone to use. Eg. "Asia/Shanghai", "America/Los_Angeles".
|
||||
Check documentation for complete list of valid values. This value
|
||||
will be used only if no timezone is set using the C APIs.
|
||||
|
||||
config ESP_RMAKER_SNTP_SERVER_NAME
|
||||
string "ESP RainMaker SNTP Server Name"
|
||||
default "pool.ntp.org"
|
||||
|
||||
@@ -41,6 +41,8 @@ extern "C"
|
||||
#define ESP_RMAKER_DEF_OTA_STATUS_NAME "status"
|
||||
#define ESP_RMAKER_DEF_OTA_INFO_NAME "info"
|
||||
#define ESP_RMAKER_DEF_OTA_URL_NAME "url"
|
||||
#define ESP_RMAKER_DEF_TIMEZONE_NAME "tz"
|
||||
#define ESP_RMAKER_DEF_TIMEZONE_POSIX_NAME "tz_posix"
|
||||
|
||||
/**
|
||||
* Create standard name param
|
||||
@@ -216,6 +218,31 @@ esp_rmaker_param_t *esp_rmaker_ota_info_param_create(const char *param_name);
|
||||
*/
|
||||
esp_rmaker_param_t *esp_rmaker_ota_url_param_create(const char *param_name);
|
||||
|
||||
/**
|
||||
* Create standard Timezone param
|
||||
*
|
||||
* This will create the standard timezone parameter.
|
||||
*
|
||||
* @param[in] param_name Name of the parameter
|
||||
* @param[in] val Default Value of the parameter (Eg. "Asia/Shanghai"). Can be kept NULL.
|
||||
*
|
||||
* @return Parameter handle on success.
|
||||
* @return NULL in case of failures.
|
||||
*/
|
||||
esp_rmaker_param_t *esp_rmaker_timezone_param_create(const char *param_name, const char *val);
|
||||
|
||||
/**
|
||||
* Create standard POSIX Timezone param
|
||||
*
|
||||
* This will create the standard posix timezone parameter.
|
||||
*
|
||||
* @param[in] param_name Name of the parameter
|
||||
* @param[in] val Default Value of the parameter (Eg. "CST-8"). Can be kept NULL.
|
||||
*
|
||||
* @return Parameter handle on success.
|
||||
* @return NULL in case of failures.
|
||||
*/
|
||||
esp_rmaker_param_t *esp_rmaker_timezone_posix_param_create(const char *param_name, const char *val);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -37,6 +37,23 @@ extern "C"
|
||||
*/
|
||||
esp_rmaker_device_t *esp_rmaker_ota_service_create(const char *serv_name, void *priv_data);
|
||||
|
||||
/** Create a standard OTA service
|
||||
*
|
||||
* This creates an OTA service with the mandatory parameters. The default parameter names will be used.
|
||||
* Refer \ref esp_rmaker_standard_params.h for default names.
|
||||
*
|
||||
* @param[in] serv_name The unique service name
|
||||
* @param[in] timezone Default value of timezone string (Eg. "Asia/Shanghai"). Can be kept NULL.
|
||||
* @param[in] timezone_posix Default value of posix timezone string (Eg. "CST-8"). Can be kept NULL.
|
||||
* @param[in] priv_data (Optional) Private data associated with the service. This should stay
|
||||
* allocated throughout the lifetime of the service.
|
||||
*
|
||||
* @return service_handle on success.
|
||||
* @return NULL in case of any error.
|
||||
*/
|
||||
esp_rmaker_device_t *esp_rmaker_time_service_create(const char *serv_name, const char *timezone,
|
||||
const char *timezone_posix, void *priv_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,8 @@ extern "C"
|
||||
#define ESP_RMAKER_PARAM_OTA_STATUS "esp.param.ota_status"
|
||||
#define ESP_RMAKER_PARAM_OTA_INFO "esp.param.ota_info"
|
||||
#define ESP_RMAKER_PARAM_OTA_URL "esp.param.ota_url"
|
||||
|
||||
#define ESP_RMAKER_PARAM_TIMEZONE "esp.param.tz"
|
||||
#define ESP_RMAKER_PARAM_TIMEZONE_POSIX "esp.param.tz_posix"
|
||||
|
||||
/********** STANDARD DEVICE TYPES **********/
|
||||
|
||||
@@ -52,6 +53,7 @@ extern "C"
|
||||
|
||||
/********** STANDARD SERVICE TYPES **********/
|
||||
#define ESP_RMAKER_SERVICE_OTA "esp.service.ota"
|
||||
#define ESP_RMAKER_SERVICE_TIME "esp.service.time"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <sntp.h>
|
||||
#include <esp_err.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -23,6 +24,12 @@ extern "C"
|
||||
typedef struct esp_rmaker_time_config {
|
||||
/** If not specified, then 'CONFIG_ESP_RMAKER_SNTP_SERVER_NAME' is used as the SNTP server. */
|
||||
char *sntp_server_name;
|
||||
/** Optional callback to invoke, whenever time is synchronised. This will be called
|
||||
* periodically as per the SNTP polling interval (which is 60min by default).
|
||||
* If kept NULL, the default callback will be invoked, which will just print the
|
||||
* current local time.
|
||||
*/
|
||||
sntp_sync_time_cb_t sync_time_cb;
|
||||
} esp_rmaker_time_config_t;
|
||||
|
||||
/** Reboot the chip after a delay
|
||||
@@ -104,6 +111,64 @@ bool esp_rmaker_time_check(void);
|
||||
*/
|
||||
esp_err_t esp_rmaker_time_wait_for_sync(uint32_t ticks_to_wait);
|
||||
|
||||
/** Set POSIX timezone
|
||||
*
|
||||
* Set the timezone (TZ environment variable) as per the POSIX format
|
||||
* specified in the [GNU libc documentation](https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html).
|
||||
* Eg. For China: "CST-8"
|
||||
* For US Pacific Time (including daylight saving information): "PST8PDT,M3.2.0,M11.1.0"
|
||||
*
|
||||
* @param[in] tz_posix NULL terminated TZ POSIX string
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* @return error on failure
|
||||
*/
|
||||
esp_err_t esp_rmaker_time_set_timezone_posix(const char *tz_posix);
|
||||
|
||||
/** Set timezone location string
|
||||
*
|
||||
* Set the timezone as a user friendly location string.
|
||||
* Check [here](https://rainmaker.espressif.com/docs/time-service.html) for a list of valid values.
|
||||
*
|
||||
* Eg. For China: "Asia/Shanghai"
|
||||
* For US Pacific Time: "America/Los_Angeles"
|
||||
*
|
||||
* @note Setting timezone using this API internally also sets the POSIX timezone string.
|
||||
*
|
||||
* @param[in] tz NULL terminated Timezone location string
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* @return error on failure
|
||||
*/
|
||||
esp_err_t esp_rmaker_time_set_timezone(const char *tz);
|
||||
|
||||
/** Enable Timezone Service
|
||||
*
|
||||
* This enables the ESP RainMaker standard timezone service which can be used to set
|
||||
* timezone, either in POSIX or location string format. Please refer the specifications
|
||||
* for additional details.
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* @return error on failure
|
||||
*/
|
||||
esp_err_t esp_rmaker_timezone_service_enable(void);
|
||||
|
||||
/** Get printable local time string
|
||||
*
|
||||
* Get a printable local time string, with information of timezone and Daylight Saving.
|
||||
* Eg. "Tue Sep 1 09:04:38 2020 -0400[EDT], DST: Yes"
|
||||
* "Tue Sep 1 21:04:04 2020 +0800[CST], DST: No"
|
||||
*
|
||||
*
|
||||
* @param[out] buf Pointer to a pre-allocated buffer into which the time string will
|
||||
* be populated.
|
||||
* @param[in] buf_len Length of the above buffer.
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* @return error on failure
|
||||
*/
|
||||
esp_err_t esp_rmaker_get_local_time_str(char *buf, size_t buf_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <esp_rmaker_core.h>
|
||||
#include <esp_rmaker_user_mapping.h>
|
||||
#include <esp_rmaker_utils.h>
|
||||
|
||||
#include <esp_rmaker_console_internal.h>
|
||||
|
||||
@@ -352,6 +353,55 @@ static void register_wifi_prov()
|
||||
esp_console_cmd_register(&cmd);
|
||||
}
|
||||
|
||||
static int local_time_cli_handler(int argc, char *argv[])
|
||||
{
|
||||
char local_time[64];
|
||||
if (esp_rmaker_get_local_time_str(local_time, sizeof(local_time)) == ESP_OK) {
|
||||
printf("%s: Current local time: %s\n", TAG, local_time);
|
||||
} else {
|
||||
printf("%s: Current local time (truncated): %s\n", TAG, local_time);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static int tz_set_cli_handler(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
printf("%s: Invalid Usage.\n", TAG);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (strcmp(argv[1], "posix") == 0) {
|
||||
if (argv[2]) {
|
||||
esp_rmaker_time_set_timezone_posix(argv[2]);
|
||||
} else {
|
||||
printf("%s: Invalid Usage.\n", TAG);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
} else {
|
||||
esp_rmaker_time_set_timezone(argv[1]);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void register_time_commands()
|
||||
{
|
||||
const esp_console_cmd_t local_time_cmd = {
|
||||
.command = "local-time",
|
||||
.help = "Get the local time of device.",
|
||||
.func = &local_time_cli_handler,
|
||||
};
|
||||
ESP_LOGI(TAG, "Registering command: %s", local_time_cmd.command);
|
||||
esp_console_cmd_register(&local_time_cmd);
|
||||
|
||||
const esp_console_cmd_t tz_set_cmd = {
|
||||
.command = "tz-set",
|
||||
.help = "Set Timezone. Usage: tz-set [posix] <tz_string>.",
|
||||
.func = &tz_set_cli_handler,
|
||||
};
|
||||
ESP_LOGI(TAG, "Registering command: %s", tz_set_cmd.command);
|
||||
esp_console_cmd_register(&tz_set_cmd);
|
||||
}
|
||||
|
||||
void register_commands()
|
||||
{
|
||||
register_generic_debug_commands();
|
||||
@@ -359,4 +409,5 @@ void register_commands()
|
||||
register_user_node_mapping();
|
||||
register_get_node_id();
|
||||
register_wifi_prov();
|
||||
register_time_commands();
|
||||
}
|
||||
|
||||
@@ -11,14 +11,154 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <string.h>
|
||||
#include <esp_log.h>
|
||||
#include "lwip/apps/sntp.h"
|
||||
#include <nvs.h>
|
||||
#include <lwip/apps/sntp.h>
|
||||
|
||||
#include <esp_rmaker_core.h>
|
||||
#include <esp_rmaker_standard_types.h>
|
||||
#include <esp_rmaker_standard_services.h>
|
||||
#include <esp_rmaker_utils.h>
|
||||
|
||||
static const char *TAG = "esp_rmaker_time_sync";
|
||||
|
||||
#define ESP_RMAKER_NVS_PART_NAME "nvs"
|
||||
|
||||
#define ESP_RMAKER_TIME_SERV_NAME "time"
|
||||
#define ESP_RMAKER_NVS_TIME_NAMESPACE "rmaker_time"
|
||||
#define ESP_RMAKER_TZ_POSIX_NVS_NAME "tz_posix"
|
||||
#define ESP_RMAKER_TZ_NVS_NAME "tz"
|
||||
|
||||
#define REF_TIME 1546300800 /* 01-Jan-2019 00:00:00 */
|
||||
static bool init_done = false;
|
||||
extern const char *esp_rmaker_tz_db_get_posix_str(const char *name);
|
||||
|
||||
#define ESP_RMAKER_DEF_TZ CONFIG_ESP_RMAKER_DEF_TIMEZONE
|
||||
|
||||
esp_err_t esp_rmaker_get_local_time_str(char *buf, size_t buf_len)
|
||||
{
|
||||
struct tm timeinfo;
|
||||
char strftime_buf[64];
|
||||
time_t now;
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
strftime(strftime_buf, sizeof(strftime_buf), "%c %z[%Z]", &timeinfo);
|
||||
size_t print_size = snprintf(buf, buf_len, "%s, DST: %s", strftime_buf, timeinfo.tm_isdst ? "Yes" : "No");
|
||||
if (print_size >= buf_len) {
|
||||
ESP_LOGE(TAG, "Buffer size %d insufficient for localtime string. REquired size: %d", buf_len, print_size);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_rmaker_print_current_time(void)
|
||||
{
|
||||
char local_time[64];
|
||||
if (esp_rmaker_get_local_time_str(local_time, sizeof(local_time)) == ESP_OK) {
|
||||
if (esp_rmaker_time_check() == false) {
|
||||
ESP_LOGI(TAG, "Time not synchronised yet.");
|
||||
}
|
||||
ESP_LOGI(TAG, "The current time is: %s.", local_time);
|
||||
return ESP_OK;
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
static char *__esp_rmaker_time_get_nvs(const char *key)
|
||||
{
|
||||
char *val = NULL;
|
||||
nvs_handle handle;
|
||||
esp_err_t err = nvs_open_from_partition(ESP_RMAKER_NVS_PART_NAME, ESP_RMAKER_NVS_TIME_NAMESPACE, NVS_READONLY, &handle);
|
||||
if (err != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
size_t len = 0;
|
||||
if ((err = nvs_get_blob(handle, key, NULL, &len)) == ESP_OK) {
|
||||
val = calloc(1, len + 1); /* +1 for NULL termination */
|
||||
if (val) {
|
||||
nvs_get_blob(handle, key, val, &len);
|
||||
}
|
||||
}
|
||||
nvs_close(handle);
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
static esp_err_t __esp_rmaker_time_set_nvs(const char *key, const char *val)
|
||||
{
|
||||
nvs_handle handle;
|
||||
esp_err_t err = nvs_open_from_partition(ESP_RMAKER_NVS_PART_NAME, ESP_RMAKER_NVS_TIME_NAMESPACE, NVS_READWRITE, &handle);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
err = nvs_set_blob(handle, key, val, strlen(val));
|
||||
nvs_commit(handle);
|
||||
nvs_close(handle);
|
||||
return err;
|
||||
}
|
||||
|
||||
static char *esp_rmaker_time_get_timezone_posix(void)
|
||||
{
|
||||
return __esp_rmaker_time_get_nvs(ESP_RMAKER_TZ_POSIX_NVS_NAME);
|
||||
}
|
||||
|
||||
static char *esp_rmaker_time_get_timezone(void)
|
||||
{
|
||||
return __esp_rmaker_time_get_nvs(ESP_RMAKER_TZ_NVS_NAME);
|
||||
}
|
||||
|
||||
esp_err_t esp_rmaker_time_set_timezone_posix(const char *tz_posix)
|
||||
{
|
||||
esp_err_t err = __esp_rmaker_time_set_nvs(ESP_RMAKER_TZ_POSIX_NVS_NAME, tz_posix);
|
||||
if (err == ESP_OK) {
|
||||
setenv("TZ", tz_posix, 1);
|
||||
tzset();
|
||||
esp_rmaker_print_current_time();
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_rmaker_time_set_timezone(const char *tz)
|
||||
{
|
||||
const char *tz_posix = esp_rmaker_tz_db_get_posix_str(tz);
|
||||
if (!tz_posix) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t err = esp_rmaker_time_set_timezone_posix(tz_posix);
|
||||
if (err == ESP_OK) {
|
||||
err = __esp_rmaker_time_set_nvs(ESP_RMAKER_TZ_NVS_NAME, tz);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_rmaker_timezone_enable(void)
|
||||
{
|
||||
char *tz_posix = esp_rmaker_time_get_timezone_posix();
|
||||
if (tz_posix) {
|
||||
setenv("TZ", tz_posix, 1);
|
||||
tzset();
|
||||
free(tz_posix);
|
||||
} else {
|
||||
if (strlen(ESP_RMAKER_DEF_TZ) > 0) {
|
||||
const char *tz_def = esp_rmaker_tz_db_get_posix_str(ESP_RMAKER_DEF_TZ);
|
||||
if (tz_def) {
|
||||
setenv("TZ", tz_def, 1);
|
||||
tzset();
|
||||
return ESP_OK;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Invalid Timezone %s specified.", ESP_RMAKER_DEF_TZ);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
static void esp_rmaker_time_sync_cb(struct timeval *tv)
|
||||
{
|
||||
ESP_LOGI(TAG, "SNTP Synchronised.");
|
||||
esp_rmaker_print_current_time();
|
||||
}
|
||||
|
||||
esp_err_t esp_rmaker_time_sync_init(esp_rmaker_time_config_t *config)
|
||||
{
|
||||
@@ -37,6 +177,12 @@ esp_err_t esp_rmaker_time_sync_init(esp_rmaker_time_config_t *config)
|
||||
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
sntp_setservername(0, sntp_server_name);
|
||||
sntp_init();
|
||||
if (config->sync_time_cb) {
|
||||
sntp_set_time_sync_notification_cb(config->sync_time_cb);
|
||||
} else {
|
||||
sntp_set_time_sync_notification_cb(esp_rmaker_time_sync_cb);
|
||||
}
|
||||
esp_rmaker_timezone_enable();
|
||||
init_done = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -52,6 +198,7 @@ bool esp_rmaker_time_check(void)
|
||||
}
|
||||
|
||||
#define DEFAULT_TICKS (2000 / portTICK_PERIOD_MS) /* 2 seconds in ticks */
|
||||
|
||||
esp_err_t esp_rmaker_time_wait_for_sync(uint32_t ticks_to_wait)
|
||||
{
|
||||
if (!init_done) {
|
||||
@@ -77,12 +224,63 @@ esp_err_t esp_rmaker_time_wait_for_sync(uint32_t ticks_to_wait)
|
||||
}
|
||||
|
||||
/* Get current time */
|
||||
struct tm timeinfo;
|
||||
char strftime_buf[64];
|
||||
time_t now;
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
|
||||
ESP_LOGI(TAG, "The current UTC time is: %s", strftime_buf);
|
||||
esp_rmaker_print_current_time();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_rmaker_time_service_cb(const esp_rmaker_device_t *device, const esp_rmaker_param_t *param,
|
||||
const esp_rmaker_param_val_t val, void *priv_data, esp_rmaker_write_ctx_t *ctx)
|
||||
{
|
||||
esp_err_t err = ESP_FAIL;
|
||||
if (strcmp(esp_rmaker_param_get_type(param), ESP_RMAKER_PARAM_TIMEZONE) == 0) {
|
||||
ESP_LOGI(TAG, "Received value = %s for %s - %s",
|
||||
val.val.s, esp_rmaker_device_get_name(device), esp_rmaker_param_get_name(param));
|
||||
err = esp_rmaker_time_set_timezone(val.val.s);
|
||||
if (err == ESP_OK) {
|
||||
char *tz_posix = esp_rmaker_time_get_timezone_posix();
|
||||
if (tz_posix) {
|
||||
esp_rmaker_param_t *tz_posix_param = esp_rmaker_device_get_param_by_type(
|
||||
device, ESP_RMAKER_PARAM_TIMEZONE_POSIX);
|
||||
esp_rmaker_param_update_and_report(tz_posix_param, esp_rmaker_str(tz_posix));
|
||||
free(tz_posix);
|
||||
}
|
||||
}
|
||||
} else if (strcmp(esp_rmaker_param_get_type(param), ESP_RMAKER_PARAM_TIMEZONE_POSIX) == 0) {
|
||||
ESP_LOGI(TAG, "Received value = %s for %s - %s",
|
||||
val.val.s, esp_rmaker_device_get_name(device), esp_rmaker_param_get_name(param));
|
||||
err = esp_rmaker_time_set_timezone_posix(val.val.s);
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
esp_rmaker_param_update_and_report(param, val);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t esp_rmaker_time_add_service(const char *tz, const char *tz_posix)
|
||||
{
|
||||
esp_rmaker_device_t *service = esp_rmaker_time_service_create(ESP_RMAKER_TIME_SERV_NAME, tz, tz_posix, NULL);
|
||||
if (!service) {
|
||||
ESP_LOGE(TAG, "Failed to create Time Service");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
esp_rmaker_device_add_cb(service, esp_rmaker_time_service_cb, NULL);
|
||||
esp_err_t err = esp_rmaker_node_add_device(esp_rmaker_get_node(), service);
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Time service enabled");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_rmaker_timezone_service_enable(void)
|
||||
{
|
||||
char *tz_posix = esp_rmaker_time_get_timezone_posix();
|
||||
char *tz = esp_rmaker_time_get_timezone();
|
||||
esp_err_t err = esp_rmaker_time_add_service(tz, tz_posix);
|
||||
if (tz_posix) {
|
||||
free(tz_posix);
|
||||
}
|
||||
if (tz) {
|
||||
free(tz);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
515
components/esp_rainmaker/src/core/esp_rmaker_timezone.c
Normal file
515
components/esp_rainmaker/src/core/esp_rmaker_timezone.c
Normal file
@@ -0,0 +1,515 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Nayar Systems
|
||||
// Copyright (c) 2020 Jacob Lambert
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// Original code taken from: https://github.com/jdlambert/micro_tz_db
|
||||
// which was forked from https://github.com/nayarsystems/posix_tz_db
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *posix_str;
|
||||
} esp_rmaker_tz_db_pair_t;
|
||||
|
||||
static const esp_rmaker_tz_db_pair_t esp_rmaker_tz_db_tzs[] = {
|
||||
{"Africa/Abidjan", "GMT0"},
|
||||
{"Africa/Accra", "GMT0"},
|
||||
{"Africa/Addis_Ababa", "EAT-3"},
|
||||
{"Africa/Algiers", "CET-1"},
|
||||
{"Africa/Asmara", "EAT-3"},
|
||||
{"Africa/Bamako", "GMT0"},
|
||||
{"Africa/Bangui", "WAT-1"},
|
||||
{"Africa/Banjul", "GMT0"},
|
||||
{"Africa/Bissau", "GMT0"},
|
||||
{"Africa/Blantyre", "CAT-2"},
|
||||
{"Africa/Brazzaville", "WAT-1"},
|
||||
{"Africa/Bujumbura", "CAT-2"},
|
||||
{"Africa/Cairo", "EET-2"},
|
||||
{"Africa/Casablanca", "<+01>-1"},
|
||||
{"Africa/Ceuta", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Africa/Conakry", "GMT0"},
|
||||
{"Africa/Dakar", "GMT0"},
|
||||
{"Africa/Dar_es_Salaam", "EAT-3"},
|
||||
{"Africa/Djibouti", "EAT-3"},
|
||||
{"Africa/Douala", "WAT-1"},
|
||||
{"Africa/El_Aaiun", "<+01>-1"},
|
||||
{"Africa/Freetown", "GMT0"},
|
||||
{"Africa/Gaborone", "CAT-2"},
|
||||
{"Africa/Harare", "CAT-2"},
|
||||
{"Africa/Johannesburg", "SAST-2"},
|
||||
{"Africa/Juba", "EAT-3"},
|
||||
{"Africa/Kampala", "EAT-3"},
|
||||
{"Africa/Khartoum", "CAT-2"},
|
||||
{"Africa/Kigali", "CAT-2"},
|
||||
{"Africa/Kinshasa", "WAT-1"},
|
||||
{"Africa/Lagos", "WAT-1"},
|
||||
{"Africa/Libreville", "WAT-1"},
|
||||
{"Africa/Lome", "GMT0"},
|
||||
{"Africa/Luanda", "WAT-1"},
|
||||
{"Africa/Lubumbashi", "CAT-2"},
|
||||
{"Africa/Lusaka", "CAT-2"},
|
||||
{"Africa/Malabo", "WAT-1"},
|
||||
{"Africa/Maputo", "CAT-2"},
|
||||
{"Africa/Maseru", "SAST-2"},
|
||||
{"Africa/Mbabane", "SAST-2"},
|
||||
{"Africa/Mogadishu", "EAT-3"},
|
||||
{"Africa/Monrovia", "GMT0"},
|
||||
{"Africa/Nairobi", "EAT-3"},
|
||||
{"Africa/Ndjamena", "WAT-1"},
|
||||
{"Africa/Niamey", "WAT-1"},
|
||||
{"Africa/Nouakchott", "GMT0"},
|
||||
{"Africa/Ouagadougou", "GMT0"},
|
||||
{"Africa/Porto-Novo", "WAT-1"},
|
||||
{"Africa/Sao_Tome", "GMT0"},
|
||||
{"Africa/Tripoli", "EET-2"},
|
||||
{"Africa/Tunis", "CET-1"},
|
||||
{"Africa/Windhoek", "CAT-2"},
|
||||
{"America/Adak", "HST10HDT,M3.2.0,M11.1.0"},
|
||||
{"America/Anchorage", "AKST9AKDT,M3.2.0,M11.1.0"},
|
||||
{"America/Anguilla", "AST4"},
|
||||
{"America/Antigua", "AST4"},
|
||||
{"America/Araguaina", "<-03>3"},
|
||||
{"America/Argentina/Buenos_Aires", "<-03>3"},
|
||||
{"America/Argentina/Catamarca", "<-03>3"},
|
||||
{"America/Argentina/Cordoba", "<-03>3"},
|
||||
{"America/Argentina/Jujuy", "<-03>3"},
|
||||
{"America/Argentina/La_Rioja", "<-03>3"},
|
||||
{"America/Argentina/Mendoza", "<-03>3"},
|
||||
{"America/Argentina/Rio_Gallegos", "<-03>3"},
|
||||
{"America/Argentina/Salta", "<-03>3"},
|
||||
{"America/Argentina/San_Juan", "<-03>3"},
|
||||
{"America/Argentina/San_Luis", "<-03>3"},
|
||||
{"America/Argentina/Tucuman", "<-03>3"},
|
||||
{"America/Argentina/Ushuaia", "<-03>3"},
|
||||
{"America/Aruba", "AST4"},
|
||||
{"America/Asuncion", "<-04>4<-03>,M10.1.0/0,M3.4.0/0"},
|
||||
{"America/Atikokan", "EST5"},
|
||||
{"America/Bahia", "<-03>3"},
|
||||
{"America/Bahia_Banderas", "CST6CDT,M4.1.0,M10.5.0"},
|
||||
{"America/Barbados", "AST4"},
|
||||
{"America/Belem", "<-03>3"},
|
||||
{"America/Belize", "CST6"},
|
||||
{"America/Blanc-Sablon", "AST4"},
|
||||
{"America/Boa_Vista", "<-04>4"},
|
||||
{"America/Bogota", "<-05>5"},
|
||||
{"America/Boise", "MST7MDT,M3.2.0,M11.1.0"},
|
||||
{"America/Cambridge_Bay", "MST7MDT,M3.2.0,M11.1.0"},
|
||||
{"America/Campo_Grande", "<-04>4"},
|
||||
{"America/Cancun", "EST5"},
|
||||
{"America/Caracas", "<-04>4"},
|
||||
{"America/Cayenne", "<-03>3"},
|
||||
{"America/Cayman", "EST5"},
|
||||
{"America/Chicago", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/Chihuahua", "MST7MDT,M4.1.0,M10.5.0"},
|
||||
{"America/Costa_Rica", "CST6"},
|
||||
{"America/Creston", "MST7"},
|
||||
{"America/Cuiaba", "<-04>4"},
|
||||
{"America/Curacao", "AST4"},
|
||||
{"America/Danmarkshavn", "GMT0"},
|
||||
{"America/Dawson", "MST7"},
|
||||
{"America/Dawson_Creek", "MST7"},
|
||||
{"America/Denver", "MST7MDT,M3.2.0,M11.1.0"},
|
||||
{"America/Detroit", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Dominica", "AST4"},
|
||||
{"America/Edmonton", "MST7MDT,M3.2.0,M11.1.0"},
|
||||
{"America/Eirunepe", "<-05>5"},
|
||||
{"America/El_Salvador", "CST6"},
|
||||
{"America/Fortaleza", "<-03>3"},
|
||||
{"America/Fort_Nelson", "MST7"},
|
||||
{"America/Glace_Bay", "AST4ADT,M3.2.0,M11.1.0"},
|
||||
{"America/Godthab", "<-03>3<-02>,M3.5.0/-2,M10.5.0/-1"},
|
||||
{"America/Goose_Bay", "AST4ADT,M3.2.0,M11.1.0"},
|
||||
{"America/Grand_Turk", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Grenada", "AST4"},
|
||||
{"America/Guadeloupe", "AST4"},
|
||||
{"America/Guatemala", "CST6"},
|
||||
{"America/Guayaquil", "<-05>5"},
|
||||
{"America/Guyana", "<-04>4"},
|
||||
{"America/Halifax", "AST4ADT,M3.2.0,M11.1.0"},
|
||||
{"America/Havana", "CST5CDT,M3.2.0/0,M11.1.0/1"},
|
||||
{"America/Hermosillo", "MST7"},
|
||||
{"America/Indiana/Indianapolis", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Indiana/Knox", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/Indiana/Marengo", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Indiana/Petersburg", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Indiana/Tell_City", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/Indiana/Vevay", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Indiana/Vincennes", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Indiana/Winamac", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Inuvik", "MST7MDT,M3.2.0,M11.1.0"},
|
||||
{"America/Iqaluit", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Jamaica", "EST5"},
|
||||
{"America/Juneau", "AKST9AKDT,M3.2.0,M11.1.0"},
|
||||
{"America/Kentucky/Louisville", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Kentucky/Monticello", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Kralendijk", "AST4"},
|
||||
{"America/La_Paz", "<-04>4"},
|
||||
{"America/Lima", "<-05>5"},
|
||||
{"America/Los_Angeles", "PST8PDT,M3.2.0,M11.1.0"},
|
||||
{"America/Lower_Princes", "AST4"},
|
||||
{"America/Maceio", "<-03>3"},
|
||||
{"America/Managua", "CST6"},
|
||||
{"America/Manaus", "<-04>4"},
|
||||
{"America/Marigot", "AST4"},
|
||||
{"America/Martinique", "AST4"},
|
||||
{"America/Matamoros", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/Mazatlan", "MST7MDT,M4.1.0,M10.5.0"},
|
||||
{"America/Menominee", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/Merida", "CST6CDT,M4.1.0,M10.5.0"},
|
||||
{"America/Metlakatla", "AKST9AKDT,M3.2.0,M11.1.0"},
|
||||
{"America/Mexico_City", "CST6CDT,M4.1.0,M10.5.0"},
|
||||
{"America/Miquelon", "<-03>3<-02>,M3.2.0,M11.1.0"},
|
||||
{"America/Moncton", "AST4ADT,M3.2.0,M11.1.0"},
|
||||
{"America/Monterrey", "CST6CDT,M4.1.0,M10.5.0"},
|
||||
{"America/Montevideo", "<-03>3"},
|
||||
{"America/Montreal", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Montserrat", "AST4"},
|
||||
{"America/Nassau", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/New_York", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Nipigon", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Nome", "AKST9AKDT,M3.2.0,M11.1.0"},
|
||||
{"America/Noronha", "<-02>2"},
|
||||
{"America/North_Dakota/Beulah", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/North_Dakota/Center", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/North_Dakota/New_Salem", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/Ojinaga", "MST7MDT,M3.2.0,M11.1.0"},
|
||||
{"America/Panama", "EST5"},
|
||||
{"America/Pangnirtung", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Paramaribo", "<-03>3"},
|
||||
{"America/Phoenix", "MST7"},
|
||||
{"America/Port-au-Prince", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Port_of_Spain", "AST4"},
|
||||
{"America/Porto_Velho", "<-04>4"},
|
||||
{"America/Puerto_Rico", "AST4"},
|
||||
{"America/Punta_Arenas", "<-03>3"},
|
||||
{"America/Rainy_River", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/Rankin_Inlet", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/Recife", "<-03>3"},
|
||||
{"America/Regina", "CST6"},
|
||||
{"America/Resolute", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/Rio_Branco", "<-05>5"},
|
||||
{"America/Santarem", "<-03>3"},
|
||||
{"America/Santiago", "<-04>4<-03>,M9.1.6/24,M4.1.6/24"},
|
||||
{"America/Santo_Domingo", "AST4"},
|
||||
{"America/Sao_Paulo", "<-03>3"},
|
||||
{"America/Scoresbysund", "<-01>1<+00>,M3.5.0/0,M10.5.0/1"},
|
||||
{"America/Sitka", "AKST9AKDT,M3.2.0,M11.1.0"},
|
||||
{"America/St_Barthelemy", "AST4"},
|
||||
{"America/St_Johns", "NST3:30NDT,M3.2.0,M11.1.0"},
|
||||
{"America/St_Kitts", "AST4"},
|
||||
{"America/St_Lucia", "AST4"},
|
||||
{"America/St_Thomas", "AST4"},
|
||||
{"America/St_Vincent", "AST4"},
|
||||
{"America/Swift_Current", "CST6"},
|
||||
{"America/Tegucigalpa", "CST6"},
|
||||
{"America/Thule", "AST4ADT,M3.2.0,M11.1.0"},
|
||||
{"America/Thunder_Bay", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Tijuana", "PST8PDT,M3.2.0,M11.1.0"},
|
||||
{"America/Toronto", "EST5EDT,M3.2.0,M11.1.0"},
|
||||
{"America/Tortola", "AST4"},
|
||||
{"America/Vancouver", "PST8PDT,M3.2.0,M11.1.0"},
|
||||
{"America/Whitehorse", "MST7"},
|
||||
{"America/Winnipeg", "CST6CDT,M3.2.0,M11.1.0"},
|
||||
{"America/Yakutat", "AKST9AKDT,M3.2.0,M11.1.0"},
|
||||
{"America/Yellowknife", "MST7MDT,M3.2.0,M11.1.0"},
|
||||
{"Antarctica/Casey", "<+08>-8"},
|
||||
{"Antarctica/Davis", "<+07>-7"},
|
||||
{"Antarctica/DumontDUrville", "<+10>-10"},
|
||||
{"Antarctica/Macquarie", "<+11>-11"},
|
||||
{"Antarctica/Mawson", "<+05>-5"},
|
||||
{"Antarctica/McMurdo", "NZST-12NZDT,M9.5.0,M4.1.0/3"},
|
||||
{"Antarctica/Palmer", "<-03>3"},
|
||||
{"Antarctica/Rothera", "<-03>3"},
|
||||
{"Antarctica/Syowa", "<+03>-3"},
|
||||
{"Antarctica/Troll", "<+00>0<+02>-2,M3.5.0/1,M10.5.0/3"},
|
||||
{"Antarctica/Vostok", "<+06>-6"},
|
||||
{"Arctic/Longyearbyen", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Asia/Aden", "<+03>-3"},
|
||||
{"Asia/Almaty", "<+06>-6"},
|
||||
{"Asia/Amman", "EET-2EEST,M3.5.4/24,M10.5.5/1"},
|
||||
{"Asia/Anadyr", "<+12>-12"},
|
||||
{"Asia/Aqtau", "<+05>-5"},
|
||||
{"Asia/Aqtobe", "<+05>-5"},
|
||||
{"Asia/Ashgabat", "<+05>-5"},
|
||||
{"Asia/Atyrau", "<+05>-5"},
|
||||
{"Asia/Baghdad", "<+03>-3"},
|
||||
{"Asia/Bahrain", "<+03>-3"},
|
||||
{"Asia/Baku", "<+04>-4"},
|
||||
{"Asia/Bangkok", "<+07>-7"},
|
||||
{"Asia/Barnaul", "<+07>-7"},
|
||||
{"Asia/Beirut", "EET-2EEST,M3.5.0/0,M10.5.0/0"},
|
||||
{"Asia/Bishkek", "<+06>-6"},
|
||||
{"Asia/Brunei", "<+08>-8"},
|
||||
{"Asia/Chita", "<+09>-9"},
|
||||
{"Asia/Choibalsan", "<+08>-8"},
|
||||
{"Asia/Colombo", "<+0530>-5:30"},
|
||||
{"Asia/Damascus", "EET-2EEST,M3.5.5/0,M10.5.5/0"},
|
||||
{"Asia/Dhaka", "<+06>-6"},
|
||||
{"Asia/Dili", "<+09>-9"},
|
||||
{"Asia/Dubai", "<+04>-4"},
|
||||
{"Asia/Dushanbe", "<+05>-5"},
|
||||
{"Asia/Famagusta", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Asia/Gaza", "EET-2EEST,M3.5.5/0,M10.5.6/1"},
|
||||
{"Asia/Hebron", "EET-2EEST,M3.5.5/0,M10.5.6/1"},
|
||||
{"Asia/Ho_Chi_Minh", "<+07>-7"},
|
||||
{"Asia/Hong_Kong", "HKT-8"},
|
||||
{"Asia/Hovd", "<+07>-7"},
|
||||
{"Asia/Irkutsk", "<+08>-8"},
|
||||
{"Asia/Jakarta", "WIB-7"},
|
||||
{"Asia/Jayapura", "WIT-9"},
|
||||
{"Asia/Jerusalem", "IST-2IDT,M3.4.4/26,M10.5.0"},
|
||||
{"Asia/Kabul", "<+0430>-4:30"},
|
||||
{"Asia/Kamchatka", "<+12>-12"},
|
||||
{"Asia/Karachi", "PKT-5"},
|
||||
{"Asia/Kathmandu", "<+0545>-5:45"},
|
||||
{"Asia/Khandyga", "<+09>-9"},
|
||||
{"Asia/Kolkata", "IST-5:30"},
|
||||
{"Asia/Krasnoyarsk", "<+07>-7"},
|
||||
{"Asia/Kuala_Lumpur", "<+08>-8"},
|
||||
{"Asia/Kuching", "<+08>-8"},
|
||||
{"Asia/Kuwait", "<+03>-3"},
|
||||
{"Asia/Macau", "CST-8"},
|
||||
{"Asia/Magadan", "<+11>-11"},
|
||||
{"Asia/Makassar", "WITA-8"},
|
||||
{"Asia/Manila", "PST-8"},
|
||||
{"Asia/Muscat", "<+04>-4"},
|
||||
{"Asia/Nicosia", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Asia/Novokuznetsk", "<+07>-7"},
|
||||
{"Asia/Novosibirsk", "<+07>-7"},
|
||||
{"Asia/Omsk", "<+06>-6"},
|
||||
{"Asia/Oral", "<+05>-5"},
|
||||
{"Asia/Phnom_Penh", "<+07>-7"},
|
||||
{"Asia/Pontianak", "WIB-7"},
|
||||
{"Asia/Pyongyang", "KST-9"},
|
||||
{"Asia/Qatar", "<+03>-3"},
|
||||
{"Asia/Qyzylorda", "<+05>-5"},
|
||||
{"Asia/Riyadh", "<+03>-3"},
|
||||
{"Asia/Sakhalin", "<+11>-11"},
|
||||
{"Asia/Samarkand", "<+05>-5"},
|
||||
{"Asia/Seoul", "KST-9"},
|
||||
{"Asia/Shanghai", "CST-8"},
|
||||
{"Asia/Singapore", "<+08>-8"},
|
||||
{"Asia/Srednekolymsk", "<+11>-11"},
|
||||
{"Asia/Taipei", "CST-8"},
|
||||
{"Asia/Tashkent", "<+05>-5"},
|
||||
{"Asia/Tbilisi", "<+04>-4"},
|
||||
{"Asia/Tehran", "<+0330>-3:30<+0430>,J79/24,J263/24"},
|
||||
{"Asia/Thimphu", "<+06>-6"},
|
||||
{"Asia/Tokyo", "JST-9"},
|
||||
{"Asia/Tomsk", "<+07>-7"},
|
||||
{"Asia/Ulaanbaatar", "<+08>-8"},
|
||||
{"Asia/Urumqi", "<+06>-6"},
|
||||
{"Asia/Ust-Nera", "<+10>-10"},
|
||||
{"Asia/Vientiane", "<+07>-7"},
|
||||
{"Asia/Vladivostok", "<+10>-10"},
|
||||
{"Asia/Yakutsk", "<+09>-9"},
|
||||
{"Asia/Yangon", "<+0630>-6:30"},
|
||||
{"Asia/Yekaterinburg", "<+05>-5"},
|
||||
{"Asia/Yerevan", "<+04>-4"},
|
||||
{"Atlantic/Azores", "<-01>1<+00>,M3.5.0/0,M10.5.0/1"},
|
||||
{"Atlantic/Bermuda", "AST4ADT,M3.2.0,M11.1.0"},
|
||||
{"Atlantic/Canary", "WET0WEST,M3.5.0/1,M10.5.0"},
|
||||
{"Atlantic/Cape_Verde", "<-01>1"},
|
||||
{"Atlantic/Faroe", "WET0WEST,M3.5.0/1,M10.5.0"},
|
||||
{"Atlantic/Madeira", "WET0WEST,M3.5.0/1,M10.5.0"},
|
||||
{"Atlantic/Reykjavik", "GMT0"},
|
||||
{"Atlantic/South_Georgia", "<-02>2"},
|
||||
{"Atlantic/Stanley", "<-03>3"},
|
||||
{"Atlantic/St_Helena", "GMT0"},
|
||||
{"Australia/Adelaide", "ACST-9:30ACDT,M10.1.0,M4.1.0/3"},
|
||||
{"Australia/Brisbane", "AEST-10"},
|
||||
{"Australia/Broken_Hill", "ACST-9:30ACDT,M10.1.0,M4.1.0/3"},
|
||||
{"Australia/Currie", "AEST-10AEDT,M10.1.0,M4.1.0/3"},
|
||||
{"Australia/Darwin", "ACST-9:30"},
|
||||
{"Australia/Eucla", "<+0845>-8:45"},
|
||||
{"Australia/Hobart", "AEST-10AEDT,M10.1.0,M4.1.0/3"},
|
||||
{"Australia/Lindeman", "AEST-10"},
|
||||
{"Australia/Lord_Howe", "<+1030>-10:30<+11>-11,M10.1.0,M4.1.0"},
|
||||
{"Australia/Melbourne", "AEST-10AEDT,M10.1.0,M4.1.0/3"},
|
||||
{"Australia/Perth", "AWST-8"},
|
||||
{"Australia/Sydney", "AEST-10AEDT,M10.1.0,M4.1.0/3"},
|
||||
{"Europe/Amsterdam", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Andorra", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Astrakhan", "<+04>-4"},
|
||||
{"Europe/Athens", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Europe/Belgrade", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Berlin", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Bratislava", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Brussels", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Bucharest", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Europe/Budapest", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Busingen", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Chisinau", "EET-2EEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Copenhagen", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Dublin", "IST-1GMT0,M10.5.0,M3.5.0/1"},
|
||||
{"Europe/Gibraltar", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Guernsey", "GMT0BST,M3.5.0/1,M10.5.0"},
|
||||
{"Europe/Helsinki", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Europe/Isle_of_Man", "GMT0BST,M3.5.0/1,M10.5.0"},
|
||||
{"Europe/Istanbul", "<+03>-3"},
|
||||
{"Europe/Jersey", "GMT0BST,M3.5.0/1,M10.5.0"},
|
||||
{"Europe/Kaliningrad", "EET-2"},
|
||||
{"Europe/Kiev", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Europe/Kirov", "<+03>-3"},
|
||||
{"Europe/Lisbon", "WET0WEST,M3.5.0/1,M10.5.0"},
|
||||
{"Europe/Ljubljana", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/London", "GMT0BST,M3.5.0/1,M10.5.0"},
|
||||
{"Europe/Luxembourg", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Madrid", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Malta", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Mariehamn", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Europe/Minsk", "<+03>-3"},
|
||||
{"Europe/Monaco", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Moscow", "MSK-3"},
|
||||
{"Europe/Oslo", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Paris", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Podgorica", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Prague", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Riga", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Europe/Rome", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Samara", "<+04>-4"},
|
||||
{"Europe/San_Marino", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Sarajevo", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Saratov", "<+04>-4"},
|
||||
{"Europe/Simferopol", "MSK-3"},
|
||||
{"Europe/Skopje", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Sofia", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Europe/Stockholm", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Tallinn", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Europe/Tirane", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Ulyanovsk", "<+04>-4"},
|
||||
{"Europe/Uzhgorod", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Europe/Vaduz", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Vatican", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Vienna", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Vilnius", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Europe/Volgograd", "<+04>-4"},
|
||||
{"Europe/Warsaw", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Zagreb", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Europe/Zaporozhye", "EET-2EEST,M3.5.0/3,M10.5.0/4"},
|
||||
{"Europe/Zurich", "CET-1CEST,M3.5.0,M10.5.0/3"},
|
||||
{"Indian/Antananarivo", "EAT-3"},
|
||||
{"Indian/Chagos", "<+06>-6"},
|
||||
{"Indian/Christmas", "<+07>-7"},
|
||||
{"Indian/Cocos", "<+0630>-6:30"},
|
||||
{"Indian/Comoro", "EAT-3"},
|
||||
{"Indian/Kerguelen", "<+05>-5"},
|
||||
{"Indian/Mahe", "<+04>-4"},
|
||||
{"Indian/Maldives", "<+05>-5"},
|
||||
{"Indian/Mauritius", "<+04>-4"},
|
||||
{"Indian/Mayotte", "EAT-3"},
|
||||
{"Indian/Reunion", "<+04>-4"},
|
||||
{"Pacific/Apia", "<+13>-13<+14>,M9.5.0/3,M4.1.0/4"},
|
||||
{"Pacific/Auckland", "NZST-12NZDT,M9.5.0,M4.1.0/3"},
|
||||
{"Pacific/Bougainville", "<+11>-11"},
|
||||
{"Pacific/Chatham", "<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45"},
|
||||
{"Pacific/Chuuk", "<+10>-10"},
|
||||
{"Pacific/Easter", "<-06>6<-05>,M9.1.6/22,M4.1.6/22"},
|
||||
{"Pacific/Efate", "<+11>-11"},
|
||||
{"Pacific/Enderbury", "<+13>-13"},
|
||||
{"Pacific/Fakaofo", "<+13>-13"},
|
||||
{"Pacific/Fiji", "<+12>-12<+13>,M11.2.0,M1.2.3/99"},
|
||||
{"Pacific/Funafuti", "<+12>-12"},
|
||||
{"Pacific/Galapagos", "<-06>6"},
|
||||
{"Pacific/Gambier", "<-09>9"},
|
||||
{"Pacific/Guadalcanal", "<+11>-11"},
|
||||
{"Pacific/Guam", "ChST-10"},
|
||||
{"Pacific/Honolulu", "HST10"},
|
||||
{"Pacific/Kiritimati", "<+14>-14"},
|
||||
{"Pacific/Kosrae", "<+11>-11"},
|
||||
{"Pacific/Kwajalein", "<+12>-12"},
|
||||
{"Pacific/Majuro", "<+12>-12"},
|
||||
{"Pacific/Marquesas", "<-0930>9:30"},
|
||||
{"Pacific/Midway", "SST11"},
|
||||
{"Pacific/Nauru", "<+12>-12"},
|
||||
{"Pacific/Niue", "<-11>11"},
|
||||
{"Pacific/Norfolk", "<+11>-11<+12>,M10.1.0,M4.1.0/3"},
|
||||
{"Pacific/Noumea", "<+11>-11"},
|
||||
{"Pacific/Pago_Pago", "SST11"},
|
||||
{"Pacific/Palau", "<+09>-9"},
|
||||
{"Pacific/Pitcairn", "<-08>8"},
|
||||
{"Pacific/Pohnpei", "<+11>-11"},
|
||||
{"Pacific/Port_Moresby", "<+10>-10"},
|
||||
{"Pacific/Rarotonga", "<-10>10"},
|
||||
{"Pacific/Saipan", "ChST-10"},
|
||||
{"Pacific/Tahiti", "<-10>10"},
|
||||
{"Pacific/Tarawa", "<+12>-12"},
|
||||
{"Pacific/Tongatapu", "<+13>-13"},
|
||||
{"Pacific/Wake", "<+12>-12"},
|
||||
{"Pacific/Wallis", "<+12>-12"}
|
||||
};
|
||||
|
||||
static char lower(char start) {
|
||||
if ('A' <= start && start <= 'Z') {
|
||||
return start - 'A' + 'a';
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basically strcmp, but accounting for spaces that have become underscores
|
||||
* @param[in] target - the 0-terminated string on the left hand side of the comparison
|
||||
* @param[in] other - the 0-terminated string on the right hand side of the comparison
|
||||
* @return > 0 if target comes before other alphabetically,
|
||||
* ==0 if they're the same,
|
||||
* < 0 if other comes before target alphabetically
|
||||
* (we don't expect NULL arguments, but, -1 if either is NULL)
|
||||
**/
|
||||
static int tz_name_cmp(const char * target, const char * other)
|
||||
{
|
||||
if (!target || !other) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (*target) {
|
||||
if (lower(*target) != lower(*other)) {
|
||||
break;
|
||||
}
|
||||
do {
|
||||
target++;
|
||||
} while (*target == '_');
|
||||
do {
|
||||
other++;
|
||||
} while (*other == '_');
|
||||
}
|
||||
|
||||
return lower(*target) - lower(*other);
|
||||
}
|
||||
|
||||
const char *esp_rmaker_tz_db_get_posix_str(const char *name)
|
||||
{
|
||||
int lo = 0, hi = sizeof(esp_rmaker_tz_db_tzs) / sizeof(esp_rmaker_tz_db_pair_t);
|
||||
while (lo < hi) {
|
||||
int mid = (lo + hi) / 2;
|
||||
esp_rmaker_tz_db_pair_t mid_pair = esp_rmaker_tz_db_tzs[mid];
|
||||
int comparison = tz_name_cmp(name, mid_pair.name);
|
||||
if (comparison == 0) {
|
||||
return mid_pair.posix_str;
|
||||
} else if (comparison < 0) {
|
||||
hi = mid;
|
||||
} else {
|
||||
lo = mid + 1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -138,3 +138,17 @@ esp_rmaker_param_t *esp_rmaker_ota_url_param_create(const char *param_name)
|
||||
esp_rmaker_str(""), PROP_FLAG_WRITE);
|
||||
return param;
|
||||
}
|
||||
|
||||
esp_rmaker_param_t *esp_rmaker_timezone_param_create(const char *param_name, const char *val)
|
||||
{
|
||||
esp_rmaker_param_t *param = esp_rmaker_param_create(param_name, ESP_RMAKER_PARAM_TIMEZONE,
|
||||
esp_rmaker_str(val), PROP_FLAG_READ | PROP_FLAG_WRITE);
|
||||
return param;
|
||||
}
|
||||
|
||||
esp_rmaker_param_t *esp_rmaker_timezone_posix_param_create(const char *param_name, const char *val)
|
||||
{
|
||||
esp_rmaker_param_t *param = esp_rmaker_param_create(param_name, ESP_RMAKER_PARAM_TIMEZONE_POSIX,
|
||||
esp_rmaker_str(val), PROP_FLAG_READ | PROP_FLAG_WRITE);
|
||||
return param;
|
||||
}
|
||||
|
||||
@@ -27,3 +27,15 @@ esp_rmaker_device_t *esp_rmaker_ota_service_create(const char *serv_name, void *
|
||||
return service;
|
||||
}
|
||||
|
||||
esp_rmaker_device_t *esp_rmaker_time_service_create(const char *serv_name, const char *timezone,
|
||||
const char *timezone_posix, void *priv_data)
|
||||
{
|
||||
esp_rmaker_device_t *service = esp_rmaker_service_create(serv_name, ESP_RMAKER_SERVICE_TIME, priv_data);
|
||||
if (service) {
|
||||
esp_rmaker_device_add_param(service, esp_rmaker_timezone_param_create(
|
||||
ESP_RMAKER_DEF_TIMEZONE_NAME, timezone));
|
||||
esp_rmaker_device_add_param(service, esp_rmaker_timezone_posix_param_create(
|
||||
ESP_RMAKER_DEF_TIMEZONE_POSIX_NAME, timezone_posix));
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user