refactor cronjobs
This commit is contained in:
@@ -31,8 +31,9 @@ const bool Cron::loadEvents()
|
||||
{
|
||||
const auto &eventName = job["name"].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"]);
|
||||
if (!addEvent(eventName, cronExpr, action))
|
||||
if (!addEvent(eventName, cronExpr, action, status))
|
||||
LOG_ERROR("Cron failed to load event [", eventName.c_str(), "]");
|
||||
else
|
||||
LOG_INFO("Cron loaded event [", eventName.c_str(), "]");
|
||||
@@ -56,21 +57,14 @@ const bool Cron::storeEvents()
|
||||
ArduinoJson::JsonDocument cronFileContent;
|
||||
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;
|
||||
thisJob["name"] = eventName;
|
||||
thisJob["cronExpr"] = cron::to_cronstr(cronExpr);
|
||||
thisJob["action"]["cmd"] = cmd;
|
||||
thisJob["action"]["params"] = cmdParams;
|
||||
|
||||
thisJob["cronExpr"] = cron::to_cronstr(eventParams.cronExpr);
|
||||
thisJob["status"] = c_statusEnum2Str.at(eventParams.status);
|
||||
thisJob["action"]["cmd"] = eventParams.cmd;
|
||||
thisJob["action"]["params"] = eventParams.cmdParams;
|
||||
cronFileArray.add(thisJob);
|
||||
}
|
||||
|
||||
@@ -83,7 +77,7 @@ const bool Cron::storeEvents()
|
||||
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);
|
||||
if (m_cronMap.contains(name))
|
||||
@@ -99,9 +93,9 @@ const bool Cron::addEvent(const std::string &name, const std::string &expr, cons
|
||||
|
||||
try
|
||||
{
|
||||
const auto eventExpr(cron::make_cron(expr));
|
||||
const auto cmd = action["cmd"].as<std::string>();
|
||||
const auto params = action["params"];
|
||||
const auto cronExpr(cron::make_cron(expr));
|
||||
if (!commands::s_commandMap.contains(cmd))
|
||||
{
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
std::tm nowTm = drivers::PCF85063::datetime2tm(now);
|
||||
auto next = cron::cron_next(eventExpr, nowTm);
|
||||
JsonDocument act(params);
|
||||
const std::tm nowTm = drivers::PCF85063::datetime2tm(now);
|
||||
const std::tm next = cron::cron_next(cronExpr, nowTm);
|
||||
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(), "]");
|
||||
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)
|
||||
{
|
||||
@@ -127,6 +121,19 @@ const bool Cron::addEvent(const std::string &name, const std::string &expr, cons
|
||||
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)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
@@ -201,38 +208,43 @@ const bool Cron::processEvents()
|
||||
|
||||
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 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 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
|
||||
{
|
||||
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 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["values"]["name"] = eventName;
|
||||
resp["values"]["now"] = drivers::PCF85063::tm2str(nowTm).c_str();
|
||||
resp["values"]["next"] = drivers::PCF85063::tm2str(next).c_str();
|
||||
resp["values"]["action"] = action;
|
||||
if (m_callback)
|
||||
resp["values"]["next"] = drivers::PCF85063::tm2str(eventParams.next).c_str();
|
||||
resp["values"]["status"] = c_statusEnum2Str.at(eventParams.status).c_str();
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user