Call read commands from Web #2116

This commit is contained in:
proddy
2024-10-20 15:02:11 +02:00
parent bd08b7e0e4
commit 798e20a266
25 changed files with 282 additions and 127 deletions

View File

@@ -379,30 +379,25 @@ static void setup_commands(std::shared_ptr<Commands> const & commands) {
}
});
// read <deviceID> <type ID> [offset] [length]
commands->add_command(ShellContext::MAIN,
CommandFlags::USER,
{F_(read)},
string_vector{F_(deviceid_mandatory), F_(typeid_mandatory), F_(offset_optional), F_(length_optional)},
[=](Shell & shell, const std::vector<std::string> & arguments) {
uint8_t device_id = Helpers::hextoint(arguments.front().c_str());
// loop through arguments and add to data as text, separated by a space
std::string data;
for (const auto & arg : arguments) {
if (!data.empty()) {
data += " ";
}
data += arg;
}
if (!EMSESP::valid_device(device_id)) {
if (!System::readCommand(data.c_str())) {
shell.printfln("Invalid deviceID");
return;
}
uint16_t type_id = Helpers::hextoint(arguments[1].c_str());
if (arguments.size() == 4) {
uint16_t offset = Helpers::hextoint(arguments[2].c_str());
uint8_t length = Helpers::hextoint(arguments.back().c_str());
EMSESP::send_read_request(type_id, device_id, offset, length, true);
} else if (arguments.size() == 3) {
uint16_t offset = Helpers::hextoint(arguments.back().c_str());
EMSESP::send_read_request(type_id, device_id, offset, 0, true);
} else {
EMSESP::send_read_request(type_id, device_id, 0, 0, true);
}
EMSESP::set_read_id(type_id);
});
commands->add_command(ShellContext::MAIN,

View File

@@ -834,4 +834,14 @@ float Helpers::numericoperator2scalefactor(int8_t numeric_operator) {
return -numeric_operator;
}
// convert the data into a vector of strings
void Helpers::splitArguments(const char * data, std::vector<std::string> & arguments) {
std::stringstream ss(data);
std::string item;
while (std::getline(ss, item, ' ')) {
arguments.push_back(item);
}
}
} // namespace emsesp

View File

@@ -19,8 +19,9 @@
#ifndef EMSESP_HELPERS_H
#define EMSESP_HELPERS_H
#include "telegram.h" // for EMS_VALUE_* settings
#include <sstream>
#include "telegram.h" // for EMS_VALUE_* settings
#include "common.h"
namespace emsesp {
@@ -82,6 +83,8 @@ class Helpers {
static const char * translated_word(const char * const * strings, const bool force_en = false);
static void splitArguments(const char * data, std::vector<std::string> & arguments);
#ifdef EMSESP_STANDALONE
static char * ultostr(char * ptr, uint32_t value, const uint8_t base);
#endif

View File

@@ -63,6 +63,7 @@ MAKE_WORD_TRANSLATION(info_cmd, "list all values (verbose)", "Liste aller Werte"
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(read_cmd, "send read request", "", "", "", "", "", "", "", "", "") // TODO translate
MAKE_WORD_TRANSLATION(setiovalue_cmd, "set I/O value", "Setze Werte E/A", "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 Protokollebene", "aanpassen log niveau", "", "zmień poziom log-u", "endre loggnivå", "", "Kayıt seviyesini değiştir", "cambia livello registrazione", "zmeniť úroveň protokolu") // TODO translate
MAKE_WORD_TRANSLATION(fetch_cmd, "refresh all EMS values", "Aktualisiere alle EMS-Werte", "Verversen alle EMS waardes", "", "odśwież wszystkie wartości EMS", "oppfrisk alle EMS verdier", "", "Bütün EMS değerlerini yenile", "aggiornare tutti i valori EMS", "obnoviť všetky hodnoty EMS") // TODO translate

View File

@@ -409,7 +409,8 @@ void System::reload_settings() {
eth_phy_addr_ = settings.eth_phy_addr;
eth_clock_mode_ = settings.eth_clock_mode;
locale_ = settings.locale;
locale_ = settings.locale;
developer_mode_ = settings.developer_mode;
});
}
@@ -851,6 +852,7 @@ void System::system_check() {
// commands - takes static function pointers
// can be called via Console using 'call system <cmd>'
void System::commands_init() {
Command::add(EMSdevice::DeviceType::SYSTEM, F_(read), System::command_read, FL_(read_cmd), CommandFlag::ADMIN_ONLY);
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send, FL_(send_cmd), CommandFlag::ADMIN_ONLY);
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch, FL_(fetch_cmd), CommandFlag::ADMIN_ONLY);
Command::add(EMSdevice::DeviceType::SYSTEM, F_(restart), System::command_restart, FL_(restart_cmd), CommandFlag::ADMIN_ONLY);
@@ -1689,6 +1691,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
#endif
node["modbusEnabled"] = settings.modbus_enabled;
node["forceHeatingOff"] = settings.boiler_heatingoff;
node["developerMode"] = settings.developer_mode;
});
// Devices - show EMS devices if we have any
@@ -2012,4 +2015,45 @@ bool System::uploadFirmwareURL(const char * url) {
return true; // OK
}
// read command, e.g. read <deviceID> <type ID> [offset] [length] from console
// or a call system read <deviceID> <type ID> [offset] [length] from the API
bool System::readCommand(const char * data) {
// convert the data into a vector of strings
std::vector<std::string> arguments = {};
Helpers::splitArguments(data, arguments);
auto num_args = arguments.size();
if (num_args > 4 || num_args == 0) {
return false;
}
uint8_t device_id = Helpers::hextoint(arguments[0].c_str());
if (!EMSESP::valid_device(device_id)) {
LOG_ERROR("Invalid device ID for read command");
return false; // invalid device
}
uint16_t type_id = Helpers::hextoint(arguments[1].c_str());
uint8_t length = 0;
uint16_t offset = 0;
if (num_args == 4) {
offset = Helpers::hextoint(arguments[2].c_str());
length = Helpers::hextoint(arguments[3].c_str());
} else if (num_args == 3) {
offset = Helpers::hextoint(arguments.back().c_str());
}
EMSESP::send_read_request(type_id, device_id, offset, length, true);
EMSESP::set_read_id(type_id);
return true;
}
// system read command
bool System::command_read(const char * value, const int8_t id) {
return readCommand(value);
}
} // namespace emsesp

