mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
some more refactoring around processing commands
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,6 +360,34 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
||||
snprintf(info_s, sizeof(info_s), "'%s/%s'", dname, cmd);
|
||||
}
|
||||
|
||||
// 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_) {
|
||||
// handle commands that report back a JSON body
|
||||
return_code = ((cf->cmdfunction_json_)(value, id, output)) ? CommandRet::OK : CommandRet::ERROR;
|
||||
} else if (cf->cmdfunction_) {
|
||||
// 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, otherwise return the HTTP code
|
||||
if (return_code != CommandRet::OK) {
|
||||
char error[100];
|
||||
if (single_command) {
|
||||
snprintf(error, sizeof(error), "Command '%s' failed (%s)", cmd, FL_(cmdRet)[return_code]);
|
||||
} else {
|
||||
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 {
|
||||
@@ -369,30 +397,8 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
||||
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
|
||||
uint8_t return_code = CommandRet::OK;
|
||||
if (cf->cmdfunction_json_) {
|
||||
// JSON
|
||||
return_code = ((cf->cmdfunction_json_)(value, id, output)) ? CommandRet::OK : CommandRet::ERROR;
|
||||
} else if (cf->cmdfunction_) {
|
||||
// Normal command
|
||||
if (!single_command && EMSESP::cmd_is_readonly(device_type, device_id, cmd, id)) {
|
||||
return_code = CommandRet::INVALID; // error on readonly or invalid hc
|
||||
} else {
|
||||
return_code = ((cf->cmdfunction_)(value, id)) ? CommandRet::OK : CommandRet::ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// report back. If not OK show output from error, other return the HTTP code
|
||||
if (return_code != CommandRet::OK) {
|
||||
if (single_command) {
|
||||
LOG_ERROR("Command '%s' failed with error '%s'", cmd, FL_(cmdRet)[return_code]);
|
||||
} else {
|
||||
LOG_ERROR("Command '%s: %s' failed with error '%s'", cmd, value, FL_(cmdRet)[return_code]);
|
||||
}
|
||||
return message(return_code, "callback function failed", output);
|
||||
}
|
||||
return return_code;
|
||||
}
|
||||
|
||||
@@ -523,7 +529,13 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo
|
||||
std::list<std::string> sorted_cmds;
|
||||
for (const auto & cf : cmdfunctions_) {
|
||||
if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN)) {
|
||||
sorted_cmds.push_back(tagged_cmd(cf.cmd_, cf.flags_));
|
||||
// remove duplicates
|
||||
auto line = tagged_cmd(cf.cmd_, cf.flags_);
|
||||
// only add if not already in list
|
||||
// removes duplicates if having more than one device (e.g. 2 thermostats)
|
||||
if (std::find(sorted_cmds.begin(), sorted_cmds.end(), line) == sorted_cmds.end()) {
|
||||
sorted_cmds.push_back(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -746,11 +746,19 @@ 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) {
|
||||
return emsdevice->get_value_info(root, cmd, id);
|
||||
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) {
|
||||
// return EMSESP::return_not_found(root, "poep", cmd); // not found
|
||||
}
|
||||
|
||||
// check for other devices...
|
||||
|
||||
@@ -786,7 +794,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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user