From bf4022210533ea6e8d64cc710adf88c7f1412727 Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 2 Nov 2021 21:00:16 +0100 Subject: [PATCH] validate devices to see if they are present - Refactor MQTT subscriptions #173 --- src/command.cpp | 24 ++++++++++++---------- src/command.h | 2 +- src/test/test.cpp | 11 ++++++---- src/web/WebAPIService.cpp | 42 +++++++++++++++------------------------ 4 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index 0fe9cc730..d4f289cc7 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -53,7 +53,7 @@ uint8_t Command::process(const char * path, const bool authenticated, const Json // error output.clear(); output["message"] = "unrecognized path"; - return CommandRet::ERRORED; + return CommandRet::ERROR; } } @@ -76,12 +76,12 @@ uint8_t Command::process(const char * path, const bool authenticated, const Json device_s = p.paths().front().c_str(); // get the device (boiler, thermostat, system etc) } - // validate the device + // validate the device, make sure it exists uint8_t device_type = EMSdevice::device_name_2_device_type(device_s); - if (device_type == EMSdevice::DeviceType::UNKNOWN) { + if (!device_has_commands(device_type)) { output.clear(); char error[100]; - snprintf(error, sizeof(error), "unknown device %s", device_s); + snprintf(error, sizeof(error), "no device called %s", device_s); output["message"] = error; return CommandRet::NOT_FOUND; } @@ -108,9 +108,10 @@ uint8_t Command::process(const char * path, const bool authenticated, const Json // parse_command_string returns the extracted command command_p = parse_command_string(command_p, id_n); if (command_p == nullptr) { - // default to info or values, only for device endpoints like api/system or api/boiler + // handle dead endpoints like api/system or api/boiler + // default to 'info' for SYSTEM and DALLASENSOR, the other devices to 'values' for shortname version if (num_paths < 3) { - if (device_type == EMSdevice::DeviceType::SYSTEM) { + if (device_type < EMSdevice::DeviceType::BOILER) { command_p = "info"; } else { command_p = "values"; @@ -179,8 +180,8 @@ const std::string Command::return_code_string(const uint8_t return_code) { case CommandRet::NOT_ALLOWED: return read_flash_string(F("Not authorized")); break; - case CommandRet::ERRORED: - return read_flash_string(F("Critical error")); + case CommandRet::FAIL: + return read_flash_string(F("Failed")); break; } char s[4]; @@ -252,9 +253,12 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * // check if its a call to and end-point to a device, i.e. has no value // except for system commands as this is a special device without any queryable entities (device values) - if ((device_type != EMSdevice::DeviceType::SYSTEM) && (!value || !strlen(value))) { + // exclude SYSTEM and DALLASSENSOR + if ((device_type >= EMSdevice::DeviceType::BOILER) && (!value || !strlen(value))) { if (!cf || !cf->cmdfunction_json_) { - LOG_INFO(F("Calling %s command '%s' to retrieve values"), dname.c_str(), cmd); +#if defined(EMSESP_DEBUG) + LOG_INFO(F("[DEBUG] Calling %s command '%s' to retrieve values"), dname.c_str(), cmd); +#endif return EMSESP::get_device_value_info(output, cmd, id, device_type) ? CommandRet::OK : CommandRet::ERROR; // entity = cmd } } diff --git a/src/command.h b/src/command.h index b72d3a833..682908b8e 100644 --- a/src/command.h +++ b/src/command.h @@ -49,7 +49,7 @@ enum CommandFlag : uint8_t { // return status after calling a Command enum CommandRet : uint8_t { - ERRORED = 0, // 0 or FALSE + FAIL = 0, // 0 or FALSE OK, // 1 or TRUE NOT_FOUND, // 2 ERROR, // 3 diff --git a/src/test/test.cpp b/src/test/test.cpp index 12fdcf055..fdd38e761 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -513,7 +513,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { EMSESP::webAPIService.webAPIService_get(&request2); request2.url("/api/thermostat/info"); EMSESP::webAPIService.webAPIService_get(&request2); - request2.url("/api/thermostat/list"); + request2.url("/api/thermostat/values"); EMSESP::webAPIService.webAPIService_get(&request2); return; @@ -522,6 +522,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { return; */ + /* request2.url("/api/system"); // check if defaults to info EMSESP::webAPIService.webAPIService_get(&request2); emsesp::EMSESP::logger().notice("*"); @@ -540,13 +541,15 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { request2.url("/api/thermostat/seltemp"); EMSESP::webAPIService.webAPIService_get(&request2); + return; + + */ - emsesp::EMSESP::logger().notice("****"); request2.url("/api/dallassensor/fdfd"); EMSESP::webAPIService.webAPIService_get(&request2); + emsesp::EMSESP::logger().notice("****"); request2.url("/api/dallassensor/info"); EMSESP::webAPIService.webAPIService_get(&request2); - return; /* AsyncWebServerRequest request2; @@ -632,7 +635,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { EMSESP::webAPIService.webAPIService_get(&request); request.url("/api/thermostat/info"); EMSESP::webAPIService.webAPIService_get(&request); - request.url("/api/thermostat/list"); + request.url("/api/thermostat/values"); EMSESP::webAPIService.webAPIService_get(&request); request.url("/api/thermostat/seltemp"); EMSESP::webAPIService.webAPIService_get(&request); diff --git a/src/web/WebAPIService.cpp b/src/web/WebAPIService.cpp index 6072a447c..b01f237a7 100644 --- a/src/web/WebAPIService.cpp +++ b/src/web/WebAPIService.cpp @@ -77,31 +77,6 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject & input) { // call command uint8_t return_code = Command::process(request->url().c_str(), authenticated, input, output); - // handle response codes - // the output will be populated with a message key if an error occurred - int ret_code; - if (return_code == CommandRet::NOT_ALLOWED) { - ret_code = 401; // Unauthorized - } else if (return_code == CommandRet::NOT_FOUND) { - ret_code = 400; // Bad request - } else if (return_code == CommandRet::OK) { - ret_code = 200; // OK - // if there was not json output from the call, default to the message 'OK'. - // this will be used for example when calling endpoints e.g. /api/thermostat/temp - if (!output.size()) { - output["message"] = "OK"; - } - } else { - ret_code = 400; // Bad request - } - - // send the json that came back from the command call - response->setCode(ret_code); - response->setLength(); - response->setContentType("application/json"); - request->send(response); // send json response - - // do a log entry if there is an error if (return_code != CommandRet::OK) { char error[100]; if (output.size()) { @@ -110,12 +85,27 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject & input) { snprintf(error, sizeof(error), "Call failed with error code (%s)", Command::return_code_string(return_code).c_str()); } emsesp::EMSESP::logger().err(error); + } else { + emsesp::EMSESP::logger().info(F("Command called")); + // if there was not json output from the call, default to the message 'OK'. + // this will be used for example when calling endpoints e.g. /api/thermostat/temp + if (!output.size()) { + output["message"] = "OK"; + } } + // send the json that came back from the command call + // FAIL, OK, NOT_FOUND, ERROR, NOT_ALLOWED = 400 (bad request), 200 (OK), 400 (not found), 400 (bad request), 401 (unauthorized) + int ret_codes[5] = {400, 200, 400, 400, 401}; + response->setCode(ret_codes[return_code]); + response->setLength(); + response->setContentType("application/json"); + request->send(response); + #if defined(EMSESP_STANDALONE) Serial.print(COLOR_YELLOW); Serial.print("web response code: "); - Serial.println(ret_code); + Serial.println(ret_codes[return_code]); if (output.size()) { serializeJsonPretty(output, Serial); }