mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-28 15:12:19 +03:00
Добавляем планировщик по типу Cron
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "ESPConfiguration.h"
|
||||
|
||||
void* getAPI_Cron(String subtype, String params);
|
||||
void* getAPI_Loging(String subtype, String params);
|
||||
void* getAPI_LogingDaily(String subtype, String params);
|
||||
void* getAPI_Timer(String subtype, String params);
|
||||
@@ -34,6 +35,7 @@ void* getAPI_Ws2812b(String subtype, String params);
|
||||
|
||||
void* getAPI(String subtype, String params) {
|
||||
void* tmpAPI;
|
||||
if ((tmpAPI = getAPI_Cron(subtype, params)) != nullptr) return tmpAPI;
|
||||
if ((tmpAPI = getAPI_Loging(subtype, params)) != nullptr) return tmpAPI;
|
||||
if ((tmpAPI = getAPI_LogingDaily(subtype, params)) != nullptr) return tmpAPI;
|
||||
if ((tmpAPI = getAPI_Timer(subtype, params)) != nullptr) return tmpAPI;
|
||||
|
||||
111
src/modules/virtual/Cron/Cron.cpp
Normal file
111
src/modules/virtual/Cron/Cron.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
#include "NTP.h"
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
extern "C" {
|
||||
#include "ccronexpr/ccronexpr.h"
|
||||
}
|
||||
|
||||
|
||||
class Cron : public IoTItem {
|
||||
private:
|
||||
bool _pause = false;
|
||||
String _format = "";
|
||||
cron_expr _expr;
|
||||
time_t _nextAlarm = 0;
|
||||
|
||||
public:
|
||||
Cron(String parameters): IoTItem(parameters) {
|
||||
jsonRead(parameters, F("formatNextAlarm"), _format);
|
||||
initCron();
|
||||
}
|
||||
|
||||
void initCron() {
|
||||
const char* err = NULL;
|
||||
memset(&_expr, 0, sizeof(_expr));
|
||||
|
||||
cron_parse_expr(value.valS.c_str(), &_expr, &err);
|
||||
if (err) {
|
||||
_pause = true;
|
||||
_nextAlarm = 0;
|
||||
memset(&_expr, 0, sizeof(_expr));
|
||||
SerialPrint("E", "Cron", F("The Cron string did not apply."), _id);
|
||||
} else
|
||||
updateNextAlarm(true);
|
||||
}
|
||||
|
||||
void updateNextAlarm(bool forced) {
|
||||
if (!_pause && _time_isTrust) {
|
||||
if (forced || (_nextAlarm <= gmtTimeToLocal(unixTime))) {
|
||||
// update alarm if next trigger is not yet in the future
|
||||
_nextAlarm = cron_next(&_expr, gmtTimeToLocal(unixTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String getNextAlarmF() {
|
||||
if (_pause) return "Pause";
|
||||
if (!_time_isTrust) return "No time";
|
||||
struct tm* timeinfo;
|
||||
char buffer [80];
|
||||
timeinfo = localtime(&_nextAlarm);
|
||||
strftime(buffer, 80, _format.c_str(), timeinfo);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
String getValue() {
|
||||
return getNextAlarmF();
|
||||
}
|
||||
|
||||
void setValue(const IoTValue& Value, bool genEvent) {
|
||||
value = Value;
|
||||
_pause = false;
|
||||
initCron();
|
||||
|
||||
if (_needSave) {
|
||||
jsonWriteStr_(valuesFlashJson, _id, value.valS);
|
||||
needSaveValues = true;
|
||||
}
|
||||
|
||||
bool _needSaveBak = _needSave;
|
||||
_needSave = false;
|
||||
regEvent(getNextAlarmF(), F("Cron alarm"), false, false);
|
||||
_needSave = _needSaveBak;
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
if (!_pause && _time_isTrust && (gmtTimeToLocal(unixTime) >= _nextAlarm)) {
|
||||
updateNextAlarm(true);
|
||||
bool _needSaveBak = _needSave;
|
||||
_needSave = false;
|
||||
regEvent(getNextAlarmF(), F("Cron alarm"));
|
||||
_needSave = _needSaveBak;
|
||||
}
|
||||
}
|
||||
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m) {
|
||||
if (command == "stop") {
|
||||
_pause = true;
|
||||
} else if (command == "continue") {
|
||||
_pause = false;
|
||||
updateNextAlarm(false);
|
||||
}
|
||||
|
||||
bool _needSaveBak = _needSave;
|
||||
_needSave = false;
|
||||
regEvent(getNextAlarmF(), F("Cron alarm"), false, false);
|
||||
_needSave = _needSaveBak;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
~Cron() {};
|
||||
};
|
||||
|
||||
void* getAPI_Cron(String subtype, String param) {
|
||||
if (subtype == F("Cron")) {
|
||||
return new Cron(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
1272
src/modules/virtual/Cron/ccronexpr/ccronexpr.c
Normal file
1272
src/modules/virtual/Cron/ccronexpr/ccronexpr.c
Normal file
File diff suppressed because it is too large
Load Diff
95
src/modules/virtual/Cron/ccronexpr/ccronexpr.h
Normal file
95
src/modules/virtual/Cron/ccronexpr/ccronexpr.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2015, alex at staticlibs.net
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: ccronexpr.h
|
||||
* Author: alex
|
||||
*
|
||||
* Created on February 24, 2015, 9:35 AM
|
||||
*/
|
||||
|
||||
#ifndef CCRONEXPR_H
|
||||
#define CCRONEXPR_H
|
||||
|
||||
#define CRON_USE_LOCAL_TIME
|
||||
|
||||
#if defined(__cplusplus) && !defined(CRON_COMPILE_AS_CXX)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef ANDROID
|
||||
#include <time.h>
|
||||
#else /* ANDROID */
|
||||
#include <time64.h>
|
||||
#endif /* ANDROID */
|
||||
|
||||
#include <stdint.h> /*added for use if uint*_t data types*/
|
||||
|
||||
/**
|
||||
* Parsed cron expression
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t seconds[8];
|
||||
uint8_t minutes[8];
|
||||
uint8_t hours[3];
|
||||
uint8_t days_of_week[1];
|
||||
uint8_t days_of_month[4];
|
||||
uint8_t months[2];
|
||||
} cron_expr;
|
||||
|
||||
/**
|
||||
* Parses specified cron expression.
|
||||
*
|
||||
* @param expression cron expression as nul-terminated string,
|
||||
* should be no longer that 256 bytes
|
||||
* @param pointer to cron expression structure, it's client code responsibility
|
||||
* to free/destroy it afterwards
|
||||
* @param error output error message, will be set to string literal
|
||||
* error message in case of error. Will be set to NULL on success.
|
||||
* The error message should NOT be freed by client.
|
||||
*/
|
||||
void cron_parse_expr(const char* expression, cron_expr* target, const char** error);
|
||||
|
||||
/**
|
||||
* Uses the specified expression to calculate the next 'fire' date after
|
||||
* the specified date. All dates are processed as UTC (GMT) dates
|
||||
* without timezones information. To use local dates (current system timezone)
|
||||
* instead of GMT compile with '-DCRON_USE_LOCAL_TIME'
|
||||
*
|
||||
* @param expr parsed cron expression to use in next date calculation
|
||||
* @param date start date to start calculation from
|
||||
* @return next 'fire' date in case of success, '((time_t) -1)' in case of error.
|
||||
*/
|
||||
time_t cron_next(cron_expr* expr, time_t date);
|
||||
|
||||
/**
|
||||
* Uses the specified expression to calculate the previous 'fire' date after
|
||||
* the specified date. All dates are processed as UTC (GMT) dates
|
||||
* without timezones information. To use local dates (current system timezone)
|
||||
* instead of GMT compile with '-DCRON_USE_LOCAL_TIME'
|
||||
*
|
||||
* @param expr parsed cron expression to use in previous date calculation
|
||||
* @param date start date to start calculation from
|
||||
* @return previous 'fire' date in case of success, '((time_t) -1)' in case of error.
|
||||
*/
|
||||
time_t cron_prev(cron_expr* expr, time_t date);
|
||||
|
||||
|
||||
#if defined(__cplusplus) && !defined(CRON_COMPILE_AS_CXX)
|
||||
} /* extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /* CCRONEXPR_H */
|
||||
57
src/modules/virtual/Cron/modinfo.json
Normal file
57
src/modules/virtual/Cron/modinfo.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"menuSection": "Виртуальные элементы",
|
||||
"configItem": [
|
||||
{
|
||||
"global": 0,
|
||||
"name": "Будильник (Cron)",
|
||||
"type": "Writing",
|
||||
"subtype": "Cron",
|
||||
"id": "cron",
|
||||
"widget": "anydataDef",
|
||||
"page": "Таймеры",
|
||||
"descr": "Будильник",
|
||||
"int": 1,
|
||||
"val": "*/15 * * * * *",
|
||||
"formatNextAlarm": "%H:%M:%S",
|
||||
"needSave": 0
|
||||
}
|
||||
],
|
||||
"about": {
|
||||
"authorName": "Ilya Belyakov",
|
||||
"authorContact": "https://t.me/Biveraxe",
|
||||
"authorGit": "https://github.com/biveraxe",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Cron",
|
||||
"moduleVersion": "1.0",
|
||||
"usedRam": {
|
||||
"esp32_4mb": 15,
|
||||
"esp8266_4mb": 15
|
||||
},
|
||||
"title": "Будильник типа Cron",
|
||||
"moduleDesc": "Планировщик времени для периодического выполнения заданий в определённое время. Генерирует событие в указанное время по формату Cron https://ru.wikipedia.org/wiki/Cron ",
|
||||
"propInfo": {
|
||||
"formatNextAlarm": "Формат представления даты и времени срабатывания следующего уведомления. http://cppstudio.com/post/621/",
|
||||
"needSave": "Требуется сохранять(1) или нет(0) состояние в энерго независимую память."
|
||||
},
|
||||
"retInfo": "Содержит время следующего срабатывания.",
|
||||
"funcInfo": [
|
||||
{
|
||||
"name": "stop",
|
||||
"descr": "Поставить процесс на паузу, при этом не будет событий.",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"name": "continue",
|
||||
"descr": "Продолжить выполнение с момента остановки.",
|
||||
"params": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"defActive": true,
|
||||
"usedLibs": {
|
||||
"esp32_4mb": [],
|
||||
"esp8266_4mb": [],
|
||||
"esp8266_1mb": [],
|
||||
"esp8266_1mb_ota": []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user