From cd016ae6397be246feeb52b5cd66988d1a8fa802 Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 23 Nov 2020 13:13:59 +0100 Subject: [PATCH] split out commands with and without json --- src/WebAPIService.cpp | 2 +- src/command.cpp | 76 ++++++++++++++++++++++++++----------------- src/command.h | 12 ++++--- 3 files changed, 54 insertions(+), 36 deletions(-) diff --git a/src/WebAPIService.cpp b/src/WebAPIService.cpp index 94da9e153..bcbbe3795 100644 --- a/src/WebAPIService.cpp +++ b/src/WebAPIService.cpp @@ -52,7 +52,7 @@ void WebAPIService::webAPIService(AsyncWebServerRequest * request) { String cmd = request->getParam(F_(cmd))->value(); // look up command in our list - if (!Command::find_command(device_type, cmd.c_str())) { + if (Command::find_command(device_type, cmd.c_str()) == nullptr) { request->send(400, "text/plain", F("Invalid cmd")); return; } diff --git a/src/command.cpp b/src/command.cpp index 78d0c4f2d..880a479a8 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -29,6 +29,29 @@ std::vector Command::cmdfunctions_; // calls a command, context is the device_type // id may be used to represent a heating circuit for example // returns false if error or not found +bool Command::call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id) { +#ifdef EMSESP_DEBUG + std::string dname = EMSdevice::device_type_2_device_name(device_type); + if (value == nullptr) { + LOG_DEBUG(F("[DEBUG] Calling %s command %s"), dname.c_str(), cmd); + } else if (id == -1) { + LOG_DEBUG(F("[DEBUG] Calling %s command %s, value %s, id is default"), dname.c_str(), cmd, value); + } else { + LOG_DEBUG(F("[DEBUG] Calling %s command %s, value %s, id is %d"), dname.c_str(), cmd, value, id); + } +#endif + + auto cf = find_command(device_type, cmd); + if ((cf == nullptr) || (cf->cmdfunction_json_)) { + return false; // command not found, or requires a json + } + + return ((cf->cmdfunction_)(value, id)); +} + +// calls a command, context is the device_type. Takes a json object for output. +// id may be used to represent a heating circuit for example +// returns false if error or not found bool Command::call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id, JsonObject & json) { #ifdef EMSESP_DEBUG std::string dname = EMSdevice::device_type_2_device_name(device_type); @@ -37,31 +60,22 @@ bool Command::call(const uint8_t device_type, const char * cmd, const char * val } else if (id == -1) { LOG_DEBUG(F("[DEBUG] Calling %s command %s, value %s, id is default"), dname.c_str(), cmd, value); } else { - LOG_DEBUG(F("[DEBUG] Calling %s command %s, value %s, id is %d in %s"), dname.c_str(), cmd, value, id); + LOG_DEBUG(F("[DEBUG] Calling %s command %s, value %s, id is %d"), dname.c_str(), cmd, value, id); } #endif - bool ok = false; - if (!cmdfunctions_.empty()) { - for (const auto & cf : cmdfunctions_) { - if (cf.device_type_ == device_type) { - // find a matching command and call it - if (uuid::read_flash_string(cf.cmd_) == cmd) { - // see if we this function wants to send its result to a json doc - if (cf.cmdfunction_json_) { - // check if json object is empty, if so quit - if (json.isNull()) { - LOG_WARNING(F("Ignore call for command %s in %s because no json"), cmd, EMSdevice::device_type_2_device_name(device_type).c_str()); - return false; - } - ok |= ((cf.cmdfunction_json_)(value, id, json)); - } else { - ok |= ((cf.cmdfunction_)(value, id)); - } - } - } - } + + auto cf = find_command(device_type, cmd); + if ((cf == nullptr) || (!cf->cmdfunction_json_)) { + return false; // command not found or not json } - return ok; + + // check if json object is empty, if so quit + if (json.isNull()) { + LOG_WARNING(F("Ignore call for command %s in %s because no json"), cmd, EMSdevice::device_type_2_device_name(device_type).c_str()); + return false; + } + + return ((cf->cmdfunction_json_)(value, id, json)); } // add a command to the list, which does not return json @@ -77,24 +91,26 @@ void Command::add(const uint8_t device_type, const uint8_t device_id, const __Fl // add a command to the list, which does return json object as output void Command::add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb) { // if the command already exists for that device type don't add it - if (!find_command(device_type, uuid::read_flash_string(cmd).c_str())) { - cmdfunctions_.emplace_back(device_type, cmd, nullptr, cb); + if (find_command(device_type, uuid::read_flash_string(cmd).c_str()) != nullptr) { + return; } + + cmdfunctions_.emplace_back(device_type, cmd, nullptr, cb); // add command } // see if a command exists for that device type -bool Command::find_command(const uint8_t device_type, const char * cmd) { - if ((cmd == nullptr) || (strlen(cmd) == 0)) { - return false; +Command::CmdFunction * Command::find_command(const uint8_t device_type, const char * cmd) { + if ((cmd == nullptr) || (strlen(cmd) == 0) || (cmdfunctions_.empty())) { + return nullptr; } - for (const auto & cf : cmdfunctions_) { + for (auto & cf : cmdfunctions_) { if (!strcmp_P(cmd, reinterpret_cast(cf.cmd_)) && (cf.device_type_ == device_type)) { - return true; + return &cf; } } - return false; // not found + return nullptr; // not found } // output list of all commands to console for a specific DeviceType diff --git a/src/command.h b/src/command.h index 2910ca2be..eeb142b59 100644 --- a/src/command.h +++ b/src/command.h @@ -57,11 +57,13 @@ class Command { return cmdfunctions_; } - static bool call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id, JsonObject & json); - static void add(const uint8_t device_type, const uint8_t device_id, const __FlashStringHelper * cmd, cmdfunction_p cb); - static void add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb); - static void show_all(uuid::console::Shell & shell); - static bool find_command(const uint8_t device_type, const char * cmd); + static bool call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id, JsonObject & json); + static bool call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id); + static void add(const uint8_t device_type, const uint8_t device_id, const __FlashStringHelper * cmd, cmdfunction_p cb); + static void add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb); + static void show_all(uuid::console::Shell & shell); + static Command::CmdFunction * find_command(const uint8_t device_type, const char * cmd); + static void show(uuid::console::Shell & shell, uint8_t device_type); static void show_devices(uuid::console::Shell & shell); static bool device_has_commands(const uint8_t device_type);