refactor cronjobs
This commit is contained in:
72
.vscode/settings.json
vendored
72
.vscode/settings.json
vendored
@@ -1,5 +1,75 @@
|
|||||||
{
|
{
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"esp32-hal.h": "c"
|
"*.h": "cpp",
|
||||||
|
"esp32-hal.h": "c",
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"bit": "cpp",
|
||||||
|
"bitset": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"charconv": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"codecvt": "cpp",
|
||||||
|
"compare": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"condition_variable": "cpp",
|
||||||
|
"cstdarg": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"unordered_set": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"netfwd": "cpp",
|
||||||
|
"numeric": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"ratio": "cpp",
|
||||||
|
"source_location": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"format": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iomanip": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"mutex": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"numbers": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"semaphore": "cpp",
|
||||||
|
"span": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"stop_token": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"text_encoding": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"cinttypes": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"variant": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,10 +71,10 @@ namespace commands
|
|||||||
response["values"]["status"] = "valid";
|
response["values"]["status"] = "valid";
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
const ArduinoJson::JsonDocument Commands::setCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
const ArduinoJson::JsonDocument Commands::addCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
||||||
{
|
{
|
||||||
ArduinoJson::JsonDocument response;
|
ArduinoJson::JsonDocument response;
|
||||||
response["cmd"] = "setCronJob";
|
response["cmd"] = "addCronJob";
|
||||||
|
|
||||||
const auto &eventName = params["name"].as<std::string>();
|
const auto &eventName = params["name"].as<std::string>();
|
||||||
const auto &timeStr = params["cronExpr"].as<std::string>();
|
const auto &timeStr = params["cronExpr"].as<std::string>();
|
||||||
@@ -84,7 +84,7 @@ namespace commands
|
|||||||
ArduinoJson::JsonDocument action;
|
ArduinoJson::JsonDocument action;
|
||||||
if (ArduinoJson::deserializeJson(action, actionStr) != ArduinoJson::DeserializationError::Ok)
|
if (ArduinoJson::deserializeJson(action, actionStr) != ArduinoJson::DeserializationError::Ok)
|
||||||
{
|
{
|
||||||
LOG_ERROR("setCronJob unable to deserialize cron job [", actionStr.c_str(), "]");
|
LOG_ERROR("addCronJob unable to deserialize cron job [", actionStr.c_str(), "]");
|
||||||
response["values"]["status"] = "invalid";
|
response["values"]["status"] = "invalid";
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -92,11 +92,31 @@ namespace commands
|
|||||||
auto &cron = Cron::getInstance(dev);
|
auto &cron = Cron::getInstance(dev);
|
||||||
if (!cron.addEvent(eventName, timeStr, action))
|
if (!cron.addEvent(eventName, timeStr, action))
|
||||||
{
|
{
|
||||||
LOG_ERROR("setCronJob unable to add job [", actionStr.c_str(), "]");
|
LOG_ERROR("addCronJob unable to add job [", actionStr.c_str(), "]");
|
||||||
response["values"]["status"] = "invalid";
|
response["values"]["status"] = "invalid";
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
LOG_INFO("setCronJob added job [", actionStr.c_str(), "]");
|
LOG_INFO("addCronJob added job [", actionStr.c_str(), "]");
|
||||||
|
response["values"]["status"] = "valid";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
const ArduinoJson::JsonDocument Commands::setCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
||||||
|
{
|
||||||
|
ArduinoJson::JsonDocument response;
|
||||||
|
response["cmd"] = "setCronJob";
|
||||||
|
const auto &eventName = params["name"].as<std::string>();
|
||||||
|
const auto &statusStr = params["status"].as<std::string>();
|
||||||
|
response["values"]["name"] = eventName;
|
||||||
|
|
||||||
|
auto &cron = Cron::getInstance(dev);
|
||||||
|
if (!cron.c_statusStr2Enum.contains(statusStr))
|
||||||
|
{
|
||||||
|
LOG_ERROR("setCronJob invalid status [", statusStr.c_str(), "]");
|
||||||
|
response["values"]["status"] = "invalid";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
cron.setEvent(eventName, cron.c_statusStr2Enum.at(statusStr));
|
||||||
|
LOG_INFO("setCronJob set job [", eventName.c_str(), "] to [", statusStr.c_str(), "]");
|
||||||
response["values"]["status"] = "valid";
|
response["values"]["status"] = "valid";
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -120,8 +140,7 @@ namespace commands
|
|||||||
uint8_t eventNum(0);
|
uint8_t eventNum(0);
|
||||||
for (const auto &[name, event] : eventMap)
|
for (const auto &[name, event] : eventMap)
|
||||||
{
|
{
|
||||||
const auto cmd = std::get<0>(event);
|
response["values"][name] = event.cmd;
|
||||||
response["values"][name] = cmd;
|
|
||||||
eventNum++;
|
eventNum++;
|
||||||
}
|
}
|
||||||
LOG_INFO("getCronJob got [", eventNum, "] events");
|
LOG_INFO("getCronJob got [", eventNum, "] events");
|
||||||
@@ -137,16 +156,11 @@ namespace commands
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cmd = std::get<0>(event);
|
|
||||||
auto cronExpr = std::get<1>(event);
|
|
||||||
auto cmdParams = std::get<3>(event);
|
|
||||||
|
|
||||||
ArduinoJson::JsonDocument action;
|
ArduinoJson::JsonDocument action;
|
||||||
action["cmd"] = cmd;
|
action["cmd"] = event.cmd;
|
||||||
action["params"] = cmdParams;
|
action["params"] = event.cmdParams;
|
||||||
response["values"]["cronExpr"] = cron::to_cronstr(cronExpr);
|
response["values"]["cronExpr"] = cron::to_cronstr(event.cronExpr);
|
||||||
response["values"]["action"] = action;
|
response["values"]["action"] = action;
|
||||||
|
|
||||||
LOG_INFO("getCronJob get job [", eventName.c_str(), "]");
|
LOG_INFO("getCronJob get job [", eventName.c_str(), "]");
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -283,7 +297,6 @@ namespace commands
|
|||||||
const std::string zone(params["zone"].as<std::string>());
|
const std::string zone(params["zone"].as<std::string>());
|
||||||
const uint16_t tOn(params["timeOn"].as<uint16_t>());
|
const uint16_t tOn(params["timeOn"].as<uint16_t>());
|
||||||
const uint16_t tPause(params["timePause"].as<uint16_t>());
|
const uint16_t tPause(params["timePause"].as<uint16_t>());
|
||||||
|
|
||||||
response["values"]["zone"] = zone;
|
response["values"]["zone"] = zone;
|
||||||
|
|
||||||
if (zone == "stop")
|
if (zone == "stop")
|
||||||
@@ -304,7 +317,7 @@ namespace commands
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_INFO("setIrrigation closing", zoneName.c_str());
|
LOG_INFO("setIrrigation closing", zoneName.c_str());
|
||||||
dev.io.digitalOutWrite(c_irrigationValveMap.at(zoneName), false); // shuto down the valve
|
dev.io.digitalOutWrite(c_irrigationValveMap.at(zoneName), false); // shutdown the valve
|
||||||
}
|
}
|
||||||
if (s_irrigationPumpTimer)
|
if (s_irrigationPumpTimer)
|
||||||
{
|
{
|
||||||
@@ -315,6 +328,13 @@ namespace commands
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_rainOverride && !dev.io.digitalInRead(DI::RAIN)) // verify rain sensor and override value (rain sensor input is inverted)
|
||||||
|
{
|
||||||
|
LOG_WARN("setIrrigation skipping zone [", zone.c_str(), "] because its raining");
|
||||||
|
response["values"]["status"] = "rain";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
response["values"]["timeOn"] = tOn;
|
response["values"]["timeOn"] = tOn;
|
||||||
response["values"]["timePause"] = tPause;
|
response["values"]["timePause"] = tPause;
|
||||||
if (!c_irrigationValveMap.contains(zone) || tOn <= 0 || tPause <= 0) // verify if zone is a valid map key
|
if (!c_irrigationValveMap.contains(zone) || tOn <= 0 || tPause <= 0) // verify if zone is a valid map key
|
||||||
@@ -360,6 +380,7 @@ namespace commands
|
|||||||
if (shTimer)
|
if (shTimer)
|
||||||
{
|
{
|
||||||
dev.io.digitalOutWrite(zoneIoNumber, true);
|
dev.io.digitalOutWrite(zoneIoNumber, true);
|
||||||
|
// controllare riempimento serbatoio con controllo del pressostato, magari in un timer
|
||||||
xTimerStart(shTimer, 0);
|
xTimerStart(shTimer, 0);
|
||||||
timerHandle = shTimer;
|
timerHandle = shTimer;
|
||||||
response["values"]["status"] = "valid";
|
response["values"]["status"] = "valid";
|
||||||
@@ -367,6 +388,20 @@ namespace commands
|
|||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
const ArduinoJson::JsonDocument Commands::setRainOverride(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
||||||
|
{
|
||||||
|
ArduinoJson::JsonDocument response;
|
||||||
|
response["cmd"] = "setRainOverride";
|
||||||
|
if (params.isNull())
|
||||||
|
{
|
||||||
|
LOG_ERROR("setRainOverride incorrect paramaters");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
s_rainOverride = params["rainOverride"].as<std::string>() == "True" ? true : false;
|
||||||
|
response["values"]["status"] = "valid";
|
||||||
|
LOG_INFO("setRainOverride [", s_rainOverride ? "True]" : "False]");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
const ArduinoJson::JsonDocument Commands::setTimeNTP(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
const ArduinoJson::JsonDocument Commands::setTimeNTP(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
||||||
{
|
{
|
||||||
ArduinoJson::JsonDocument response;
|
ArduinoJson::JsonDocument response;
|
||||||
@@ -477,6 +512,13 @@ namespace commands
|
|||||||
LOG_WARN("Comand not yet implemented");
|
LOG_WARN("Comand not yet implemented");
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
const ArduinoJson::JsonDocument Commands::getRainOverride(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
||||||
|
{
|
||||||
|
ArduinoJson::JsonDocument response;
|
||||||
|
response["cmd"] = "getRainOverride";
|
||||||
|
response["values"]["rainOverride"] = s_rainOverride ? "True" : "False";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
const ArduinoJson::JsonDocument Commands::getTimeDrift(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
const ArduinoJson::JsonDocument Commands::getTimeDrift(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
||||||
{
|
{
|
||||||
ArduinoJson::JsonDocument response;
|
ArduinoJson::JsonDocument response;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ namespace commands
|
|||||||
{"rubinetti", {"rubinetti", NULL}}};
|
{"rubinetti", {"rubinetti", NULL}}};
|
||||||
|
|
||||||
static TimerHandle_t s_irrigationPumpTimer = NULL;
|
static TimerHandle_t s_irrigationPumpTimer = NULL;
|
||||||
|
static bool s_rainOverride = false;
|
||||||
|
|
||||||
// define command callback type
|
// define command callback type
|
||||||
using Command = std::function<const ArduinoJson::JsonDocument(const devices_t &, const ArduinoJson::JsonDocument &)>;
|
using Command = std::function<const ArduinoJson::JsonDocument(const devices_t &, const ArduinoJson::JsonDocument &)>;
|
||||||
@@ -53,6 +54,7 @@ namespace commands
|
|||||||
|
|
||||||
// CRONJOBS //
|
// CRONJOBS //
|
||||||
static const ArduinoJson::JsonDocument loadCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument loadCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
|
static const ArduinoJson::JsonDocument addCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
static const ArduinoJson::JsonDocument setCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument setCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
static const ArduinoJson::JsonDocument getCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument getCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
static const ArduinoJson::JsonDocument delCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument delCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
@@ -62,6 +64,7 @@ namespace commands
|
|||||||
static const ArduinoJson::JsonDocument setHPlimit(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument setHPlimit(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
static const ArduinoJson::JsonDocument setHeating(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument setHeating(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
static const ArduinoJson::JsonDocument setIrrigation(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument setIrrigation(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
|
static const ArduinoJson::JsonDocument setRainOverride(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
static const ArduinoJson::JsonDocument setTimeNTP(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument setTimeNTP(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
|
|
||||||
// GETTERS //
|
// GETTERS //
|
||||||
@@ -73,6 +76,7 @@ namespace commands
|
|||||||
static const ArduinoJson::JsonDocument getTankInfo(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument getTankInfo(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
static const ArduinoJson::JsonDocument getRainInfo(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument getRainInfo(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
static const ArduinoJson::JsonDocument getIrrigation(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument getIrrigation(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
|
static const ArduinoJson::JsonDocument getRainOverride(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
static const ArduinoJson::JsonDocument getTimeDrift(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
static const ArduinoJson::JsonDocument getTimeDrift(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -84,6 +88,7 @@ namespace commands
|
|||||||
{"getConfig", Commands::getConfig},
|
{"getConfig", Commands::getConfig},
|
||||||
// CRONJOBS
|
// CRONJOBS
|
||||||
{"loadCronJob", Commands::loadCronJob},
|
{"loadCronJob", Commands::loadCronJob},
|
||||||
|
{"addCronJob", Commands::addCronJob},
|
||||||
{"setCronJob", Commands::setCronJob},
|
{"setCronJob", Commands::setCronJob},
|
||||||
{"getCronJob", Commands::getCronJob},
|
{"getCronJob", Commands::getCronJob},
|
||||||
{"delCronJob", Commands::delCronJob},
|
{"delCronJob", Commands::delCronJob},
|
||||||
@@ -92,10 +97,12 @@ namespace commands
|
|||||||
{"setHPlimit", Commands::setHPlimit},
|
{"setHPlimit", Commands::setHPlimit},
|
||||||
{"setHeating", Commands::setHeating},
|
{"setHeating", Commands::setHeating},
|
||||||
{"setIrrigation", Commands::setIrrigation},
|
{"setIrrigation", Commands::setIrrigation},
|
||||||
|
{"setRainOverride", Commands::setRainOverride},
|
||||||
// GETTERS
|
// GETTERS
|
||||||
{"getHPpower", Commands::getHPpower},
|
{"getHPpower", Commands::getHPpower},
|
||||||
{"getInputStatus", Commands::getInputStatus},
|
{"getInputStatus", Commands::getInputStatus},
|
||||||
{"getOutputStatus", Commands::getOutputStatus},
|
{"getOutputStatus", Commands::getOutputStatus},
|
||||||
|
{"getRainOverride", Commands::getRainOverride},
|
||||||
// NTP and Time
|
// NTP and Time
|
||||||
{"getTimeDrift", Commands::getTimeDrift},
|
{"getTimeDrift", Commands::getTimeDrift},
|
||||||
{"setTimeNTP", Commands::setTimeNTP},
|
{"setTimeNTP", Commands::setTimeNTP},
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ const bool Cron::loadEvents()
|
|||||||
{
|
{
|
||||||
const auto &eventName = job["name"].as<std::string>();
|
const auto &eventName = job["name"].as<std::string>();
|
||||||
const auto &cronExpr = job["cronExpr"].as<std::string>();
|
const auto &cronExpr = job["cronExpr"].as<std::string>();
|
||||||
|
const auto status = c_statusStr2Enum.at(job["status"].as<std::string>());
|
||||||
ArduinoJson::JsonDocument action(job["action"]);
|
ArduinoJson::JsonDocument action(job["action"]);
|
||||||
if (!addEvent(eventName, cronExpr, action))
|
if (!addEvent(eventName, cronExpr, action, status))
|
||||||
LOG_ERROR("Cron failed to load event [", eventName.c_str(), "]");
|
LOG_ERROR("Cron failed to load event [", eventName.c_str(), "]");
|
||||||
else
|
else
|
||||||
LOG_INFO("Cron loaded event [", eventName.c_str(), "]");
|
LOG_INFO("Cron loaded event [", eventName.c_str(), "]");
|
||||||
@@ -56,21 +57,14 @@ const bool Cron::storeEvents()
|
|||||||
ArduinoJson::JsonDocument cronFileContent;
|
ArduinoJson::JsonDocument cronFileContent;
|
||||||
ArduinoJson::JsonArray cronFileArray = cronFileContent.to<JsonArray>();
|
ArduinoJson::JsonArray cronFileArray = cronFileContent.to<JsonArray>();
|
||||||
|
|
||||||
for (const auto &job : m_cronMap) // convert cron events map to json file
|
for (const auto &[eventName, eventParams] : m_cronMap) // convert cron events map to json file
|
||||||
{
|
{
|
||||||
const auto &eventName = job.first;
|
|
||||||
const auto ¶ms = job.second;
|
|
||||||
|
|
||||||
const auto &cmd = std::get<0>(params);
|
|
||||||
const auto &cronExpr = std::get<1>(params);
|
|
||||||
const auto &cmdParams = std::get<3>(params);
|
|
||||||
|
|
||||||
ArduinoJson::JsonDocument thisJob;
|
ArduinoJson::JsonDocument thisJob;
|
||||||
thisJob["name"] = eventName;
|
thisJob["name"] = eventName;
|
||||||
thisJob["cronExpr"] = cron::to_cronstr(cronExpr);
|
thisJob["cronExpr"] = cron::to_cronstr(eventParams.cronExpr);
|
||||||
thisJob["action"]["cmd"] = cmd;
|
thisJob["status"] = c_statusEnum2Str.at(eventParams.status);
|
||||||
thisJob["action"]["params"] = cmdParams;
|
thisJob["action"]["cmd"] = eventParams.cmd;
|
||||||
|
thisJob["action"]["params"] = eventParams.cmdParams;
|
||||||
cronFileArray.add(thisJob);
|
cronFileArray.add(thisJob);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +77,7 @@ const bool Cron::storeEvents()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool Cron::addEvent(const std::string &name, const std::string &expr, const ArduinoJson::JsonDocument action)
|
const bool Cron::addEvent(const std::string &name, const std::string &expr, const ArduinoJson::JsonDocument action, const CronStatus status)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_mutex);
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
if (m_cronMap.contains(name))
|
if (m_cronMap.contains(name))
|
||||||
@@ -99,9 +93,9 @@ const bool Cron::addEvent(const std::string &name, const std::string &expr, cons
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const auto eventExpr(cron::make_cron(expr));
|
|
||||||
const auto cmd = action["cmd"].as<std::string>();
|
const auto cmd = action["cmd"].as<std::string>();
|
||||||
const auto params = action["params"];
|
const auto params = action["params"];
|
||||||
|
const auto cronExpr(cron::make_cron(expr));
|
||||||
if (!commands::s_commandMap.contains(cmd))
|
if (!commands::s_commandMap.contains(cmd))
|
||||||
{
|
{
|
||||||
LOG_ERROR("Cron unknown command [", cmd.c_str(), "]");
|
LOG_ERROR("Cron unknown command [", cmd.c_str(), "]");
|
||||||
@@ -113,11 +107,11 @@ const bool Cron::addEvent(const std::string &name, const std::string &expr, cons
|
|||||||
LOG_ERROR("Cron unable to update current time");
|
LOG_ERROR("Cron unable to update current time");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::tm nowTm = drivers::PCF85063::datetime2tm(now);
|
const std::tm nowTm = drivers::PCF85063::datetime2tm(now);
|
||||||
auto next = cron::cron_next(eventExpr, nowTm);
|
const std::tm next = cron::cron_next(cronExpr, nowTm);
|
||||||
JsonDocument act(params);
|
JsonDocument cmdParams(params); // create a copy of command parameters
|
||||||
LOG_INFO("Cron adding event [", name.c_str(), "] next execution [", drivers::PCF85063::tm2str(next).c_str(), "]");
|
LOG_INFO("Cron adding event [", name.c_str(), "] next execution [", drivers::PCF85063::tm2str(next).c_str(), "]");
|
||||||
m_cronMap[name] = std::make_tuple(cmd, eventExpr, next, act);
|
m_cronMap[name] = CronEvent(cmd, cmdParams, cronExpr, next, status);
|
||||||
}
|
}
|
||||||
catch (cron::bad_cronexpr const &ex)
|
catch (cron::bad_cronexpr const &ex)
|
||||||
{
|
{
|
||||||
@@ -127,6 +121,19 @@ const bool Cron::addEvent(const std::string &name, const std::string &expr, cons
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool Cron::setEvent(const std::string &name, const CronStatus status)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
if (!m_cronMap.contains(name))
|
||||||
|
{
|
||||||
|
LOG_ERROR("Cron event [", name.c_str(), "] does not exist");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG_INFO("Cron set event [", name.c_str(), "] status [", c_statusEnum2Str.at(status).c_str(), "]");
|
||||||
|
m_cronMap.at(name).status = status;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const bool Cron::getEvent(const std::string &name, CronEvent &event)
|
const bool Cron::getEvent(const std::string &name, CronEvent &event)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_mutex);
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
@@ -201,38 +208,43 @@ const bool Cron::processEvents()
|
|||||||
|
|
||||||
std::tm nowTm = drivers::PCF85063::datetime2tm(now);
|
std::tm nowTm = drivers::PCF85063::datetime2tm(now);
|
||||||
|
|
||||||
for (auto &event : m_cronMap)
|
for (auto &[eventName, eventParams] : m_cronMap)
|
||||||
{
|
{
|
||||||
auto &eventName = event.first;
|
|
||||||
auto &eventAction = event.second;
|
|
||||||
|
|
||||||
auto &cmd = std::get<0>(eventAction);
|
|
||||||
auto &cronexrp = std::get<1>(eventAction);
|
|
||||||
auto &next = std::get<2>(eventAction);
|
|
||||||
auto &cmdParams = std::get<3>(eventAction);
|
|
||||||
|
|
||||||
const auto nowPoint = std::chrono::system_clock::from_time_t(std::mktime(&nowTm));
|
const auto nowPoint = std::chrono::system_clock::from_time_t(std::mktime(&nowTm));
|
||||||
const auto nextEventPoint = std::chrono::system_clock::from_time_t(std::mktime(&next));
|
const auto nextEventPoint = std::chrono::system_clock::from_time_t(std::mktime(&eventParams.next));
|
||||||
|
|
||||||
LOG_DEBUG("Cron current time [", std::asctime(&nowTm), "]");
|
LOG_DEBUG("Cron current time [", std::asctime(&nowTm), "]");
|
||||||
LOG_DEBUG("Cron checking event [", eventName.c_str(), "] executionTime [", drivers::PCF85063::tm2str(next).c_str(), "]");
|
LOG_DEBUG("Cron checking event [", eventName.c_str(), "] executionTime [", drivers::PCF85063::tm2str(eventParams.next).c_str(), "]");
|
||||||
|
|
||||||
if (nextEventPoint <= nowPoint) // execution time hs passed, run event
|
if (nextEventPoint <= nowPoint) // execution time hs passed, run event
|
||||||
{
|
{
|
||||||
next = cron::cron_next(cronexrp, nowTm); // update next execution time only if event was executed
|
|
||||||
// otherwise time tracking is lost
|
|
||||||
LOG_INFO("Cron running event [", eventName.c_str(), "] next execution time [", drivers::PCF85063::tm2str(next).c_str(), "]");
|
|
||||||
auto action = commands::s_commandMap.at(cmd)(m_dev, cmdParams); // here the magic happens
|
|
||||||
ArduinoJson::JsonDocument resp;
|
ArduinoJson::JsonDocument resp;
|
||||||
|
ArduinoJson::JsonDocument action;
|
||||||
|
eventParams.next = cron::cron_next(eventParams.cronExpr, nowTm); // update next execution time only if event was executed, otherwise time tracking is lost
|
||||||
resp["cmd"] = "logCronJob";
|
resp["cmd"] = "logCronJob";
|
||||||
resp["values"]["name"] = eventName;
|
resp["values"]["name"] = eventName;
|
||||||
resp["values"]["now"] = drivers::PCF85063::tm2str(nowTm).c_str();
|
resp["values"]["now"] = drivers::PCF85063::tm2str(nowTm).c_str();
|
||||||
resp["values"]["next"] = drivers::PCF85063::tm2str(next).c_str();
|
resp["values"]["next"] = drivers::PCF85063::tm2str(eventParams.next).c_str();
|
||||||
resp["values"]["action"] = action;
|
resp["values"]["status"] = c_statusEnum2Str.at(eventParams.status).c_str();
|
||||||
if (m_callback)
|
switch (eventParams.status)
|
||||||
{
|
{
|
||||||
m_callback(resp);
|
case CronStatus::ACTIVE:
|
||||||
|
LOG_INFO("Cron running ACTIVE event [", eventName.c_str(), "] next execution time [", drivers::PCF85063::tm2str(eventParams.next).c_str(), "]");
|
||||||
|
action = commands::s_commandMap.at(eventParams.cmd)(m_dev, eventParams.cmdParams); // here the magic happens
|
||||||
|
resp["values"]["action"] = action;
|
||||||
|
break;
|
||||||
|
case CronStatus::INACTIVE:
|
||||||
|
LOG_INFO("Cron skipping INACTIVE event [", eventName.c_str(), "] next execution time [", drivers::PCF85063::tm2str(eventParams.next).c_str(), "]");
|
||||||
|
break;
|
||||||
|
case CronStatus::SKIP:
|
||||||
|
LOG_INFO("Cron skipping 1 time ACTIVE event [", eventName.c_str(), "] next execution time [", drivers::PCF85063::tm2str(eventParams.next).c_str(), "]");
|
||||||
|
eventParams.status = CronStatus::ACTIVE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (m_callback)
|
||||||
|
m_callback(resp); // execute cronLog callback action
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -15,8 +15,33 @@
|
|||||||
|
|
||||||
class Cron
|
class Cron
|
||||||
{
|
{
|
||||||
public: // eventName cronExpression nextExec command parameters
|
public:
|
||||||
using CronEvent = std::tuple<std::string, cron::cronexpr, std::tm, ArduinoJson::JsonDocument>;
|
enum class CronStatus
|
||||||
|
{
|
||||||
|
ACTIVE,
|
||||||
|
INACTIVE,
|
||||||
|
SKIP
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<CronStatus, std::string> c_statusEnum2Str = {
|
||||||
|
{CronStatus::ACTIVE, "ACTIVE"},
|
||||||
|
{CronStatus::INACTIVE, "INACTIVE"},
|
||||||
|
{CronStatus::SKIP, "SKIP"}};
|
||||||
|
|
||||||
|
const std::map<std::string, CronStatus> c_statusStr2Enum = {
|
||||||
|
{"ACTIVE", CronStatus::ACTIVE},
|
||||||
|
{"INACTIVE", CronStatus::INACTIVE},
|
||||||
|
{"SKIP", CronStatus::SKIP}};
|
||||||
|
|
||||||
|
struct CronEvent
|
||||||
|
{
|
||||||
|
std::string cmd;
|
||||||
|
ArduinoJson::JsonDocument cmdParams;
|
||||||
|
cron::cronexpr cronExpr;
|
||||||
|
std::tm next;
|
||||||
|
CronStatus status;
|
||||||
|
};
|
||||||
|
|
||||||
using CronEventMap = std::map<std::string, CronEvent>;
|
using CronEventMap = std::map<std::string, CronEvent>;
|
||||||
using CronCallback = std::function<void(const ArduinoJson::JsonDocument &)>;
|
using CronCallback = std::function<void(const ArduinoJson::JsonDocument &)>;
|
||||||
|
|
||||||
@@ -40,7 +65,8 @@ public:
|
|||||||
|
|
||||||
const bool loadEvents();
|
const bool loadEvents();
|
||||||
const bool storeEvents();
|
const bool storeEvents();
|
||||||
const bool addEvent(const std::string &name, const std::string &expr, const ArduinoJson::JsonDocument action);
|
const bool addEvent(const std::string &name, const std::string &expr, const ArduinoJson::JsonDocument action, const CronStatus status = CronStatus::ACTIVE);
|
||||||
|
const bool setEvent(const std::string &name, const CronStatus status);
|
||||||
const bool getEvent(const std::string &name, CronEvent &event);
|
const bool getEvent(const std::string &name, CronEvent &event);
|
||||||
const bool delEvent(const std::string &name);
|
const bool delEvent(const std::string &name);
|
||||||
const CronEventMap &getAllEvents();
|
const CronEventMap &getAllEvents();
|
||||||
|
|||||||
Reference in New Issue
Block a user