You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.5 KiB
99 lines
2.5 KiB
// Copyright (c) 2020 Lukasz Chodyla |
|
// Distributed under the MIT License. |
|
// See accompanying file LICENSE.txt for the full license. |
|
|
|
#include "nx/firmware/Restarter.h" |
|
|
|
#include "esp_log.h" |
|
#include "esp_system.h" |
|
#include "freertos/FreeRTOS.h" |
|
#include "freertos/task.h" |
|
#include <time.h> |
|
#include <string.h> |
|
|
|
#define TAG "RESTARTER" |
|
|
|
#define RESTARTER_CHECK_INTERVAL_SEC 10 |
|
#define RESTART_SCHEDULE_SIZE 12 |
|
#define RESTART_SCHEDULE_MIN_LEN 7 // 'x x x x' |
|
|
|
const char* schedule = ""; |
|
const char* tz = ""; |
|
|
|
// day - days from sunday (0 is sunday), schedule - binary schedule from sunday (1 is sunday, 64 is saturday) |
|
int isDayInSchedule(int day, int schedule) |
|
{ |
|
int dayMatch = 1 << day; |
|
int match = (dayMatch & schedule); |
|
return match != 0; |
|
} |
|
|
|
void restarterTask(void* param) |
|
{ |
|
//UNUSED(param); |
|
ESP_LOGI(TAG, "Starting restarter task"); |
|
|
|
if (strlen(schedule) < RESTART_SCHEDULE_MIN_LEN) { |
|
ESP_LOGW(TAG, "Closing restarter task due to the incomplete schedule: [%s]", schedule); |
|
vTaskDelete( NULL ); |
|
return; |
|
} |
|
|
|
long int intervalMs = 1000 * RESTARTER_CHECK_INTERVAL_SEC; |
|
|
|
char scheduleLine[RESTART_SCHEDULE_SIZE]; |
|
strcpy(scheduleLine, schedule); |
|
|
|
int daySchedule = atoi( strtok(scheduleLine, " ") ); |
|
int hour = atoi( strtok(NULL, " ") ); |
|
int minute = atoi( strtok(NULL, " ") ); |
|
int maxUptime = atoi( strtok(NULL, " ") ); |
|
|
|
ESP_LOGI(TAG, "Restart schedule: %i %i %i %i", daySchedule, hour, minute, maxUptime); |
|
|
|
if (daySchedule == 0) { |
|
ESP_LOGI(TAG, "Closing restarter task due to zero days in schedule"); |
|
vTaskDelete( NULL ); |
|
return; |
|
} |
|
|
|
while (1) { |
|
vTaskDelay(intervalMs / portTICK_PERIOD_MS); |
|
|
|
int uptimeMin = portTICK_PERIOD_MS * xTaskGetTickCount() / 1000 / 60; |
|
|
|
time_t now; |
|
struct tm timeinfo; |
|
time(&now); |
|
|
|
// Set timezone to Eastern Standard Time and print local time |
|
setenv("TZ", tz, 1); |
|
tzset(); |
|
localtime_r(&now, &timeinfo); |
|
|
|
if (uptimeMin < maxUptime) { |
|
continue; |
|
} |
|
if (!isDayInSchedule(timeinfo.tm_wday, daySchedule)) { |
|
continue; |
|
} |
|
if (hour != timeinfo.tm_hour || hour == -1) { |
|
continue; |
|
} |
|
if (minute != timeinfo.tm_min) { |
|
continue; |
|
} |
|
|
|
ESP_LOGI(TAG, "all conditions met, restarting..."); |
|
esp_restart(); |
|
} |
|
} |
|
|
|
void nxStartRestarter(const char* scheduleString, const char* timezone) |
|
{ |
|
schedule = scheduleString; |
|
tz = timezone; |
|
|
|
xTaskCreate(restarterTask, "restarter_task", 2048, |
|
(void*)1, tskIDLE_PRIORITY, NULL); |
|
}
|
|
|