mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-06-13 19:36:26 +03:00
optimize
This commit is contained in:
@@ -86,37 +86,39 @@ StateUpdateResult WebScheduler::update(JsonObject root, WebScheduler & webSchedu
|
|||||||
|
|
||||||
auto scheduleItems = root["schedule"].as<JsonArray>();
|
auto scheduleItems = root["schedule"].as<JsonArray>();
|
||||||
for (const JsonObject schedule : scheduleItems) {
|
for (const JsonObject schedule : scheduleItems) {
|
||||||
auto si = ScheduleItem();
|
// create each schedule item, overwriting any previous settings
|
||||||
si.active = schedule["active"];
|
// ignore the id (as this is only used in the web for table rendering)
|
||||||
si.flags = schedule["flags"];
|
auto si = ScheduleItem();
|
||||||
si.time = schedule["time"].as<std::string>();
|
si.active = schedule["active"];
|
||||||
si.cmd_name = schedule["cmd_name"].as<std::string>();
|
si.flags = schedule["flags"];
|
||||||
|
si.time = schedule["time"].as<std::string>();
|
||||||
|
si.cmd_name = schedule["cmd_name"].as<std::string>();
|
||||||
strlcpy(si.name, schedule["name"].as<const char *>(), sizeof(si.name));
|
strlcpy(si.name, schedule["name"].as<const char *>(), sizeof(si.name));
|
||||||
|
|
||||||
|
// calculated elapsed minutes
|
||||||
si.elapsed_min = Helpers::string2minutes(si.time.c_str());
|
si.elapsed_min = Helpers::string2minutes(si.time.c_str());
|
||||||
si.retry_cnt = 0xFF;
|
si.retry_cnt = 0xFF;
|
||||||
|
|
||||||
webScheduler.scheduleItems.push_back(si);
|
webScheduler.scheduleItems.push_back(si);
|
||||||
if (webScheduler.scheduleItems.back().name[0] != '\0') {
|
char key[sizeof(webScheduler.scheduleItems.back().name) + 2];
|
||||||
char key[sizeof(webScheduler.scheduleItems.back().name) + 2];
|
snprintf(key, sizeof(key), "s:%s", webScheduler.scheduleItems.back().name);
|
||||||
snprintf(key, sizeof(key), "s:%s", webScheduler.scheduleItems.back().name);
|
if (EMSESP::nvs_.isKey(key)) {
|
||||||
if (EMSESP::nvs_.isKey(key)) {
|
webScheduler.scheduleItems.back().active = EMSESP::nvs_.getBool(key);
|
||||||
webScheduler.scheduleItems.back().active = EMSESP::nvs_.getBool(key);
|
|
||||||
}
|
|
||||||
Command::add(
|
|
||||||
EMSdevice::DeviceType::SCHEDULER,
|
|
||||||
webScheduler.scheduleItems.back().name,
|
|
||||||
[webScheduler](const char * value, const int8_t id) {
|
|
||||||
return EMSESP::webSchedulerService.command_setvalue(value, id, webScheduler.scheduleItems.back().name);
|
|
||||||
},
|
|
||||||
FL_(schedule_cmd),
|
|
||||||
CommandFlag::ADMIN_ONLY);
|
|
||||||
}
|
}
|
||||||
|
Command::add(
|
||||||
|
EMSdevice::DeviceType::SCHEDULER,
|
||||||
|
webScheduler.scheduleItems.back().name,
|
||||||
|
[name = std::string(webScheduler.scheduleItems.back().name)](const char * value, const int8_t id) {
|
||||||
|
return EMSESP::webSchedulerService.command_setvalue(value, id, name.c_str());
|
||||||
|
},
|
||||||
|
FL_(schedule_cmd),
|
||||||
|
CommandFlag::ADMIN_ONLY);
|
||||||
}
|
}
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set active by api command
|
// set active by api command
|
||||||
|
// value is a boolean to enable/disable the schedule item
|
||||||
bool WebSchedulerService::command_setvalue(const char * value, const int8_t id, const char * name) {
|
bool WebSchedulerService::command_setvalue(const char * value, const int8_t id, const char * name) {
|
||||||
bool v;
|
bool v;
|
||||||
if (!Helpers::value2bool(value, v)) {
|
if (!Helpers::value2bool(value, v)) {
|
||||||
@@ -132,7 +134,7 @@ bool WebSchedulerService::command_setvalue(const char * value, const int8_t id,
|
|||||||
scheduleItem.active = v;
|
scheduleItem.active = v;
|
||||||
publish_single(name, v);
|
publish_single(name, v);
|
||||||
|
|
||||||
if (EMSESP::mqtt_.get_publish_onchange(0)) {
|
if (EMSESP::mqtt_.get_publish_onchange(EMSdevice::DeviceType::SYSTEM)) {
|
||||||
publish();
|
publish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +213,7 @@ void WebSchedulerService::get_value_json(JsonObject output, const ScheduleItem &
|
|||||||
output["name"] = (const char *)scheduleItem.name;
|
output["name"] = (const char *)scheduleItem.name;
|
||||||
output["fullname"] = (const char *)scheduleItem.name;
|
output["fullname"] = (const char *)scheduleItem.name;
|
||||||
output["type"] = "boolean";
|
output["type"] = "boolean";
|
||||||
Mqtt::add_value_bool(output, "value", scheduleItem.active);
|
Mqtt::add_value_bool(output, "active", scheduleItem.active);
|
||||||
if (scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_CONDITION) {
|
if (scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_CONDITION) {
|
||||||
output["condition"] = scheduleItem.time;
|
output["condition"] = scheduleItem.time;
|
||||||
} else if (scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_ONCHANGE) {
|
} else if (scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_ONCHANGE) {
|
||||||
@@ -221,11 +223,11 @@ void WebSchedulerService::get_value_json(JsonObject output, const ScheduleItem &
|
|||||||
} else {
|
} else {
|
||||||
output["time"] = scheduleItem.time;
|
output["time"] = scheduleItem.time;
|
||||||
}
|
}
|
||||||
output["cmd_name"] = scheduleItem.cmd_name;
|
output["cmd_name"] = scheduleItem.cmd_name;
|
||||||
bool hasName = scheduleItem.name[0] != '\0';
|
// bool hasName = scheduleItem.name[0] != '\0';
|
||||||
output["readable"] = hasName;
|
// output["readable"] = hasName;
|
||||||
output["writeable"] = hasName;
|
// output["writeable"] = hasName;
|
||||||
output["visible"] = hasName;
|
// output["visible"] = hasName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish single value
|
// publish single value
|
||||||
@@ -256,7 +258,7 @@ void WebSchedulerService::publish(const bool force) {
|
|||||||
publish_single(scheduleItem.name, scheduleItem.active);
|
publish_single(scheduleItem.name, scheduleItem.active);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (!EMSESP::mqtt_.get_publish_onchange(0)) {
|
} else if (!EMSESP::mqtt_.get_publish_onchange(EMSdevice::DeviceType::SYSTEM)) {
|
||||||
return; // wait for first time period
|
return; // wait for first time period
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,7 +284,6 @@ void WebSchedulerService::publish(const bool force) {
|
|||||||
snprintf(val_obj, sizeof(val_obj), "value_json['%s']", scheduleItem.name);
|
snprintf(val_obj, sizeof(val_obj), "value_json['%s']", scheduleItem.name);
|
||||||
snprintf(val_cond, sizeof(val_cond), "%s is defined", val_obj);
|
snprintf(val_cond, sizeof(val_cond), "%s is defined", val_obj);
|
||||||
|
|
||||||
// Optimized: use stack buffer instead of string concatenation to avoid heap allocations
|
|
||||||
char val_tpl[150];
|
char val_tpl[150];
|
||||||
if (Mqtt::discovery_type() == Mqtt::discoveryType::HOMEASSISTANT) {
|
if (Mqtt::discovery_type() == Mqtt::discoveryType::HOMEASSISTANT) {
|
||||||
snprintf(val_tpl, sizeof(val_tpl), "{{%s if %s}}", val_obj, val_cond);
|
snprintf(val_tpl, sizeof(val_tpl), "{{%s if %s}}", val_obj, val_cond);
|
||||||
@@ -296,7 +297,7 @@ void WebSchedulerService::publish(const bool force) {
|
|||||||
|
|
||||||
config["uniq_id"] = uniq_s;
|
config["uniq_id"] = uniq_s;
|
||||||
config["name"] = (const char *)scheduleItem.name;
|
config["name"] = (const char *)scheduleItem.name;
|
||||||
// Optimized: use stack buffer instead of string concatenation
|
|
||||||
char def_ent_id[80];
|
char def_ent_id[80];
|
||||||
snprintf(def_ent_id, sizeof(def_ent_id), "switch.%s", uniq_s);
|
snprintf(def_ent_id, sizeof(def_ent_id), "switch.%s", uniq_s);
|
||||||
config["def_ent_id"] = def_ent_id;
|
config["def_ent_id"] = def_ent_id;
|
||||||
@@ -341,8 +342,7 @@ bool WebSchedulerService::runScheduleCommand(const ScheduleItem & si) {
|
|||||||
return EMSESP::webCommandService.executeCommand(si.cmd_name.c_str());
|
return EMSESP::webCommandService.executeCommand(si.cmd_name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from emsesp.cpp on every entity-change
|
// queue schedules to be handled executed in WebSchedulerService::loop() called from emsesp.cpp
|
||||||
// queue schedules to be handled executed in scheduler-loop
|
|
||||||
bool WebSchedulerService::onChange(const char * cmd) {
|
bool WebSchedulerService::onChange(const char * cmd) {
|
||||||
for (ScheduleItem & scheduleItem : *scheduleItems_) {
|
for (ScheduleItem & scheduleItem : *scheduleItems_) {
|
||||||
if (scheduleItem.active && scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_ONCHANGE && Helpers::toLower(scheduleItem.time.c_str()) == Helpers::toLower(cmd)) {
|
if (scheduleItem.active && scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_ONCHANGE && Helpers::toLower(scheduleItem.time.c_str()) == Helpers::toLower(cmd)) {
|
||||||
@@ -462,22 +462,22 @@ void WebSchedulerService::load_test_data() {
|
|||||||
update([&](WebScheduler & webScheduler) {
|
update([&](WebScheduler & webScheduler) {
|
||||||
webScheduler.scheduleItems.clear();
|
webScheduler.scheduleItems.clear();
|
||||||
|
|
||||||
auto si = ScheduleItem();
|
auto si = ScheduleItem();
|
||||||
si.active = true;
|
si.active = true;
|
||||||
si.flags = 1; // day schedule
|
si.flags = 1; // day schedule
|
||||||
si.time = "12:00";
|
si.time = "12:00";
|
||||||
si.cmd_name = "test_cmd1";
|
si.cmd_name = "fetch_values";
|
||||||
strcpy(si.name, "test_scheduler1");
|
strcpy(si.name, "test_scheduler1");
|
||||||
si.elapsed_min = 0;
|
si.elapsed_min = 0;
|
||||||
si.retry_cnt = 0xFF;
|
si.retry_cnt = 0xFF;
|
||||||
|
|
||||||
webScheduler.scheduleItems.push_back(si);
|
webScheduler.scheduleItems.push_back(si);
|
||||||
|
|
||||||
si = ScheduleItem();
|
si = ScheduleItem();
|
||||||
si.active = true;
|
si.active = true;
|
||||||
si.flags = SCHEDULEFLAG_SCHEDULE_TIMER;
|
si.flags = SCHEDULEFLAG_SCHEDULE_TIMER;
|
||||||
si.time = "01:00";
|
si.time = "01:00";
|
||||||
si.cmd_name = "test_cmd2";
|
si.cmd_name = "send_message";
|
||||||
strcpy(si.name, "test_scheduler2");
|
strcpy(si.name, "test_scheduler2");
|
||||||
si.elapsed_min = 60;
|
si.elapsed_min = 60;
|
||||||
si.retry_cnt = 0xFF;
|
si.retry_cnt = 0xFF;
|
||||||
|
|||||||
Reference in New Issue
Block a user