From 31cfdc6604f61b2206a886fd9dd42aa00c3948f4 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 10 Oct 2024 21:26:22 +0100 Subject: [PATCH] support single scheduler item updates for Dashboard --- src/web/WebSchedulerService.cpp | 88 +++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 27 deletions(-) diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index b1b0229c4..dae491fa9 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -49,10 +49,10 @@ void WebSchedulerService::begin() { // and also calls when the Scheduler web page is refreshed void WebScheduler::read(WebScheduler & webScheduler, JsonObject root) { JsonArray schedule = root["schedule"].to(); - uint8_t counter = 0; + uint8_t counter = 1; for (const ScheduleItem & scheduleItem : webScheduler.scheduleItems) { JsonObject si = schedule.add(); - si["id"] = counter++; // id is only used to render the table and must be unique + si["id"] = counter++; // id is only used to render the table and must be unique. 0 is for Dashboard si["flags"] = scheduleItem.flags; si["active"] = scheduleItem.flags != SCHEDULEFLAG_SCHEDULE_IMMEDIATE ? scheduleItem.active : false; si["time"] = scheduleItem.flags != SCHEDULEFLAG_SCHEDULE_IMMEDIATE ? scheduleItem.time : ""; @@ -65,39 +65,60 @@ void WebScheduler::read(WebScheduler & webScheduler, JsonObject root) { // call on initialization and also when the Schedule web page is saved // this loads the data into the internal class StateUpdateResult WebScheduler::update(JsonObject root, WebScheduler & webScheduler) { + // check if we're only toggling it on/off via the Dashboard + // if it is a single schedule object and id is 0 + if (root["schedule"].is()) { + JsonObject si = root["schedule"]; + if (si["id"] == 0) { + // find the item, matching the name + for (ScheduleItem & scheduleItem : webScheduler.scheduleItems) { + std::string name = si["name"].as(); + if (scheduleItem.name == name) { + scheduleItem.active = si["active"]; + EMSESP::webSchedulerService.publish(true); + return StateUpdateResult::CHANGED; + } + } + return StateUpdateResult::UNCHANGED; + } + } + + // otherwise we're updating and saving the whole list again + if (!root["schedule"].is()) { + return StateUpdateResult::ERROR; // invalid format + } + // reset the list Command::erase_device_commands(EMSdevice::DeviceType::SCHEDULER); webScheduler.scheduleItems.clear(); EMSESP::webSchedulerService.ha_reset(); // build up the list of schedule items - if (root["schedule"].is()) { - for (const JsonObject schedule : root["schedule"].as()) { - // create each schedule item, overwriting any previous settings - // ignore the id (as this is only used in the web for table rendering) - auto si = ScheduleItem(); - si.active = schedule["active"]; - si.flags = schedule["flags"]; - si.time = si.flags == SCHEDULEFLAG_SCHEDULE_IMMEDIATE ? "" : schedule["time"].as(); - si.cmd = schedule["cmd"].as(); - si.value = schedule["value"].as(); - si.name = schedule["name"].as(); + for (const JsonObject schedule : root["schedule"].as()) { + // create each schedule item, overwriting any previous settings + // ignore the id (as this is only used in the web for table rendering) + auto si = ScheduleItem(); + si.active = schedule["active"]; + si.flags = schedule["flags"]; + si.time = si.flags == SCHEDULEFLAG_SCHEDULE_IMMEDIATE ? "" : schedule["time"].as(); + si.cmd = schedule["cmd"].as(); + si.value = schedule["value"].as(); + si.name = schedule["name"].as(); - // calculated elapsed minutes - si.elapsed_min = Helpers::string2minutes(si.time); - si.retry_cnt = 0xFF; // no startup retries + // calculated elapsed minutes + si.elapsed_min = Helpers::string2minutes(si.time); + si.retry_cnt = 0xFF; // no startup retries - webScheduler.scheduleItems.push_back(si); // add to list - if (!webScheduler.scheduleItems.back().name.empty()) { - Command::add( - EMSdevice::DeviceType::SCHEDULER, - webScheduler.scheduleItems.back().name.c_str(), - [webScheduler](const char * value, const int8_t id) { - return EMSESP::webSchedulerService.command_setvalue(value, id, webScheduler.scheduleItems.back().name.c_str()); - }, - FL_(schedule_cmd), - CommandFlag::ADMIN_ONLY); - } + webScheduler.scheduleItems.push_back(si); // add to list + if (!webScheduler.scheduleItems.back().name.empty()) { + Command::add( + EMSdevice::DeviceType::SCHEDULER, + webScheduler.scheduleItems.back().name.c_str(), + [webScheduler](const char * value, const int8_t id) { + return EMSESP::webSchedulerService.command_setvalue(value, id, webScheduler.scheduleItems.back().name.c_str()); + }, + FL_(schedule_cmd), + CommandFlag::ADMIN_ONLY); } } @@ -551,6 +572,19 @@ void WebSchedulerService::test() { si.elapsed_min = 0; si.retry_cnt = 0xFF; // no startup retries + webScheduler.scheduleItems.push_back(si); + + // test 2 + si = ScheduleItem(); + si.active = false; + si.flags = 1; + si.time = "13:00"; + si.cmd = "system/message"; + si.value = "20"; + si.name = ""; // to make sure its excluded from Dashboard + si.elapsed_min = 0; + si.retry_cnt = 0xFF; // no startup retries + webScheduler.scheduleItems.push_back(si); already_added = true;