Save/load time to/from storage in time_manager

This commit is contained in:
Camden Dixie O'Brien 2023-05-16 22:12:49 +01:00
parent c82af79d52
commit a4a4a035f2
3 changed files with 75 additions and 3 deletions

View File

@ -1,5 +1,5 @@
idf_component_register( idf_component_register(
SRCS "time_manager.c" SRCS "time_manager.c"
INCLUDE_DIRS "." INCLUDE_DIRS "."
REQUIRES console_wrapper lwip settings REQUIRES console_wrapper lwip nvs_flash settings
) )

View File

@ -10,10 +10,15 @@
#include "esp_log.h" #include "esp_log.h"
#include "esp_sntp.h" #include "esp_sntp.h"
#include "freertos/FreeRTOS.h"
#include "nvs_flash.h"
#include <time.h> #include <time.h>
#define TAG "Time" #define TAG "Time"
#define NVS_NAMESPACE "time"
#define TIMESTAMP_KEY "timestamp"
static void handle_timezone_update(const char *timezone) static void handle_timezone_update(const char *timezone)
{ {
setenv("TZ", timezone, 1); setenv("TZ", timezone, 1);
@ -54,6 +59,29 @@ static const char *sync_status_description(sntp_sync_status_t status)
} }
} }
static int store_time(void)
{
esp_err_t error;
nvs_handle_t nvs;
error = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs);
if (error != ESP_OK) {
ESP_LOGE(TAG, "Error opening NVS: %04x", error);
return 1;
}
struct timeval tv;
gettimeofday(&tv, NULL);
error = nvs_set_u64(nvs, TIMESTAMP_KEY, tv.tv_sec);
if (error == ESP_OK)
ESP_LOGI(TAG, "Stored time");
else
ESP_LOGE(TAG, "Error storing time: %04x", error);
nvs_close(nvs);
return error == ESP_OK ? 0 : 1;
}
static int command_func(int argc, char **argv) static int command_func(int argc, char **argv)
{ {
if (argc == 1) { if (argc == 1) {
@ -65,10 +93,13 @@ static int command_func(int argc, char **argv)
const sntp_sync_status_t status = sntp_get_sync_status(); const sntp_sync_status_t status = sntp_get_sync_status();
printf("%s\n", sync_status_description(status)); printf("%s\n", sync_status_description(status));
return 0; return 0;
} else if (strcmp(argv[1], "store") == 0) {
return store_time();
} else { } else {
Time time; Time time;
if (sscanf(argv[1], "%02u:%02u", &time.hour, &time.minute) < 2 const int result
|| time.hour > 23 || time.minute > 59) { = sscanf(argv[1], "%02u:%02u", &time.hour, &time.minute);
if (result < 2 || time.hour > 23 || time.minute > 59) {
printf("Invalid time\n"); printf("Invalid time\n");
return 1; return 1;
} }
@ -81,6 +112,16 @@ static int command_func(int argc, char **argv)
} }
} }
static void time_saver_func(void *arg)
{
(void)arg;
const TickType_t delay = CONFIG_TIME_SAVE_PERIOD_MS / portTICK_PERIOD_MS;
while (1) {
(void)store_time();
vTaskDelay(delay);
}
}
void time_manager_init(void) void time_manager_init(void)
{ {
char timezone[SETTINGS_MAX_VALUE_SIZE]; char timezone[SETTINGS_MAX_VALUE_SIZE];
@ -100,6 +141,31 @@ void time_manager_init(void)
console_register( console_register(
"time", "Get / set time and SNTP status", "time", "Get / set time and SNTP status",
"time OR time <HH:MM> OR time sntp-status", command_func); "time OR time <HH:MM> OR time sntp-status", command_func);
// Attempt to load time from storage
esp_err_t error;
nvs_handle_t nvs;
error = nvs_open(NVS_NAMESPACE, NVS_READONLY, &nvs);
if (error == ESP_OK) {
uint64_t timestamp;
error = nvs_get_u64(nvs, TIMESTAMP_KEY, &timestamp);
if (error == ESP_OK) {
struct timeval tv = { .tv_sec = (time_t)timestamp };
settimeofday(&tv, NULL);
} else {
if (error != ESP_ERR_NVS_NOT_FOUND)
ESP_LOGE(TAG, "Error getting stored time: %04x", error);
}
nvs_close(nvs);
} else {
if (error != ESP_ERR_NVS_NOT_FOUND)
ESP_LOGE(TAG, "Error opening NVS: %04x", error);
}
// Start task to save time to storage
(void)xTaskCreate(
&time_saver_func, "time saver", CONFIG_DEFAULT_TASK_STACK, NULL, 1,
NULL);
} }
Time get_time(void) Time get_time(void)

View File

@ -30,4 +30,10 @@ menu "Bedside clock settings"
config WIFI_MAX_RETRIES config WIFI_MAX_RETRIES
int "Maximum number of times to retry connecting to WiFi network" int "Maximum number of times to retry connecting to WiFi network"
default 10 default 10
config TIME_SAVE_PERIOD_MS
int "How often (in ms) to save the time to persistent storage"
default 300000
config DEFAULT_TASK_STACK
int "Default task stack size (in words)"
default 4096
endmenu endmenu