implemented config and irrigation commands

This commit is contained in:
Emanuele Trabattoni
2025-07-25 21:53:49 +02:00
parent 74a97a7dd6
commit 5459148538
5 changed files with 184 additions and 41 deletions

View File

@@ -64,11 +64,11 @@
"cmd": "setIrrigation", "cmd": "setIrrigation",
"params": { "params": {
"zone": [ "zone": [
"Ricircolo", "ricircolo",
"1", "1",
"2", "2",
"3", "3",
"Rubinetti" "rubinetti"
], ],
"timeOn": 120, "timeOn": 120,
"timePause": 2 "timePause": 2

View File

@@ -104,9 +104,6 @@ public:
deserialize(); deserialize();
saveConfig(); saveConfig();
}; // filesystem is unmounted here }; // filesystem is unmounted here
LOG_WARN("setConfig will cause restart!");
delay(5000);
esp_restart();
} }
void resetConfig() void resetConfig()

View File

@@ -156,7 +156,7 @@ namespace drivers
// Delay Bus Access between different devices // Delay Bus Access between different devices
if (device != m_lastDevice) if (device != m_lastDevice)
{ {
LOG_WARN("MODBUS device change from ", printHex(m_lastDevice).c_str(), "to", printHex(device).c_str()); LOG_DEBUG("MODBUS device change from ", printHex(m_lastDevice).c_str(), "to", printHex(device).c_str());
BUS_DELAY; BUS_DELAY;
m_lastDevice = device; m_lastDevice = device;
} }
@@ -213,7 +213,7 @@ namespace drivers
// Delay Bus Access between different devices // Delay Bus Access between different devices
if (device != m_lastDevice) if (device != m_lastDevice)
{ {
LOG_WARN("MODBUS device change from ", printHex(m_lastDevice).c_str(), "to", printHex(device).c_str()); LOG_DEBUG("MODBUS device change from ", printHex(m_lastDevice).c_str(), "to", printHex(device).c_str());
BUS_DELAY; BUS_DELAY;
m_lastDevice = device; m_lastDevice = device;
} }
@@ -266,7 +266,7 @@ namespace drivers
// Delay Bus Access between different devices // Delay Bus Access between different devices
if (device != m_lastDevice) if (device != m_lastDevice)
{ {
LOG_WARN("MODBUS device change from ", printHex(m_lastDevice).c_str(), "to", printHex(device).c_str()); LOG_DEBUG("MODBUS device change from ", printHex(m_lastDevice).c_str(), "to", printHex(device).c_str());
BUS_DELAY; BUS_DELAY;
m_lastDevice = device; m_lastDevice = device;
} }
@@ -325,7 +325,7 @@ namespace drivers
// Delay Bus Access between different devices // Delay Bus Access between different devices
if (device != m_lastDevice) if (device != m_lastDevice)
{ {
LOG_WARN("MODBUS device change from ", printHex(m_lastDevice).c_str(), "to", printHex(device).c_str()); LOG_DEBUG("MODBUS device change from ", printHex(m_lastDevice).c_str(), "to", printHex(device).c_str());
BUS_DELAY; BUS_DELAY;
m_lastDevice = device; m_lastDevice = device;
} }

View File