View File

@@ -63,6 +63,7 @@ class System {
void loop();
// commands
static bool command_read(const char * value, const int8_t id);
static bool command_send(const char * value, const int8_t id);
static bool command_publish(const char * value, const int8_t id);
static bool command_fetch(const char * value, const int8_t id);
@@ -124,6 +125,8 @@ class System {
static bool is_valid_gpio(uint8_t pin, bool has_psram = false);
static bool load_board_profile(std::vector<int8_t> & data, const std::string & board_profile);
static bool readCommand(const char * data);
static void restart_requested(bool restart_requested) {
restart_requested_ = restart_requested;
}
@@ -170,6 +173,14 @@ class System {
readonly_mode_ = readonly_mode;
}
bool developer_mode() {
return developer_mode_;
}
void developer_mode(bool developer_mode) {
developer_mode_ = developer_mode;
}
// Boolean Format API/MQTT
uint8_t bool_format() {
return bool_format_;
@@ -398,6 +409,7 @@ class System {
uint16_t modbus_port_;
uint8_t modbus_max_clients_;
uint32_t modbus_timeout_;
bool developer_mode_;
// ethernet
uint8_t phy_type_;

View File

@@ -973,16 +973,16 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
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("/rest/deviceEntities");
// EMSESP::webCustomizationService.device_entities(&request);
request.url("/rest/dashboardData");
EMSESP::webDataService.dashboard_data(&request);
// request.url("/rest/dashboardData");
// EMSESP::webDataService.dashboard_data(&request);
// COMMANDS
// shell.invoke_command("call system fetch");
@@ -999,7 +999,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
// EMSESP::webAPIService.webAPIService(&request);
// POST COMMANDS
// request.method(HTTP_POST);
request.method(HTTP_POST);
// char data1[] = "{\"device\":\"system\", \"cmd\":\"restart\",\"id\":-1}";
// deserializeJson(doc, data1);
@@ -1021,6 +1021,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
// request.url("/rest/action");
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
char data6[] = "{\"device\":\"system\", \"cmd\":\"read\",\"value\":\"8 2 27 1\"}";
deserializeJson(doc, data6);
json = doc.as<JsonVariant>();
request.url("/api");
EMSESP::webAPIService.webAPIService(&request, json);
shell.invoke_command("call system read \"8 2 27 1\"");
} else {
EMSESP::webCustomEntityService.test(); // custom entities

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.7.0-dev.46"
#define EMSESP_APP_VERSION "3.7.0-dev.47"

View File

@@ -28,8 +28,9 @@ WebAPIService::WebAPIService(AsyncWebServer * server, SecurityManager * security
server->on(EMSESP_API_SERVICE_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { webAPIService(request, json); });
}
// POST|GET /{device}
// POST|GET /{device}/{entity}
// POST|GET api/
// POST|GET api/{device}
// POST|GET api/{device}/{entity}
void WebAPIService::webAPIService(AsyncWebServerRequest * request, JsonVariant json) {
JsonObject input;
// if no body then treat it as a secure GET

View File

@@ -80,6 +80,7 @@ void WebSettings::read(WebSettings & settings, JsonObject root) {
root["modbus_port"] = settings.modbus_port;
root["modbus_max_clients"] = settings.modbus_max_clients;
root["modbus_timeout"] = settings.modbus_timeout;
root["developer_mode"] = settings.developer_mode;
}
// call on initialization and also when settings are updated via web or console
@@ -358,9 +359,12 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
settings.fahrenheit = root["fahrenheit"];
EMSESP::system_.fahrenheit(settings.fahrenheit);
settings.readonly_mode = root["readonly_mode"];
settings.readonly_mode = root["readonly_mode"] | false;
EMSESP::system_.readonly_mode(settings.readonly_mode);
settings.developer_mode = root["developer_mode"] | false;
EMSESP::system_.developer_mode(settings.developer_mode);
settings.bool_dashboard = root["bool_dashboard"] | EMSESP_DEFAULT_BOOL_FORMAT;
EMSESP::system_.bool_dashboard(settings.bool_dashboard);

View File

@@ -65,10 +65,13 @@ class WebSettings {
uint8_t bool_format;
uint8_t bool_dashboard;
uint8_t enum_format;
int8_t weblog_level;
uint8_t weblog_buffer;
bool weblog_compact;
bool fahrenheit;
int8_t weblog_level;
uint8_t weblog_buffer;
bool weblog_compact;
bool fahrenheit;
bool modbus_enabled;
uint16_t modbus_port;
uint8_t modbus_max_clients;
@@ -79,6 +82,8 @@ class WebSettings {
uint8_t eth_phy_addr;
uint8_t eth_clock_mode;
bool developer_mode; // developer mode
static void read(WebSettings & settings, JsonObject root);
static StateUpdateResult update(JsonObject root, WebSettings & settings);