mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-01-27 09:09:25 +03:00
Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev
This commit is contained in:
@@ -334,10 +334,10 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
||||
// first see if there is a command registered and it's valid
|
||||
auto cf = find_command(device_type, device_id, cmd, flag);
|
||||
if (!cf) {
|
||||
LOG_WARNING("Command failed: invalid command '%s'", cmd ? cmd : "");
|
||||
LOG_WARNING("Command failed: unknown command '%s'", cmd ? cmd : "");
|
||||
// if we don't alread have a message set, set it to invalid command
|
||||
if (!output["message"]) {
|
||||
output["message"] = "invalid command";
|
||||
output["message"] = "unknown command";
|
||||
}
|
||||
return CommandRet::ERROR;
|
||||
}
|
||||
@@ -360,39 +360,45 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
||||
snprintf(info_s, sizeof(info_s), "'%s/%s'", dname, cmd);
|
||||
}
|
||||
|
||||
if (single_command) {
|
||||
LOG_DEBUG(("%sCalling command %s"), ro.c_str(), info_s);
|
||||
} else {
|
||||
if (id > 0) {
|
||||
LOG_INFO(("%sCalling command %s with value %s and id %d on device 0x%02X"), ro.c_str(), info_s, value, id, device_id);
|
||||
} else {
|
||||
LOG_INFO(("%sCalling command %s with value %s"), ro.c_str(), info_s, value);
|
||||
}
|
||||
}
|
||||
|
||||
// call the function based on type, either with a json package or no parameters
|
||||
// call the function based on command function type
|
||||
// commands return true or false only (bool)
|
||||
uint8_t return_code = CommandRet::OK;
|
||||
if (cf->cmdfunction_json_) {
|
||||
// JSON
|
||||
// handle commands that report back a JSON body
|
||||
return_code = ((cf->cmdfunction_json_)(value, id, output)) ? CommandRet::OK : CommandRet::ERROR;
|
||||
} else if (cf->cmdfunction_) {
|
||||
// Normal command
|
||||
// if it's a read only command and we're trying to set a value, return an error
|
||||
if (!single_command && EMSESP::cmd_is_readonly(device_type, device_id, cmd, id)) {
|
||||
return_code = CommandRet::INVALID; // error on readonly or invalid hc
|
||||
} else {
|
||||
// call it...
|
||||
return_code = ((cf->cmdfunction_)(value, id)) ? CommandRet::OK : CommandRet::ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// report back. If not OK show output from error, other return the HTTP code
|
||||
// report back. If not OK show output from error, otherwise return the HTTP code
|
||||
if (return_code != CommandRet::OK) {
|
||||
char error[100];
|
||||
if (single_command) {
|
||||
LOG_ERROR("Command '%s' failed with error '%s'", cmd, FL_(cmdRet)[return_code]);
|
||||
snprintf(error, sizeof(error), "Command '%s' failed (%s)", cmd, FL_(cmdRet)[return_code]);
|
||||
} else {
|
||||
LOG_ERROR("Command '%s: %s' failed with error '%s'", cmd, value, FL_(cmdRet)[return_code]);
|
||||
snprintf(error, sizeof(error), "Command '%s: %s' failed (%s)", cmd, value, FL_(cmdRet)[return_code]);
|
||||
}
|
||||
output.clear();
|
||||
output["message"] = error;
|
||||
LOG_WARNING(error);
|
||||
} else {
|
||||
if (single_command) {
|
||||
LOG_DEBUG(("%sCalling command %s"), ro.c_str(), info_s);
|
||||
} else {
|
||||
if (id > 0) {
|
||||
LOG_INFO(("%sCalling command %s with value %s and id %d on device 0x%02X"), ro.c_str(), info_s, value, id, device_id);
|
||||
} else {
|
||||
LOG_INFO(("%sCalling command %s with value %s"), ro.c_str(), info_s, value);
|
||||
}
|
||||
}
|
||||
return message(return_code, "callback function failed", output);
|
||||
}
|
||||
|
||||
return return_code;
|
||||
}
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(const in
|
||||
// if its a new one, the heating circuit object will be created and also the fetch flags set
|
||||
std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(std::shared_ptr<const Telegram> telegram) {
|
||||
// look through the Monitor and Set arrays to see if there is a match
|
||||
uint8_t hc_num = 0;
|
||||
uint8_t hc_num = 0; // 0 means we haven't found it yet
|
||||
bool toggle_ = false;
|
||||
|
||||
// search device-id types for remote thermostats first, they have only a single typeid for all hcs
|
||||
@@ -271,6 +271,7 @@ std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(std::sha
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// not found, search status message/set types
|
||||
if (hc_num == 0) {
|
||||
for (uint8_t i = 0; i < set_typeids.size(); i++) {
|
||||
|
||||
@@ -109,6 +109,7 @@ class Thermostat : public EMSdevice {
|
||||
return hc_num_;
|
||||
}
|
||||
|
||||
// returns heating circuit number 0..9
|
||||
uint8_t hc() const {
|
||||
return hc_num_ - 1;
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ void EMSdevice::fetch_values() {
|
||||
// toggle on/off automatic fetch for a telegramID
|
||||
void EMSdevice::toggle_fetch(uint16_t telegram_id, bool toggle) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
EMSESP::logger().debug("Toggling fetch for deviceID 0x%02X, telegramID 0x%02X to %d", device_id(), telegram_id, toggle);
|
||||
EMSESP::logger().debug("Setting fetch to %d for deviceID 0x%02X, telegramID 0x%02X", toggle, device_id(), telegram_id);
|
||||
#endif
|
||||
|
||||
for (auto & tf : telegram_functions_) {
|
||||
|
||||
@@ -746,15 +746,22 @@ void EMSESP::publish_response(std::shared_ptr<const Telegram> telegram) {
|
||||
// for other types like sensors, scheduler, custom entities it will process single commands like 'info', 'values', 'commands'...
|
||||
bool EMSESP::get_device_value_info(JsonObject root, const char * cmd, const int8_t id, const uint8_t devicetype) {
|
||||
// check first for EMS devices
|
||||
bool found_device = false;
|
||||
for (const auto & emsdevice : emsdevices) {
|
||||
if (emsdevice->device_type() == devicetype) {
|
||||
found_device = true;
|
||||
if (emsdevice->get_value_info(root, cmd, id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if the EMS device was valid, but the cmd not found show an error
|
||||
if (found_device) {
|
||||
root["message"] = std::string("unknown command ") + cmd;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for other devices...
|
||||
// check for other non EMS devices...
|
||||
|
||||
// temperature sensor
|
||||
if (devicetype == DeviceType::TEMPERATURESENSOR) {
|
||||
@@ -788,7 +795,7 @@ bool EMSESP::get_device_value_info(JsonObject root, const char * cmd, const int8
|
||||
bool EMSESP::return_not_found(JsonObject output, const char * msg, const char * cmd) {
|
||||
output.clear();
|
||||
char error[100];
|
||||
snprintf(error, sizeof(error), "cannot find %s in '%s'", msg, cmd);
|
||||
snprintf(error, sizeof(error), "cannot find %s in %s", msg, cmd);
|
||||
output["message"] = error;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -59,9 +59,9 @@ MAKE_WORD_TRANSLATION(water_device, "Water Module", "Wassermodul", "", "", "Modu
|
||||
MAKE_WORD_TRANSLATION(pool_device, "Pool Module", "Poolmodul", "", "", "Moduł basenu", "", "", "", "", "") // TODO translate
|
||||
|
||||
// commands
|
||||
MAKE_WORD_TRANSLATION(info_cmd, "lists all values", "Liste aller Werte", "lijst van alle waardes", "", "wyświetl wszystkie wartości", "Viser alle verdier", "", "Tüm değerleri listele", "elenca tutti i valori", "zobraziť všetky hodnoty") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(commands_cmd, "lists all commands", "Liste aller Kommandos", "lijst van alle commando's", "", "wyświetl wszystkie komendy", "Viser alle kommandoer", "", "Tüm komutları listele", "elencaa tutti i comandi", "zobraziť všetky príkazy") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(entities_cmd, "lists all entities", "Liste aller Entitäten", "lijst van alle entiteiten", "", "wyświetl wszsytkie encje", "Viser alle enheter", "", "Tüm varlıkları listele", "elenca tutte le entità", "zobraziť všetky entity") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(info_cmd, "list all values", "Liste aller Werte", "lijst van alle waardes", "", "wyświetl wszystkie wartości", "Viser alle verdier", "", "Tüm değerleri listele", "elenca tutti i valori", "zobraziť všetky hodnoty") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(commands_cmd, "list all commands", "Liste aller Kommandos", "lijst van alle commando's", "", "wyświetl wszystkie komendy", "Viser alle kommandoer", "", "Tüm komutları listele", "elencaa tutti i comandi", "zobraziť všetky príkazy") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(entities_cmd, "list all entities", "Liste aller Entitäten", "lijst van alle entiteiten", "", "wyświetl wszsytkie encje", "Viser alle enheter", "", "Tüm varlıkları listele", "elenca tutte le entità", "zobraziť všetky entity") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(send_cmd, "send a telegram", "Sende EMS-Telegramm", "stuur een telegram", "", "wyślij telegram", "send et telegram", "", "Bir telegram gönder", "invia un telegramma", "poslať telegram") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(setiovalue_cmd, "set io value", "Setze Wertevorgabe", "instellen standaardwaarde", "", "ustaw wartość", "sett en io verdi", "", "Giriş/Çıkış değerlerini ayarla", "imposta valore io", "nastaviť hodnotu io") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(changeloglevel_cmd, "change log level", "Ändere Sysloglevel", "aanpassen log niveau", "", "zmień poziom log-u", "endre loggnivå", "", "Kayıt seviyesini değiştir", "cambia livello registrazione", "") // TODO translate
|
||||
|
||||
17
src/mqtt.cpp
17
src/mqtt.cpp
@@ -579,7 +579,7 @@ void Mqtt::ha_status() {
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO camelCase
|
||||
// These come from the heartbeat MQTT topic
|
||||
publish_system_ha_sensor_config(DeviceValueType::STRING, "EMS Bus", "bus_status", DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::STRING, "Uptime", "uptime", DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "Uptime (sec)", "uptime_sec", DeviceValueUOM::SECONDS);
|
||||
@@ -592,6 +592,9 @@ void Mqtt::ha_status() {
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx reads", "txreads", DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx writes", "txwrites", DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx fails", "txfails", DeviceValueUOM::NONE);
|
||||
|
||||
// This comes from the info MQTT topic
|
||||
publish_system_ha_sensor_config(DeviceValueType::STRING, "Version", "version", DeviceValueUOM::NONE);
|
||||
}
|
||||
|
||||
// add sub or pub task to the queue.
|
||||
@@ -980,7 +983,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
readonly_sensors = false;
|
||||
break;
|
||||
default:
|
||||
// plain old sensor, and make read-only
|
||||
// plain old sensor, and make it read-only
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1083,12 +1086,18 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
free(F_name); // very important!
|
||||
doc["name"] = ha_name;
|
||||
|
||||
|
||||
// not needed for commands
|
||||
if (type != DeviceValueType::CMD) {
|
||||
// state topic, except for commands
|
||||
char stat_t[MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s", Mqtt::base().c_str(), tag_to_topic(device_type, tag).c_str());
|
||||
|
||||
// This is where we determine which MQTT topic to pull the data from
|
||||
// There is one exception for DeviceType::SYSTEM, which uses the heartbeat topic, and when fetching the version we want to take this from the info topic instead
|
||||
if ((device_type == EMSdevice::DeviceType::SYSTEM) && (strncmp(entity, "version", 7) == 0)) {
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s", Mqtt::base().c_str(), F_(info));
|
||||
} else {
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s", Mqtt::base().c_str(), tag_to_topic(device_type, tag).c_str());
|
||||
}
|
||||
doc["stat_t"] = stat_t;
|
||||
|
||||
// value template
|
||||
|
||||
@@ -668,7 +668,6 @@ void System::send_info_mqtt() {
|
||||
}
|
||||
|
||||
// create the json for heartbeat
|
||||
// TODO camelCase
|
||||
void System::heartbeat_json(JsonObject output) {
|
||||
switch (EMSESP::bus_status()) {
|
||||
case EMSESP::BUS_STATUS_OFFLINE:
|
||||
@@ -1414,7 +1413,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
|
||||
#endif
|
||||
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & settings) {
|
||||
if (WiFi.status() == WL_CONNECTED && !settings.bssid.isEmpty()) {
|
||||
node["BSSID"] = "set"; // TODO why is this not the actual value?
|
||||
node["BSSID"] = "set"; // TODO why is this not the actual value??
|
||||
}
|
||||
node["TxPower setting"] = settings.tx_power;
|
||||
node["static ip config"] = settings.staticIPConfig;
|
||||
|
||||
@@ -119,8 +119,8 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
// RC300WWmode2(0x31D), data: 00 00 09 07
|
||||
uart_telegram({0x10, 00, 0xFF, 00, 02, 0x1D, 00, 00, 0x09, 0x07});
|
||||
|
||||
// 2nd thermostat
|
||||
// Thermostat RCPLUSStatusMessage_HC2(0x01A6)
|
||||
// 2nd thermostat on HC2
|
||||
// Thermostat RC300Monitor(0x02A6)
|
||||
uart_telegram({0x98, 0x00, 0xFF, 0x00, 0x01, 0xA6, 0x00, 0xCF, 0x21, 0x2E, 0x00, 0x00, 0x2E, 0x24,
|
||||
0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03});
|
||||
|
||||
@@ -599,8 +599,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
if (command == "2thermostats") {
|
||||
shell.printfln("Testing multiple thermostats...");
|
||||
test("2thermostats");
|
||||
shell.invoke_command("show values");
|
||||
shell.invoke_command("show devices");
|
||||
// shell.invoke_command("show values");
|
||||
// shell.invoke_command("show devices");
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -963,17 +963,27 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
// load devices
|
||||
test("boiler");
|
||||
// test("thermostat");
|
||||
test("2thermostats");
|
||||
|
||||
if (single) {
|
||||
// run dedicated tests only
|
||||
EMSESP::webCustomEntityService.test(); // custom entities
|
||||
EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS
|
||||
EMSESP::temperaturesensor_.test(); // add temperature sensors
|
||||
EMSESP::webSchedulerService.test(); // run scheduler tests, and conditions
|
||||
// EMSESP::webCustomEntityService.test(); // custom entities
|
||||
// EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS
|
||||
// EMSESP::temperaturesensor_.test(); // add temperature sensors
|
||||
// EMSESP::webSchedulerService.test(); // run scheduler tests, and conditions
|
||||
|
||||
// request.url("/api/analogsensor/test_analog10/bad");
|
||||
// request.url("/api/thermostat/commands");
|
||||
// EMSESP::webAPIService.webAPIService(&request);
|
||||
|
||||
request.url("/api/thermostat/hc1/mode2");
|
||||
EMSESP::webAPIService.webAPIService(&request);
|
||||
|
||||
request.url("/api/thermostat/hc2/mode");
|
||||
EMSESP::webAPIService.webAPIService(&request);
|
||||
|
||||
request.url("/api/thermostat/hc1/mode");
|
||||
EMSESP::webAPIService.webAPIService(&request);
|
||||
|
||||
} else {
|
||||
EMSESP::webCustomEntityService.test(); // custom entities
|
||||
EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS
|
||||
|
||||
@@ -124,15 +124,7 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) {
|
||||
|
||||
// call command
|
||||
uint8_t return_code = Command::process(request->url().c_str(), is_admin, input, output);
|
||||
|
||||
if (return_code != CommandRet::OK) {
|
||||
char error[100];
|
||||
if (output.size()) {
|
||||
snprintf(error, sizeof(error), "API call failed. %s (%s)", (const char *)output["message"], Command::return_code_string(return_code).c_str());
|
||||
} else {
|
||||
snprintf(error, sizeof(error), "API call failed (%s)", Command::return_code_string(return_code).c_str());
|
||||
}
|
||||
emsesp::EMSESP::logger().err(error);
|
||||
api_fails_++;
|
||||
}
|
||||
|
||||
@@ -142,10 +134,10 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) {
|
||||
if (api_data) {
|
||||
request->send(200, "text/plain; charset=utf-8", api_data);
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
Serial.println();
|
||||
Serial.printf("%sweb output: %s[%s] %s(200)%s ", COLOR_WHITE, COLOR_BRIGHT_CYAN, request->url().c_str(), COLOR_BRIGHT_GREEN, COLOR_MAGENTA);
|
||||
serializeJson(output, Serial);
|
||||
Serial.println(COLOR_RESET);
|
||||
Serial.println();
|
||||
#endif
|
||||
api_count_++;
|
||||
delete response;
|
||||
@@ -166,11 +158,11 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) {
|
||||
api_count_++;
|
||||
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
Serial.println();
|
||||
Serial.printf("%sweb output: %s[%s]", COLOR_WHITE, COLOR_BRIGHT_CYAN, request->url().c_str());
|
||||
Serial.printf(" %s(%d)%s ", ret_codes[return_code] == 200 ? COLOR_BRIGHT_GREEN : COLOR_BRIGHT_RED, ret_codes[return_code], COLOR_YELLOW);
|
||||
serializeJson(output, Serial);
|
||||
Serial.println(COLOR_RESET);
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ bool WebSchedulerService::has_commands() {
|
||||
}
|
||||
|
||||
// execute scheduled command
|
||||
bool WebSchedulerService::command(const char * cmd, const char * data) {
|
||||
bool WebSchedulerService::command(const char * name, const char * cmd, const char * data) {
|
||||
JsonDocument doc_input;
|
||||
JsonObject input = doc_input.to<JsonObject>();
|
||||
if (strlen(data)) { // empty data queries a value
|
||||
@@ -347,7 +347,7 @@ bool WebSchedulerService::command(const char * cmd, const char * data) {
|
||||
|
||||
if (return_code == CommandRet::OK) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
EMSESP::logger().debug("Scheduled command '%s' with data '%s' was successful", cmd, data);
|
||||
EMSESP::logger().debug("Schedule command '%s' with data '%s' was successful", cmd, data);
|
||||
#endif
|
||||
if (strlen(data) == 0 && output.size()) {
|
||||
Mqtt::queue_publish("response", output);
|
||||
@@ -357,14 +357,10 @@ bool WebSchedulerService::command(const char * cmd, const char * data) {
|
||||
|
||||
char error[100];
|
||||
if (output.size()) {
|
||||
snprintf(error,
|
||||
sizeof(error),
|
||||
"Scheduled command %s failed with error: %s (%s)",
|
||||
cmd,
|
||||
(const char *)output["message"],
|
||||
Command::return_code_string(return_code).c_str());
|
||||
// check for empty name
|
||||
snprintf(error, sizeof(error), "Schedule %s: %s", name ? name : "", (const char *)output["message"]); // use error message if we have it
|
||||
} else {
|
||||
snprintf(error, sizeof(error), "Scheduled command %s failed with error %s", cmd, Command::return_code_string(return_code).c_str());
|
||||
snprintf(error, sizeof(error), "Schedule %s: command %s failed with error %s", name, cmd, Command::return_code_string(return_code).c_str());
|
||||
}
|
||||
|
||||
emsesp::EMSESP::logger().warning(error);
|
||||
@@ -381,7 +377,7 @@ bool WebSchedulerService::onChange(const char * cmd) {
|
||||
#ifdef EMESESP_DEBUG
|
||||
// emsesp::EMSESP::logger().debug(scheduleItem.cmd.c_str());
|
||||
#endif
|
||||
cmd_ok |= command(scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
|
||||
cmd_ok |= command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
|
||||
}
|
||||
}
|
||||
return cmd_ok;
|
||||
@@ -396,7 +392,7 @@ void WebSchedulerService::condition() {
|
||||
#endif
|
||||
if (!match.empty() && match[0] == '1') {
|
||||
if (scheduleItem.retry_cnt == 0xFF) { // default unswitched
|
||||
scheduleItem.retry_cnt = command(scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str()) ? 1 : 0xFF;
|
||||
scheduleItem.retry_cnt = command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str()) ? 1 : 0xFF;
|
||||
}
|
||||
} else if (scheduleItem.retry_cnt == 1) {
|
||||
scheduleItem.retry_cnt = 0xFF;
|
||||
@@ -429,7 +425,7 @@ void WebSchedulerService::loop() {
|
||||
if (last_tm_min == -2) {
|
||||
for (ScheduleItem & scheduleItem : *scheduleItems_) {
|
||||
if (scheduleItem.active && scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_TIMER && scheduleItem.elapsed_min == 0) {
|
||||
scheduleItem.retry_cnt = command(scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str()) ? 0xFF : 0;
|
||||
scheduleItem.retry_cnt = command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str()) ? 0xFF : 0;
|
||||
}
|
||||
}
|
||||
last_tm_min = -1; // startup done, now use for RTC
|
||||
@@ -442,12 +438,13 @@ void WebSchedulerService::loop() {
|
||||
// retry startup commands not yet executed
|
||||
if (scheduleItem.active && scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_TIMER && scheduleItem.elapsed_min == 0
|
||||
&& scheduleItem.retry_cnt < MAX_STARTUP_RETRIES) {
|
||||
scheduleItem.retry_cnt = command(scheduleItem.cmd.c_str(), scheduleItem.value.c_str()) ? 0xFF : scheduleItem.retry_cnt + 1;
|
||||
scheduleItem.retry_cnt =
|
||||
command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), scheduleItem.value.c_str()) ? 0xFF : scheduleItem.retry_cnt + 1;
|
||||
}
|
||||
// scheduled timer commands
|
||||
if (scheduleItem.active && scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_TIMER && scheduleItem.elapsed_min > 0
|
||||
&& (uptime_min % scheduleItem.elapsed_min == 0)) {
|
||||
command(scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
|
||||
command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
|
||||
}
|
||||
}
|
||||
last_uptime_min = uptime_min;
|
||||
@@ -464,7 +461,7 @@ void WebSchedulerService::loop() {
|
||||
for (const ScheduleItem & scheduleItem : *scheduleItems_) {
|
||||
uint8_t dow = scheduleItem.flags & SCHEDULEFLAG_SCHEDULE_TIMER ? 0 : scheduleItem.flags;
|
||||
if (scheduleItem.active && (real_dow & dow) && real_min == scheduleItem.elapsed_min) {
|
||||
command(scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
|
||||
command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
|
||||
}
|
||||
}
|
||||
last_tm_min = tm->tm_min;
|
||||
@@ -502,41 +499,41 @@ void WebSchedulerService::test() {
|
||||
|
||||
// should output 'locale is en'
|
||||
test_value = "\"locale is \"system/settings/locale";
|
||||
command(test_cmd.c_str(), compute(test_value).c_str());
|
||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||
|
||||
// test with negative value
|
||||
// should output 'rssi is -23'
|
||||
test_value = "\"rssi is \"0+system/network/rssi";
|
||||
command(test_cmd.c_str(), compute(test_value).c_str());
|
||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||
|
||||
// should output 'rssi is -23 dbm'
|
||||
test_value = "\"rssi is \"(system/network/rssi)\" dBm\"";
|
||||
command(test_cmd.c_str(), compute(test_value).c_str());
|
||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||
|
||||
test_value = "(custom/seltemp/value)";
|
||||
command(test_cmd.c_str(), compute(test_value).c_str());
|
||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||
|
||||
test_value = "\"seltemp=\"(custom/seltemp/value)";
|
||||
command(test_cmd.c_str(), compute(test_value).c_str());
|
||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||
|
||||
test_value = "(custom/seltemp)";
|
||||
command(test_cmd.c_str(), compute(test_value).c_str());
|
||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||
|
||||
test_value = "(boiler/outdoortemp)";
|
||||
command(test_cmd.c_str(), compute(test_value).c_str());
|
||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||
|
||||
test_value = "boiler/flowtempoffset";
|
||||
command(test_cmd.c_str(), compute(test_value).c_str());
|
||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||
|
||||
test_value = "(boiler/flowtempoffset/value)";
|
||||
command(test_cmd.c_str(), compute(test_value).c_str());
|
||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||
|
||||
test_value = "(boiler/storagetemp1/value)";
|
||||
command(test_cmd.c_str(), compute(test_value).c_str());
|
||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||
|
||||
// (14 - 40) * 2.8 + 5 = -67.8
|
||||
test_value = "(custom/seltemp - boiler/flowtempoffset) * 2.8 + 5";
|
||||
command(test_cmd.c_str(), compute(test_value).c_str());
|
||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ class WebSchedulerService : public StatefulService<WebScheduler> {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
private:
|
||||
#endif
|
||||
bool command(const char * cmd, const char * data);
|
||||
bool command(const char * name, const char * cmd, const char * data);
|
||||
void condition();
|
||||
|
||||
HttpEndpoint<WebScheduler> _httpEndpoint;
|
||||
|
||||
Reference in New Issue
Block a user