@@ -3,21 +3,34 @@
namespace commands namespace commands
{ {
void restart(TimerHandle_t t)
{
esp_restart();
}
// CONFIG // // CONFIG //
// CONFIG // // CONFIG //
const ArduinoJson::JsonDocument Commands::setConfig(const devices_t &dev, const ArduinoJson::JsonDocument &params) const ArduinoJson::JsonDocument Commands::setConfig(const devices_t &dev, const ArduinoJson::JsonDocument &params)
{ {
ArduinoJson::JsonDocument response; ArduinoJson::JsonDocument response;
auto &conf = Config::getInstance(); auto &conf = Config::getInstance();
std::string buf;
response["cmd"] = "setConfig";
auto values = response["values"].to<JsonObject>(); auto values = response["values"].to<JsonObject>();
if (params.isNull()) if (params.isNull())
{ {
values["status"] = "Invalid"; values["status"] = "Invalid";
return response;
} }
else conf.setConfig(params);
values["status"] = "Valid";
serializeJson(params, buf);
LOG_INFO("setConfig ->", buf.c_str());
TimerHandle_t resetTimer(xTimerCreate("restartTimer", pdMS_TO_TICKS(5000), false, NULL, restart));
LOG_WARN("setConfig will cause restart!");
if (resetTimer)
{ {
conf.setConfig(params); xTimerStart(resetTimer, 0);
values["status"] = "Valid";
} }
return response; return response;
} }
@@ -25,8 +38,11 @@ namespace commands
{ {
ArduinoJson::JsonDocument response; ArduinoJson::JsonDocument response;
auto &conf = Config::getInstance(); auto &conf = Config::getInstance();
std::string buf;
response["cmd"] = "getConfig"; response["cmd"] = "getConfig";
response["values"] = conf.getConfig(); response["values"] = conf.getConfig();
serializeJson(response["values"], buf);
LOG_INFO("getConfig ->", buf.c_str());
return response; return response;
} }
// CONFIG // // CONFIG //
@@ -85,14 +101,145 @@ namespace commands
const ArduinoJson::JsonDocument Commands::setHeating(const devices_t &dev, const ArduinoJson::JsonDocument &params) const ArduinoJson::JsonDocument Commands::setHeating(const devices_t &dev, const ArduinoJson::JsonDocument &params)
{ {
ArduinoJson::JsonDocument response; ArduinoJson::JsonDocument response;
LOG_WARN("Comand not yet implemented"); if (params.isNull())
{
LOG_ERROR("setHeating incorrect paramaters");
return response;
}
for (auto v : c_heatingValveMap)
{
if (params[v.first].isNull())
continue;
if (params[v.first] == "ON")
{
dev.io.digitalOutWrite(v.second, true);
LOG_INFO("setHeating -> ", v.first.c_str(), "ON");
}
else if (params[v.first] == "OFF")
{
dev.io.digitalOutWrite(v.second, false);
LOG_INFO("setHeating -> ", v.first.c_str(), "OFF");
}
else
LOG_ERROR("setHeating invalid valve state");
}
return response; return response;
} }
void resetZone(TimerHandle_t th)
{
devices_t *dev = (devices_t *)pvTimerGetTimerID(th);
const char *timerName = pcTimerGetName(th);
LOG_INFO("Reset irrigation zone -> ", timerName);
if (!c_irrigationValveMap.contains(timerName))
{
LOG_ERROR("Irrigation timer name invalid");
return;
}
dev->io.digitalOutWrite(c_irrigationValveMap.at(timerName), false);
c_irrigationTimerMap.at(timerName).second = NULL; // reset timer handle for this timer
xTimerDelete(th, 0); // delete the timer on expiry
}
void resetWaterPump(TimerHandle_t th)
{
devices_t *dev = (devices_t *)pvTimerGetTimerID(th);
LOG_INFO("Shutdown irrigation pump");
dev->io.digitalOutWrite(RO::IRR_PUMP, false);
s_irrigationPumpTimer = NULL;
xTimerDelete(th, 0); // delete the timer on expiry
}
const ArduinoJson::JsonDocument Commands::setIrrigation(const devices_t &dev, const ArduinoJson::JsonDocument &params) const ArduinoJson::JsonDocument Commands::setIrrigation(const devices_t &dev, const ArduinoJson::JsonDocument &params)
{ {
ArduinoJson::JsonDocument response; ArduinoJson::JsonDocument response;
LOG_WARN("Comand not yet implemented"); auto &conf = Config::getInstance();
response["cmd"] = "setIrrigation";
if (params.isNull())
{
LOG_ERROR("setIrrigation incorrect paramaters");
return response;
}
const std::string zone(params["zone"].as<std::string>());
const uint16_t tOn(params["timeOn"].as<uint16_t>());
const uint16_t tPause(params["timePause"].as<uint16_t>());
if (zone == "stop")
{ // stop all zones and reset timers
LOG_INFO("setIrrigation stop all zones");
for (auto &h : c_irrigationTimerMap)
{
const auto zoneName = h.first;
auto &timerHandle = h.second.second; // get the timer handle
if (timerHandle) // if handle is not null (not from a deleted timer)
{
if (xTimerIsTimerActive(timerHandle)) // stop the timer if active
{
LOG_INFO("setIrrigation stopping timer", zoneName.c_str());
xTimerStop(timerHandle, 0);
xTimerDelete(timerHandle, pdMS_TO_TICKS(10)); // delete it
timerHandle = NULL;
}
}
LOG_INFO("setIrrigation closing ", zoneName.c_str());
dev.io.digitalOutWrite(c_irrigationValveMap.at(zoneName), false); // shuto down the valve
}
if (s_irrigationPumpTimer)
{
xTimerChangePeriod(s_irrigationPumpTimer, pdMS_TO_TICKS(30 * 1000), 0); // shutdown the pump in 30s after the stop
xTimerReset(s_irrigationPumpTimer, 0);
}
response["values"]["status"] = "stop";
return response;
}
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, tPause);
response["values"]["status"] = "invalid";
return response;
}
// verify if timer was already started, zone is already on
const auto timerName = c_irrigationTimerMap.at(zone).first;
const auto zoneIoNumber = c_irrigationValveMap.at(zone);
auto &timerHandle = c_irrigationTimerMap.at(zone).second;
if (timerHandle)
{ // this timer was alteady started, ignore command
LOG_WARN("setIrrigation zone", timerName, "already started");
response["values"]["status"] = "conflict";
return response;
}
const uint32_t pumpTime((tOn + 30) * 1000);
if (!s_irrigationPumpTimer) // Pump has not yet started
{
s_irrigationPumpTimer = xTimerCreate("pumpTimer", pdMS_TO_TICKS(pumpTime), false, (void *)&dev, resetWaterPump);
dev.io.digitalOutWrite(RO::IRR_PUMP, true);
xTimerStart(s_irrigationPumpTimer, 0); // immediate start pump timer
LOG_INFO("setIrrigation pump time ", pumpTime);
}
else
{
const auto currentRemaining(xTimerGetExpiryTime(s_irrigationPumpTimer) - xTaskGetTickCount());
const auto newRemaining(pumpTime);
const auto newPeriod = std::max(newRemaining, currentRemaining);
xTimerChangePeriod(s_irrigationPumpTimer, newPeriod, 0); // set new period based on timing of new zone
xTimerReset(s_irrigationPumpTimer, 0); // if timer was already started, restart
LOG_INFO("setIrrigation pump time reset", newRemaining);
}
TimerHandle_t shTimer(xTimerCreate(timerName, pdMS_TO_TICKS(tOn * 1000), false, (void *)&dev, resetZone));
if (shTimer)
{
dev.io.digitalOutWrite(zoneIoNumber, true);
xTimerStart(shTimer, pdMS_TO_TICKS(tPause * 1000));
timerHandle = shTimer;
response["values"]["status"] = "ok";
LOG_INFO("setIrrigation zone -> ", timerName, "tOn", tOn, "tPause", tPause);
}
return response; return response;
} }
// SETTERS // // SETTERS //
@@ -114,13 +261,6 @@ namespace commands
return response; return response;
} }
const ArduinoJson::JsonDocument Commands::getHPlimit(const devices_t &dev, const ArduinoJson::JsonDocument &params)
{
ArduinoJson::JsonDocument response;
LOG_WARN("Comand not yet implemented");
return response;
}
const ArduinoJson::JsonDocument Commands::getInputStatus(const devices_t &dev, const ArduinoJson::JsonDocument &params) const ArduinoJson::JsonDocument Commands::getInputStatus(const devices_t &dev, const ArduinoJson::JsonDocument &params)
{ {
ArduinoJson::JsonDocument response; ArduinoJson::JsonDocument response;

View File

@@ -18,10 +18,9 @@ namespace commands
P3, P3,
P4, P4,
NC_1, NC_1,
NC_2, FST_FLOOR,
PUMP_HT,
GND_FLOOR, GND_FLOOR,
FR_FLOOR, PUMP_HT,
IRR_PUMP, IRR_PUMP,
Z1, Z1,
Z2, Z2,
@@ -33,21 +32,29 @@ namespace commands
RO_MAX // unused to detect invalid values RO_MAX // unused to detect invalid values
}; };
const std::map<const std::string, uint8_t> c_hpLimitsMap = {{"P1", RO::P1}, static const std::map<const std::string, uint8_t> c_hpLimitsMap = {{"P1", RO::P1},
{"P2", RO::P2}, {"P2", RO::P2},
{"P3", RO::P3}, {"P3", RO::P3},
{"P4", RO::P4}, {"P4", RO::P4},
{"UNLIMITED", RO::P1}}; {"UNLIMITED", RO::P1}};
const std::map<const std::string, uint8_t> c_heatingValveMap = {{"pump", RO::PUMP_HT}, static const std::map<const std::string, uint8_t> c_heatingValveMap = {{"pump", RO::PUMP_HT},
{"first", RO::FR_FLOOR}, {"first", RO::FST_FLOOR},
{"ground", RO::GND_FLOOR}}; {"ground", RO::GND_FLOOR}};
const std::map<const std::string, uint8_t> c_irrigationValveMap = {{"ricircolo", RO::RETURN}, static const std::map<const std::string, uint8_t> c_irrigationValveMap = {{"ricircolo", RO::RETURN},
{"1", RO::Z1}, {"zone1", RO::Z1},
{"2", RO::Z2}, {"zone2", RO::Z2},
{"3", RO::Z3}, {"zone3", RO::Z3},
{"rubinetti", RO::AUX}}; {"rubinetti", RO::AUX}};
static std::map<const std::string, std::pair<const char *, TimerHandle_t>> c_irrigationTimerMap = {{"ricircolo", {"ricircolo", NULL}},
{"zone1", {"zone1", NULL}},
{"zone2", {"zone2", NULL}},
{"zone3", {"zone3", NULL}},
{"rubinetti", {"rubinetti", NULL}}};
static TimerHandle_t s_irrigationPumpTimer = NULL;
class Commands class Commands
{ {
@@ -57,7 +64,7 @@ namespace commands
// CONFIG // // CONFIG //
static const ArduinoJson::JsonDocument setConfig(const devices_t &dev, const ArduinoJson::JsonDocument &params); static const ArduinoJson::JsonDocument setConfig(const devices_t &dev, const ArduinoJson::JsonDocument &params);
static const ArduinoJson::JsonDocument getConfig(const devices_t &dev, const ArduinoJson::JsonDocument &params); static const ArduinoJson::JsonDocument getConfig(const devices_t &dev, const ArduinoJson::JsonDocument &params);
// CRONJOBS // // CRONJOBS //
static const ArduinoJson::JsonDocument setCronjob(const devices_t &dev, const ArduinoJson::JsonDocument &params); static const ArduinoJson::JsonDocument setCronjob(const devices_t &dev, const ArduinoJson::JsonDocument &params);
static const ArduinoJson::JsonDocument getCronjob(const devices_t &dev, const ArduinoJson::JsonDocument &params); static const ArduinoJson::JsonDocument getCronjob(const devices_t &dev, const ArduinoJson::JsonDocument &params);
@@ -67,10 +74,9 @@ namespace commands
static const ArduinoJson::JsonDocument setHPlimit(const devices_t &dev, const ArduinoJson::JsonDocument &params); static const ArduinoJson::JsonDocument setHPlimit(const devices_t &dev, const ArduinoJson::JsonDocument &params);
static const ArduinoJson::JsonDocument setHeating(const devices_t &dev, const ArduinoJson::JsonDocument &params); static const ArduinoJson::JsonDocument setHeating(const devices_t &dev, const ArduinoJson::JsonDocument &params);
static const ArduinoJson::JsonDocument setIrrigation(const devices_t &dev, const ArduinoJson::JsonDocument &params); static const ArduinoJson::JsonDocument setIrrigation(const devices_t &dev, const ArduinoJson::JsonDocument &params);
// GETTERS // // GETTERS //
static const ArduinoJson::JsonDocument getHPpower(const devices_t &dev, const ArduinoJson::JsonDocument &params); static const ArduinoJson::JsonDocument getHPpower(const devices_t &dev, const ArduinoJson::JsonDocument &params);
static const ArduinoJson::JsonDocument getHPlimit(const devices_t &dev, const ArduinoJson::JsonDocument &params);
static const ArduinoJson::JsonDocument getInputStatus(const devices_t &dev, const ArduinoJson::JsonDocument &params); static const ArduinoJson::JsonDocument getInputStatus(const devices_t &dev, const ArduinoJson::JsonDocument &params);
static const ArduinoJson::JsonDocument getOutputStatus(const devices_t &dev, const ArduinoJson::JsonDocument &params); static const ArduinoJson::JsonDocument getOutputStatus(const devices_t &dev, const ArduinoJson::JsonDocument &params);
static const ArduinoJson::JsonDocument getTemperatures(const devices_t &dev, const ArduinoJson::JsonDocument &params); static const ArduinoJson::JsonDocument getTemperatures(const devices_t &dev, const ArduinoJson::JsonDocument &params);
@@ -87,7 +93,7 @@ namespace commands
{"setCronjob", Commands::setCronjob}, {"setCronjob", Commands::setCronjob},
{"getCronjob", Commands::getCronjob}, {"getCronjob", Commands::getCronjob},
{"delCronjob", Commands::delCronjob}, {"delCronjob", Commands::delCronjob},
{"setHPlimit", Commands::setHPlimit}, {"setHPlimit", Commands::setHPlimit},
{"setHeating", Commands::setHeating}, {"setHeating", Commands::setHeating},
{"setIrrigation", Commands::setIrrigation}, {"setIrrigation", Commands::setIrrigation},