Merge remote-tracking branch 'origin/pro-develop' into pro-develop
This commit is contained in:
@@ -10,8 +10,8 @@ namespace drivers
|
|||||||
{
|
{
|
||||||
LOG_INFO("Inizializing RGB Led");
|
LOG_INFO("Inizializing RGB Led");
|
||||||
pinMode(c_ledPin, OUTPUT);
|
pinMode(c_ledPin, OUTPUT);
|
||||||
m_lp.pin = c_ledPin;
|
m_blinkTask = NULL;
|
||||||
m_lp.blinkTask = NULL;
|
m_flashTimer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Led::~Led()
|
Led::~Led()
|
||||||
@@ -22,54 +22,85 @@ namespace drivers
|
|||||||
|
|
||||||
void Led::setColor(const color_t color)
|
void Led::setColor(const color_t color)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_ledMutex);
|
||||||
blinkStop();
|
blinkStop();
|
||||||
|
m_colorDefault = color;
|
||||||
rgbLedWrite(c_ledPin, color.g, color.r, color.b);
|
rgbLedWrite(c_ledPin, color.g, color.r, color.b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Led::flashHandle(TimerHandle_t th)
|
||||||
|
{
|
||||||
|
Led *led = (Led *)pvTimerGetTimerID(th);
|
||||||
|
std::lock_guard<std::mutex> lock(led->m_ledMutex);
|
||||||
|
rgbLedWrite(led->c_ledPin, led->m_colorDefault.g, led->m_colorDefault.r, led->m_colorDefault.b); // reset color to saved color
|
||||||
|
LOG_DEBUG("Led Flash timer expired");
|
||||||
|
xTimerDelete(th, 0);
|
||||||
|
led->m_flashTimer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Led::flashColor(const uint16_t tOn, const color_t color)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_ledMutex);
|
||||||
|
if (m_flashTimer == NULL)
|
||||||
|
{
|
||||||
|
blinkStop();
|
||||||
|
rgbLedWrite(c_ledPin, color.g, color.r, color.b); // set color to flash
|
||||||
|
m_flashTimer = xTimerCreate("flasher", pdMS_TO_TICKS(tOn), pdFALSE, this, flashHandle);
|
||||||
|
xTimerStart(m_flashTimer, 0);
|
||||||
|
LOG_DEBUG("Led Flash timer created");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Led::blinkColor(const uint16_t tOn, const uint16_t tOff, const color_t color)
|
void Led::blinkColor(const uint16_t tOn, const uint16_t tOff, const color_t color)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_ledMutex);
|
||||||
blinkStop();
|
blinkStop();
|
||||||
m_lp.color1 = color;
|
m_color1 = color;
|
||||||
m_lp.color2 = {0, 0, 0};
|
m_color2 = {0, 0, 0};
|
||||||
m_lp.tOn = tOn;
|
m_tOn = tOn;
|
||||||
m_lp.tOff = tOff;
|
m_tOff = tOff;
|
||||||
xTaskCreate(blinkTask, "blinker", TASK_STACK, static_cast<void *>(&m_lp), TASK_PRIORITY, &m_lp.blinkTask);
|
xTaskCreate(blinkTask, "blinker", TASK_STACK, this, TASK_PRIORITY, &m_blinkTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Led::blinkAlternate(const uint16_t tOn, const uint16_t tOff, const color_t color1, const color_t color2)
|
void Led::blinkAlternate(const uint16_t tOn, const uint16_t tOff, const color_t color1, const color_t color2)
|
||||||
{
|
{
|
||||||
{
|
std::lock_guard<std::mutex> lock(m_ledMutex);
|
||||||
blinkStop();
|
blinkStop();
|
||||||
m_lp.color1 = color1;
|
m_color1 = color1;
|
||||||
m_lp.color2 = color2;
|
m_color2 = color2;
|
||||||
m_lp.tOn = tOn;
|
m_tOn = tOn;
|
||||||
m_lp.tOff = tOff;
|
m_tOff = tOff;
|
||||||
xTaskCreate(blinkTask, "blinker", TASK_STACK, static_cast<void *>(&m_lp), TASK_PRIORITY, &m_lp.blinkTask);
|
xTaskCreate(blinkTask, "blinker", TASK_STACK, this, TASK_PRIORITY, &m_blinkTask);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Led::blinkStop()
|
void Led::blinkStop()
|
||||||
{
|
{
|
||||||
if (m_lp.blinkTask != NULL)
|
if (m_blinkTask != NULL)
|
||||||
vTaskDelete(m_lp.blinkTask);
|
vTaskDelete(m_blinkTask);
|
||||||
m_lp.blinkTask = NULL;
|
m_blinkTask = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Led::blinkTask(void *params)
|
void Led::blinkTask(void *params)
|
||||||
{
|
{
|
||||||
|
Led *led = static_cast<Led *>(params);
|
||||||
LOG_DEBUG("Blinker Task Created");
|
LOG_DEBUG("Blinker Task Created");
|
||||||
led_params_t *lPar = static_cast<led_params_t *>(params);
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
rgbLedWrite(lPar->pin, lPar->color1.g, lPar->color1.r, lPar->color1.b);
|
{
|
||||||
delay(lPar->tOn);
|
std::lock_guard<std::mutex> lock(led->m_ledMutex);
|
||||||
rgbLedWrite(lPar->pin, lPar->color2.g, lPar->color2.r, lPar->color2.b); // off
|
rgbLedWrite(led->c_ledPin, led->m_color1.g, led->m_color1.r, led->m_color1.b);
|
||||||
if (lPar->tOff == 0)
|
}
|
||||||
|
delay(led->m_tOn);
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(led->m_ledMutex);
|
||||||
|
rgbLedWrite(led->c_ledPin, led->m_color2.g, led->m_color2.r, led->m_color2.b); // off
|
||||||
|
}
|
||||||
|
if (led->m_tOff == 0)
|
||||||
break;
|
break;
|
||||||
delay(lPar->tOff);
|
delay(led->m_tOff);
|
||||||
}
|
}
|
||||||
LOG_DEBUG("Blinker Task Ended");
|
LOG_DEBUG("Blinker Task Ended");
|
||||||
lPar->blinkTask = NULL;
|
led->m_blinkTask = NULL;
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,15 @@
|
|||||||
#define DEBUGLOG_DEFAULT_LOG_LEVEL_INFO
|
#define DEBUGLOG_DEFAULT_LOG_LEVEL_INFO
|
||||||
#include <DebugLog.h>
|
#include <DebugLog.h>
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace drivers
|
namespace drivers
|
||||||
{
|
{
|
||||||
|
|
||||||
class Led
|
class Led
|
||||||
{
|
{
|
||||||
const uint8_t c_ledPin = 38;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t r;
|
uint8_t r;
|
||||||
@@ -31,31 +32,34 @@ namespace drivers
|
|||||||
const color_t COLOR_VIOLET = {127, 0, 255};
|
const color_t COLOR_VIOLET = {127, 0, 255};
|
||||||
const color_t COLOR_MAGENTA = {255, 0, 255};
|
const color_t COLOR_MAGENTA = {255, 0, 255};
|
||||||
|
|
||||||
private:
|
public:
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
color_t color1;
|
|
||||||
color_t color2;
|
|
||||||
uint8_t pin;
|
|
||||||
uint16_t tOn;
|
|
||||||
uint16_t tOff;
|
|
||||||
TaskHandle_t blinkTask;
|
|
||||||
} led_params_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Led();
|
Led();
|
||||||
~Led();
|
~Led();
|
||||||
|
|
||||||
void setColor(const color_t color);
|
void setColor(const color_t color);
|
||||||
|
void flashColor(const uint16_t tOn, const color_t color);
|
||||||
void blinkColor(const uint16_t tOn, const uint16_t tOff, const color_t color);
|
void blinkColor(const uint16_t tOn, const uint16_t tOff, const color_t color);
|
||||||
void blinkAlternate(const uint16_t tOn, const uint16_t tOff, const color_t color1, const color_t color2);
|
void blinkAlternate(const uint16_t tOn, const uint16_t tOff, const color_t color1, const color_t color2);
|
||||||
void blinkStop();
|
void blinkStop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void flashHandle(TimerHandle_t th);
|
||||||
static void blinkTask(void *params);
|
static void blinkTask(void *params);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
led_params_t m_lp;
|
const uint8_t c_ledPin = 38;
|
||||||
|
|
||||||
|
color_t m_color1;
|
||||||
|
color_t m_color2;
|
||||||
|
color_t m_colorDefault;
|
||||||
|
|
||||||
|
uint16_t m_tOn;
|
||||||
|
uint16_t m_tOff;
|
||||||
|
|
||||||
|
TaskHandle_t m_blinkTask;
|
||||||
|
TimerHandle_t m_flashTimer;
|
||||||
|
|
||||||
|
std::mutex m_ledMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,27 +78,28 @@ namespace commands
|
|||||||
ArduinoJson::JsonDocument response;
|
ArduinoJson::JsonDocument response;
|
||||||
response["cmd"] = "setCronJob";
|
response["cmd"] = "setCronJob";
|
||||||
|
|
||||||
const auto &jobName = 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>();
|
||||||
const auto &actionStr = params["action"].as<std::string>();
|
const auto &actionStr = params["action"].as<std::string>();
|
||||||
|
response["values"]["name"] = eventName;
|
||||||
|
|
||||||
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("setCronJob unable to deserialize cron job [", actionStr.c_str(), "]");
|
||||||
response["value"]["status"] = "invalid";
|
response["values"]["status"] = "invalid";
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &cron = Cron::getInstance(dev);
|
auto &cron = Cron::getInstance(dev);
|
||||||
if (!cron.addEvent(jobName, timeStr, action))
|
if (!cron.addEvent(eventName, timeStr, action))
|
||||||
{
|
{
|
||||||
LOG_ERROR("setCronJob unable to add job [", actionStr.c_str(), "]");
|
LOG_ERROR("setCronJob unable to add job [", actionStr.c_str(), "]");
|
||||||
response["value"]["status"] = "invalid";
|
response["values"]["status"] = "invalid";
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
LOG_INFO("setCronJob added job [", actionStr.c_str(), "]");
|
LOG_INFO("setCronJob added job [", actionStr.c_str(), "]");
|
||||||
response["value"]["status"] = "valid";
|
response["values"]["status"] = "valid";
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
const ArduinoJson::JsonDocument Commands::getCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
const ArduinoJson::JsonDocument Commands::getCronJob(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
||||||
@@ -107,6 +108,7 @@ namespace commands
|
|||||||
response["cmd"] = "getCronJob";
|
response["cmd"] = "getCronJob";
|
||||||
auto &cron = Cron::getInstance(dev);
|
auto &cron = Cron::getInstance(dev);
|
||||||
auto eventName = params["name"].as<std::string>();
|
auto eventName = params["name"].as<std::string>();
|
||||||
|
response["values"]["name"] = eventName;
|
||||||
|
|
||||||
if (eventName.empty())
|
if (eventName.empty())
|
||||||
{
|
{
|
||||||
@@ -144,7 +146,6 @@ namespace commands
|
|||||||
ArduinoJson::JsonDocument action;
|
ArduinoJson::JsonDocument action;
|
||||||
action["cmd"] = cmd;
|
action["cmd"] = cmd;
|
||||||
action["params"] = cmdParams;
|
action["params"] = cmdParams;
|
||||||
response["values"]["name"] = eventName;
|
|
||||||
response["values"]["cronExpr"] = cron::to_cronstr(cronExpr);
|
response["values"]["cronExpr"] = cron::to_cronstr(cronExpr);
|
||||||
response["values"]["action"] = action;
|
response["values"]["action"] = action;
|
||||||
|
|
||||||
@@ -157,6 +158,7 @@ namespace commands
|
|||||||
response["cmd"] = "delCronJob";
|
response["cmd"] = "delCronJob";
|
||||||
auto &cron = Cron::getInstance(dev);
|
auto &cron = Cron::getInstance(dev);
|
||||||
auto eventName = params["name"].as<std::string>();
|
auto eventName = params["name"].as<std::string>();
|
||||||
|
response["values"]["name"] = eventName;
|
||||||
if (eventName.empty() || !cron.delEvent(eventName))
|
if (eventName.empty() || !cron.delEvent(eventName))
|
||||||
{
|
{
|
||||||
LOG_ERROR("delCronJob failed to delete job [", eventName.c_str(), "]");
|
LOG_ERROR("delCronJob failed to delete job [", eventName.c_str(), "]");
|
||||||
@@ -189,20 +191,18 @@ namespace commands
|
|||||||
const ArduinoJson::JsonDocument Commands::setHPlimit(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
const ArduinoJson::JsonDocument Commands::setHPlimit(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
||||||
{
|
{
|
||||||
ArduinoJson::JsonDocument response;
|
ArduinoJson::JsonDocument response;
|
||||||
{
|
response["cmd"] = "setHPlimit";
|
||||||
std::string msg;
|
|
||||||
serializeJson(params, msg);
|
|
||||||
LOG_INFO("setHPlimit params ->", msg.c_str());
|
|
||||||
};
|
|
||||||
if (!params["level"].is<std::string>())
|
if (!params["level"].is<std::string>())
|
||||||
{
|
{
|
||||||
LOG_ERROR("setHPlimit incorrect parameters");
|
LOG_ERROR("setHPlimit incorrect parameters");
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
const auto level = params["level"].as<std::string>();
|
const auto level = params["level"].as<std::string>();
|
||||||
|
response["values"]["level"] = level;
|
||||||
if (!c_hpLimitsMap.contains(level))
|
if (!c_hpLimitsMap.contains(level))
|
||||||
{
|
{
|
||||||
LOG_ERROR("setHPlimit invalid level", level.c_str());
|
LOG_ERROR("setHPlimit invalid level", level.c_str());
|
||||||
|
response["values"]["status"] = "invalid";
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
for (const auto [lvl, ro] : c_hpLimitsMap)
|
for (const auto [lvl, ro] : c_hpLimitsMap)
|
||||||
@@ -213,17 +213,14 @@ namespace commands
|
|||||||
dev.io.digitalOutWrite(ro, false);
|
dev.io.digitalOutWrite(ro, false);
|
||||||
}
|
}
|
||||||
LOG_INFO("setHPlimit -> level", level.c_str());
|
LOG_INFO("setHPlimit -> level", level.c_str());
|
||||||
|
response["values"]["status"] = "valid";
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ArduinoJson::JsonDocument Commands::setHeating(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
const ArduinoJson::JsonDocument Commands::setHeating(const devices_t &dev, const ArduinoJson::JsonDocument ¶ms)
|
||||||
{
|
{
|
||||||
ArduinoJson::JsonDocument response;
|
ArduinoJson::JsonDocument response;
|
||||||
{
|
response["cmd"] = "setHeating";
|
||||||
std::string msg;
|
|
||||||
serializeJson(params, msg);
|
|
||||||
LOG_INFO("setHeating params ->", msg.c_str());
|
|
||||||
};
|
|
||||||
if (params.isNull())
|
if (params.isNull())
|
||||||
{
|
{
|
||||||
LOG_ERROR("setHeating incorrect paramaters");
|
LOG_ERROR("setHeating incorrect paramaters");
|
||||||
@@ -236,15 +233,20 @@ namespace commands
|
|||||||
if (params[lvl] == "ON")
|
if (params[lvl] == "ON")
|
||||||
{
|
{
|
||||||
dev.io.digitalOutWrite(ro, true);
|
dev.io.digitalOutWrite(ro, true);
|
||||||
|
response["values"][lvl] = "ON";
|
||||||
LOG_INFO("setHeating -> ", lvl.c_str(), "ON");
|
LOG_INFO("setHeating -> ", lvl.c_str(), "ON");
|
||||||
}
|
}
|
||||||
else if (params[lvl] == "OFF")
|
else if (params[lvl] == "OFF")
|
||||||
{
|
{
|
||||||
dev.io.digitalOutWrite(ro, false);
|
dev.io.digitalOutWrite(ro, false);
|
||||||
|
response["values"][lvl] = "OFF";
|
||||||
LOG_INFO("setHeating -> ", lvl.c_str(), "OFF");
|
LOG_INFO("setHeating -> ", lvl.c_str(), "OFF");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
response["values"][lvl] = "invalid";
|
||||||
LOG_ERROR("setHeating invalid valve state");
|
LOG_ERROR("setHeating invalid valve state");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -277,11 +279,6 @@ namespace commands
|
|||||||
{
|
{
|
||||||
ArduinoJson::JsonDocument response;
|
ArduinoJson::JsonDocument response;
|
||||||
auto &conf = Config::getInstance();
|
auto &conf = Config::getInstance();
|
||||||
{
|
|
||||||
std::string msg;
|
|
||||||
serializeJson(params, msg);
|
|
||||||
LOG_INFO("setIrrigation params ->", msg.c_str());
|
|
||||||
};
|
|
||||||
response["cmd"] = "setIrrigation";
|
response["cmd"] = "setIrrigation";
|
||||||
if (params.isNull())
|
if (params.isNull())
|
||||||
{
|
{
|
||||||
@@ -292,6 +289,8 @@ namespace commands
|
|||||||
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;
|
||||||
|
|
||||||
if (zone == "stop")
|
if (zone == "stop")
|
||||||
{ // stop all zones and reset timers
|
{ // stop all zones and reset timers
|
||||||
LOG_INFO("setIrrigation stop all zones");
|
LOG_INFO("setIrrigation stop all zones");
|
||||||
@@ -321,6 +320,8 @@ namespace commands
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response["values"]["timeOn"] = tOn;
|
||||||
|
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
|
||||||
{
|
{
|
||||||
LOG_ERROR("setIrrigation incorrect zone[", zone.c_str(), "] or time values tOn[", tOn, "] tPause[", tPause, "]");
|
LOG_ERROR("setIrrigation incorrect zone[", zone.c_str(), "] or time values tOn[", tOn, "] tPause[", tPause, "]");
|
||||||
@@ -366,7 +367,7 @@ namespace commands
|
|||||||
dev.io.digitalOutWrite(zoneIoNumber, true);
|
dev.io.digitalOutWrite(zoneIoNumber, true);
|
||||||
xTimerStart(shTimer, 0);
|
xTimerStart(shTimer, 0);
|
||||||
timerHandle = shTimer;
|
timerHandle = shTimer;
|
||||||
response["values"]["status"] = "ok";
|
response["values"]["status"] = "valid";
|
||||||
LOG_INFO("setIrrigation zone [", timerName, "] tOn[", tOn, "] tPause[", tPause, "]");
|
LOG_INFO("setIrrigation zone [", timerName, "] tOn[", tOn, "] tPause[", tPause, "]");
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
@@ -387,15 +388,13 @@ namespace commands
|
|||||||
|
|
||||||
if (!rtcOk || !ntpOk)
|
if (!rtcOk || !ntpOk)
|
||||||
{
|
{
|
||||||
response["values"]["status"] = "unable to get time";
|
response["values"]["status"] = "invalid";
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
response["values"]["status"] = "valid";
|
response["values"]["status"] = "valid";
|
||||||
response["values"]["time"] = rtc.getTimeStr();
|
response["values"]["time"] = rtc.getTimeStr();
|
||||||
|
|
||||||
LOG_INFO("setTimeNTP -> RTC is [", response["status"]["time"].as<std::string>().c_str(), "]");
|
LOG_INFO("setTimeNTP -> RTC is [", response["status"]["time"].as<std::string>().c_str(), "]");
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
// SETTERS //
|
// SETTERS //
|
||||||
@@ -482,7 +481,7 @@ namespace commands
|
|||||||
|
|
||||||
if (!rtcOk || !ntpOk)
|
if (!rtcOk || !ntpOk)
|
||||||
{
|
{
|
||||||
response["values"]["status"] = "unable to get time";
|
response["values"]["status"] = "invalid";
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,7 +491,8 @@ namespace commands
|
|||||||
auto timeDiff = std::chrono::duration_cast<std::chrono::seconds>(ntpTimePoint - rtcTimePoint);
|
auto timeDiff = std::chrono::duration_cast<std::chrono::seconds>(ntpTimePoint - rtcTimePoint);
|
||||||
auto direction = timeDiff.count() >= 0 ? "BEYOND" : "AHEAD";
|
auto direction = timeDiff.count() >= 0 ? "BEYOND" : "AHEAD";
|
||||||
|
|
||||||
response["values"]["drift"] = (int32_t)timeDiff.count();
|
response["values"]["status"] = "valid";
|
||||||
|
response["values"]["drift"] = (uint32_t)timeDiff.count();
|
||||||
response["values"]["direction"] = "RTC is [" + std::string(direction) + "] NTP time";
|
response["values"]["direction"] = "RTC is [" + std::string(direction) + "] NTP time";
|
||||||
|
|
||||||
LOG_INFO("getTimeDrift -> RTC is [", (int32_t)timeDiff.count(), "] sec, [", std::string(direction).c_str(), "] NTP time");
|
LOG_INFO("getTimeDrift -> RTC is [", (int32_t)timeDiff.count(), "] sec, [", std::string(direction).c_str(), "] NTP time");
|
||||||
|
|||||||
@@ -222,7 +222,13 @@ const bool Cron::processEvents()
|
|||||||
next = cron::cron_next(cronexrp, nowTm); // update next execution time only if event was executed
|
next = cron::cron_next(cronexrp, nowTm); // update next execution time only if event was executed
|
||||||
// otherwise time tracking is lost
|
// otherwise time tracking is lost
|
||||||
LOG_INFO("Cron running event [", eventName.c_str(), "] next execution time [", drivers::PCF85063::tm2str(next).c_str(), "]");
|
LOG_INFO("Cron running event [", eventName.c_str(), "] next execution time [", drivers::PCF85063::tm2str(next).c_str(), "]");
|
||||||
auto resp = commands::s_commandMap.at(cmd)(m_dev, cmdParams); // here the magic happens
|
auto action = commands::s_commandMap.at(cmd)(m_dev, cmdParams); // here the magic happens
|
||||||
|
ArduinoJson::JsonDocument resp;
|
||||||
|
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)
|
if (m_callback)
|
||||||
{
|
{
|
||||||
m_callback(resp);
|
m_callback(resp);
|
||||||
|
|||||||
16
src/main.cpp
16
src/main.cpp
@@ -57,7 +57,7 @@ void loop()
|
|||||||
|
|
||||||
//////////////// MQTT //////////////
|
//////////////// MQTT //////////////
|
||||||
/////////////// CALLBACK //////////////
|
/////////////// CALLBACK //////////////
|
||||||
std::function<void(const ArduinoJson::JsonDocument &)> commandsCallback =
|
MQTTwrapper::ActionCallback commandsCallback =
|
||||||
[&mqtt, &devices](const ArduinoJson::JsonDocument &doc)
|
[&mqtt, &devices](const ArduinoJson::JsonDocument &doc)
|
||||||
{
|
{
|
||||||
if (!doc["cmd"].is<std::string>())
|
if (!doc["cmd"].is<std::string>())
|
||||||
@@ -81,6 +81,18 @@ void loop()
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MQTTwrapper::MessageCallback onMessage = [&devices](const MQTTwrapper::Topic &topic, const MQTTwrapper::Message &message)
|
||||||
|
{
|
||||||
|
LOG_INFO("onMessage callback [", topic.c_str(),"]");
|
||||||
|
devices.led.flashColor(250, devices.led.COLOR_YELLOW);
|
||||||
|
};
|
||||||
|
|
||||||
|
MQTTwrapper::MessageCallback onPublish = [&devices](const MQTTwrapper::Topic &topic, const MQTTwrapper::Message &message)
|
||||||
|
{
|
||||||
|
LOG_INFO("onPublish callback [", topic.c_str(),"]");
|
||||||
|
devices.led.flashColor(250, devices.led.COLOR_BLUE);
|
||||||
|
};
|
||||||
|
|
||||||
///////////// CRONJOB //////////////
|
///////////// CRONJOB //////////////
|
||||||
/////////////// CALLBACK //////////////
|
/////////////// CALLBACK //////////////
|
||||||
Cron::CronCallback cronCallback = [&mqtt](const ArduinoJson::JsonDocument &resp)
|
Cron::CronCallback cronCallback = [&mqtt](const ArduinoJson::JsonDocument &resp)
|
||||||
@@ -132,6 +144,8 @@ void loop()
|
|||||||
buzzer.beep(250, NOTE_B);
|
buzzer.beep(250, NOTE_B);
|
||||||
led.setColor(led.COLOR_GREEN);
|
led.setColor(led.COLOR_GREEN);
|
||||||
mqtt.subscribe(conf.m_mqttSubscribe["commands"], commandsCallback);
|
mqtt.subscribe(conf.m_mqttSubscribe["commands"], commandsCallback);
|
||||||
|
mqtt.setOnMessageCb(onMessage);
|
||||||
|
mqtt.setOnPublishCb(onPublish);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
delay(250);
|
delay(250);
|
||||||
|
|||||||
30
src/mqtt.cpp
30
src/mqtt.cpp
@@ -44,7 +44,7 @@ const bool MQTTwrapper::disconnect()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool MQTTwrapper::subscribe(const topic_t &topic, const action_t action)
|
const bool MQTTwrapper::subscribe(const Topic &topic, const ActionCallback action)
|
||||||
{
|
{
|
||||||
if (m_actionMap.contains(topic))
|
if (m_actionMap.contains(topic))
|
||||||
{
|
{
|
||||||
@@ -61,7 +61,7 @@ const bool MQTTwrapper::subscribe(const topic_t &topic, const action_t action)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool MQTTwrapper::unsubscribe(const topic_t &topic)
|
const bool MQTTwrapper::unsubscribe(const Topic &topic)
|
||||||
{
|
{
|
||||||
if (!m_actionMap.contains(topic))
|
if (!m_actionMap.contains(topic))
|
||||||
{
|
{
|
||||||
@@ -83,7 +83,7 @@ const bool MQTTwrapper::connected()
|
|||||||
return m_loopHandle != NULL;
|
return m_loopHandle != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool MQTTwrapper::publish(const topic_t &topic, const ArduinoJson::JsonDocument obj)
|
const bool MQTTwrapper::publish(const Topic &topic, const ArduinoJson::JsonDocument obj)
|
||||||
{
|
{
|
||||||
std::string message;
|
std::string message;
|
||||||
if (!m_client.connected())
|
if (!m_client.connected())
|
||||||
@@ -99,12 +99,32 @@ const bool MQTTwrapper::publish(const topic_t &topic, const ArduinoJson::JsonDoc
|
|||||||
if (m_client.publish(topic.c_str(), message.c_str()))
|
if (m_client.publish(topic.c_str(), message.c_str()))
|
||||||
{
|
{
|
||||||
LOG_DEBUG("MQTT published topic [", topic.c_str(), "] - message [", message.c_str(), "]");
|
LOG_DEBUG("MQTT published topic [", topic.c_str(), "] - message [", message.c_str(), "]");
|
||||||
|
if (m_onPublish)
|
||||||
|
{
|
||||||
|
m_onPublish(topic, message);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
LOG_ERROR("MQTT failed to publish topic [", topic.c_str(), "] - message [", message.c_str(), "]");
|
LOG_ERROR("MQTT failed to publish topic [", topic.c_str(), "] - message [", message.c_str(), "]");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MQTTwrapper::setOnMessageCb(MessageCallback cb)
|
||||||
|
{
|
||||||
|
if (cb)
|
||||||
|
m_onReceive = cb;
|
||||||
|
else
|
||||||
|
LOG_ERROR("MQTT invalid onReceive Callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MQTTwrapper::setOnPublishCb(MessageCallback cb)
|
||||||
|
{
|
||||||
|
if (cb)
|
||||||
|
m_onPublish = cb;
|
||||||
|
else
|
||||||
|
LOG_ERROR("MQTT invalid onPublish Callback");
|
||||||
|
}
|
||||||
|
|
||||||
void MQTTwrapper::callback(char *topic, uint8_t *payload, unsigned int length)
|
void MQTTwrapper::callback(char *topic, uint8_t *payload, unsigned int length)
|
||||||
{
|
{
|
||||||
std::string pl;
|
std::string pl;
|
||||||
@@ -120,13 +140,15 @@ void MQTTwrapper::callback(char *topic, uint8_t *payload, unsigned int length)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MQTTwrapper::onMessage(const std::string topic, const std::string message)
|
void MQTTwrapper::onMessage(const Topic topic, const Message message)
|
||||||
{
|
{
|
||||||
ArduinoJson::JsonDocument obj;
|
ArduinoJson::JsonDocument obj;
|
||||||
LOG_DEBUG("MQTT received topic [", topic.c_str(), "] - message [", message.c_str(), "]");
|
LOG_DEBUG("MQTT received topic [", topic.c_str(), "] - message [", message.c_str(), "]");
|
||||||
if (ArduinoJson::deserializeJson(obj, message) == ArduinoJson::DeserializationError::Ok)
|
if (ArduinoJson::deserializeJson(obj, message) == ArduinoJson::DeserializationError::Ok)
|
||||||
{
|
{
|
||||||
m_actionMap[topic](obj);
|
m_actionMap[topic](obj);
|
||||||
|
if (m_onReceive)
|
||||||
|
m_onReceive(topic, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_ERROR("MQTT failed to deserialize message\n", message.c_str());
|
LOG_ERROR("MQTT failed to deserialize message\n", message.c_str());
|
||||||
|
|||||||
29
src/mqtt.h
29
src/mqtt.h
@@ -13,12 +13,16 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
typedef std::string topic_t;
|
|
||||||
typedef std::function<void(const ArduinoJson::JsonDocument &)> action_t; // the actions receive a JsonObject containing the received message
|
|
||||||
typedef std::map<topic_t, action_t> action_map_t;
|
|
||||||
|
|
||||||
class MQTTwrapper
|
class MQTTwrapper
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
using Topic = std::string;
|
||||||
|
using Message = std::string;
|
||||||
|
using MessageCallback = std::function<void(const Topic &topic, const Message &message)>;
|
||||||
|
using ActionCallback = std::function<void(const ArduinoJson::JsonDocument &)>; // the actions receive a JsonObject containing the received message
|
||||||
|
using StateChangeCallback = std::function<void(void)>;
|
||||||
|
|
||||||
|
using ActionMap = std::map<Topic, ActionCallback>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::map<int, std::string> stateMap = {
|
const std::map<int, std::string> stateMap = {
|
||||||
@@ -31,8 +35,7 @@ private:
|
|||||||
{2, "MQTT_CONNECT_BAD_CLIENT_ID"},
|
{2, "MQTT_CONNECT_BAD_CLIENT_ID"},
|
||||||
{3, "MQTT_CONNECT_UNAVAILABLE"},
|
{3, "MQTT_CONNECT_UNAVAILABLE"},
|
||||||
{4, "MQTT_CONNECT_BAD_CREDENTIALS"},
|
{4, "MQTT_CONNECT_BAD_CREDENTIALS"},
|
||||||
{5, "MQTT_CONNECT_UNAUTHORIZED"}
|
{5, "MQTT_CONNECT_UNAUTHORIZED"}};
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static MQTTwrapper *
|
static MQTTwrapper *
|
||||||
@@ -54,10 +57,13 @@ public:
|
|||||||
const bool disconnect();
|
const bool disconnect();
|
||||||
const bool connected();
|
const bool connected();
|
||||||
|
|
||||||
const bool subscribe(const topic_t &topic, const action_t action);
|
const bool subscribe(const Topic &topic, const ActionCallback action);
|
||||||
const bool unsubscribe(const topic_t &topic);
|
const bool unsubscribe(const Topic &topic);
|
||||||
|
|
||||||
const bool publish(const topic_t &topic, const ArduinoJson::JsonDocument obj);
|
const bool publish(const Topic &topic, const ArduinoJson::JsonDocument obj);
|
||||||
|
|
||||||
|
void setOnMessageCb(MessageCallback cb);
|
||||||
|
void setOnPublishCb(MessageCallback cb);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void callback(char *topic, uint8_t *payload, unsigned int length); // C-style callback only to invoke onMessage
|
static void callback(char *topic, uint8_t *payload, unsigned int length); // C-style callback only to invoke onMessage
|
||||||
@@ -68,8 +74,11 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const Config &m_config;
|
const Config &m_config;
|
||||||
action_map_t m_actionMap;
|
ActionMap m_actionMap;
|
||||||
NetworkClient m_tcp;
|
NetworkClient m_tcp;
|
||||||
PubSubClient m_client;
|
PubSubClient m_client;
|
||||||
TaskHandle_t m_loopHandle;
|
TaskHandle_t m_loopHandle;
|
||||||
|
|
||||||
|
MessageCallback m_onPublish;
|
||||||
|
MessageCallback m_onReceive;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user