From ae7737e47bbe79180af4c341ed9f41b5bb75efd5 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Jul 2024 13:23:23 +0200 Subject: [PATCH 1/9] rename HardwareStatus to hardwareStatus --- interface/src/api/system.ts | 4 ++-- src/web/WebStatusService.cpp | 7 ++++--- src/web/WebStatusService.h | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/interface/src/api/system.ts b/interface/src/api/system.ts index 04e65484d..7b5e46c7b 100644 --- a/interface/src/api/system.ts +++ b/interface/src/api/system.ts @@ -7,9 +7,9 @@ import type { HardwareStatus, LogSettings, SystemStatus } from 'types'; import { alovaInstance, alovaInstanceGH } from './endpoints'; -// HardwareStatus - also used to ping in Restart monitor for pinging +// hardwareStatus - also used to ping in Restart monitor for pinging export const readHardwareStatus = () => - alovaInstance.Get('/rest/HardwareStatus'); + alovaInstance.Get('/rest/hardwareStatus'); // SystemStatus export const readSystemStatus = () => diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index d306085a7..dca2642fd 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -24,9 +24,9 @@ namespace emsesp { -// /rest/HardwareStatus +// /rest/hardwareStatus WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) { - server->on(HARDWARE_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { HardwareStatus(request); }); + server->on(HARDWARE_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { hardwareStatus(request); }); server->on(SYSTEM_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { systemStatus(request); }); } @@ -85,7 +85,7 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) { request->send(response); } -void WebStatusService::HardwareStatus(AsyncWebServerRequest * request) { +void WebStatusService::hardwareStatus(AsyncWebServerRequest * request) { EMSESP::system_.refreshHeapMem(); // refresh free heap and max alloc heap auto * response = new AsyncJsonResponse(false); @@ -121,6 +121,7 @@ void WebStatusService::HardwareStatus(AsyncWebServerRequest * request) { root["fs_free"] = EMSESP::system_.FStotal() - FSused; root["free_caps"] = heap_caps_get_free_size(MALLOC_CAP_8BIT) / 1024; // includes heap and psram + root["psram"] = EMSESP::system_.PSram(); if (EMSESP::system_.PSram()) { root["psram_size"] = EMSESP::system_.PSram(); root["free_psram"] = ESP.getFreePsram() / 1024; diff --git a/src/web/WebStatusService.h b/src/web/WebStatusService.h index 4fe30f450..e3fe28083 100644 --- a/src/web/WebStatusService.h +++ b/src/web/WebStatusService.h @@ -1,7 +1,7 @@ #ifndef WebStatusService_h #define WebStatusService_h -#define HARDWARE_STATUS_SERVICE_PATH "/rest/HardwareStatus" +#define HARDWARE_STATUS_SERVICE_PATH "/rest/hardwareStatus" #define SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus" namespace emsesp { @@ -12,7 +12,7 @@ class WebStatusService { private: void systemStatus(AsyncWebServerRequest * request); - void HardwareStatus(AsyncWebServerRequest * request); + void hardwareStatus(AsyncWebServerRequest * request); }; } // namespace emsesp From 3f6157d7a48a33377e5d5bb32850a6a5b7dea52f Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Jul 2024 13:23:47 +0200 Subject: [PATCH 2/9] fetch hardware status on load, so we have the psram setting --- interface/src/app/settings/ApplicationSettings.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/src/app/settings/ApplicationSettings.tsx b/interface/src/app/settings/ApplicationSettings.tsx index b419aa9b7..28ba474ec 100644 --- a/interface/src/app/settings/ApplicationSettings.tsx +++ b/interface/src/app/settings/ApplicationSettings.tsx @@ -50,6 +50,10 @@ export function boardProfileSelectItems() { } const ApplicationSettings: FC = () => { + const { data: hardwareData, error } = useRequest(SystemApi.readHardwareStatus, { + force: true + }); + const { loadData, saveData, @@ -835,7 +839,7 @@ const ApplicationSettings: FC = () => { checked={data.modbus_enabled} onChange={updateFormValue} name="modbus_enabled" - disabled={saving} + disabled={!hardwareData.psram} /> } label={LL.ENABLE_MODBUS()} From e169f27adebc7a8ab2366308a1d3f94f8b0207dd Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Jul 2024 13:24:18 +0200 Subject: [PATCH 3/9] include psram in hardware status --- interface/src/types/system.ts | 1 + mock-api/rest_server.ts | 87 ++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/interface/src/types/system.ts b/interface/src/types/system.ts index b1f2173db..b4a093ca8 100644 --- a/interface/src/types/system.ts +++ b/interface/src/types/system.ts @@ -21,6 +21,7 @@ export interface HardwareStatus { fs_used: number; fs_free: number; free_mem: number; + psram: boolean; psram_size?: number; free_psram?: number; has_loader: boolean; diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index 8ff3bba1c..85478d33b 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -336,7 +336,7 @@ const SYSTEM_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'systemStatus'; const ACTIVITY_ENDPOINT = REST_ENDPOINT_ROOT + 'activity'; // SETTINGS -const HARDWARE_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'HardwareStatus'; +const HARDWARE_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'hardwareStatus'; const SECURITY_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'securitySettings'; const RESTART_ENDPOINT = REST_ENDPOINT_ROOT + 'restart'; const RESTART_PARTITION_ENDPOINT = REST_ENDPOINT_ROOT + 'partition'; @@ -366,6 +366,8 @@ const hardware_status = { fs_used: 24, fs_free: 2024, free_mem: 100, + psram: true, + // psram: false, psram_size: 4093, free_psram: 4074, has_loader: true, @@ -604,42 +606,53 @@ const emsesp_allvalues = { }; let settings = { - locale: 'en', - tx_mode: 4, - ems_bus_id: 11, - syslog_enabled: false, - syslog_level: 3, - trace_raw: false, - syslog_mark_interval: 0, - syslog_host: '192.168.1.4', - syslog_port: 514, - shower_timer: true, - shower_alert: true, - shower_alert_trigger: 7, - shower_alert_coldshot: 10, - shower_min_duration: 120, - rx_gpio: 23, - tx_gpio: 5, - phy_type: 0, - eth_power: 0, - eth_phy_addr: 0, - eth_clock_mode: 0, - dallas_gpio: 3, - dallas_parasite: false, - led_gpio: 2, - hide_led: false, - notoken_api: false, - readonly_mode: false, - low_clock: false, - boiler_heatingoff: false, - telnet_enabled: true, - analog_enabled: false, - pbutton_gpio: 0, - board_profile: 'S32', - bool_format: 1, - bool_dashboard: 1, - enum_format: 1, - fahrenheit: false + "locale": "en", + "tx_mode": 1, + "ems_bus_id": 11, + "syslog_enabled": false, + "syslog_level": 3, + "trace_raw": false, + "syslog_mark_interval": 0, + "syslog_host": "192.168.1.8", + "syslog_port": 514, + "boiler_heatingoff": false, + "remote_timeout": 24, + "remote_timeout_en": false, + "shower_timer": true, + "shower_alert": false, + "shower_alert_coldshot": 10, + "shower_alert_trigger": 7, + "shower_min_duration": 180, + "rx_gpio": 4, + "tx_gpio": 5, + "dallas_gpio": 14, + "dallas_parasite": false, + "led_gpio": 2, + "hide_led": true, + "low_clock": false, + "telnet_enabled": true, + "notoken_api": false, + "readonly_mode": false, + "analog_enabled": true, + "pbutton_gpio": 34, + "solar_maxflow": 30, + "board_profile": "E32V2", + "fahrenheit": false, + "bool_format": 1, + "bool_dashboard": 1, + "enum_format": 1, + "weblog_level": 6, + "weblog_buffer": 50, + "weblog_compact": true, + "phy_type": 1, + "eth_power": 15, + "eth_phy_addr": 0, + "eth_clock_mode": 1, + "platform": "ESP32R", + "modbus_enabled": false, + "modbus_port": 502, + "modbus_max_clients": 10, + "modbus_timeout": 10000 }; const emsesp_devices = { From c947889e5340f386e50ce6d99b13ec82ba4a4699 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Jul 2024 13:24:28 +0200 Subject: [PATCH 4/9] add test for mqtt via API --- src/test/test.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/test.cpp b/src/test/test.cpp index 2c5e4ed73..5cf7bf92c 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -1172,7 +1172,9 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const test("boiler"); test("thermostat"); - EMSESP::mqtt_.incoming("ems-esp/boiler/wwseltemp", "59"); + EMSESP::mqtt_.incoming("ems-esp/boiler/seltemp", "59"); + EMSESP::mqtt_.incoming("badems-esp/boiler/seltemp", "59"); // should fail + ok = true; } From b3532bd3728acbe38b2c17c7e5432bd737dbf34d Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Jul 2024 13:24:40 +0200 Subject: [PATCH 5/9] remove version from payload --- src/web/WebSettingsService.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 054947c61..e3fbd997e 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -32,7 +32,6 @@ WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, Securit } void WebSettings::read(WebSettings & settings, JsonObject root) { - root["version"] = settings.version; root["locale"] = settings.locale; root["tx_mode"] = settings.tx_mode; root["ems_bus_id"] = settings.ems_bus_id; From 51783ab7a18adca7f457194d2db5960813f80119 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Jul 2024 13:25:02 +0200 Subject: [PATCH 6/9] tidy up how paths are checked for API and MQTT --- src/command.cpp | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index b0ed8aa33..7cc3e0574 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -26,7 +26,7 @@ uuid::log::Logger Command::logger_{F_(command), uuid::log::Facility::DAEMON}; std::vector Command::cmdfunctions_; -// takes a path and a json body, parses the data and calls the command +// takes a URI path and a json body, parses the data and calls the command // the path is leading so if duplicate keys are in the input JSON it will be ignored // the entry point will be either via the Web API (api/) or MQTT (/) // returns a return code and json output @@ -34,22 +34,11 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec SUrlParser p; // parse URL for the path names p.parse(path); - if (!p.paths().size()) { - return json_message(CommandRet::ERROR, "invalid path", output); - } - - // check first if it's from API, if so strip the "api/" - if (p.paths().front() == "api") { + // check first if it's from API or MQTT, if so strip the "api/" or "/" from the path + if (p.paths().size() && ((p.paths().front() == "api") || (p.paths().front() == Mqtt::base()))) { p.paths().erase(p.paths().begin()); } else { - // not /api, so must be MQTT path. Check for base and remove it. - if (!strncmp(path, Mqtt::base().c_str(), Mqtt::base().length())) { - char new_path[Mqtt::MQTT_TOPIC_MAX_SIZE]; - strlcpy(new_path, path, sizeof(new_path)); - p.parse(new_path + Mqtt::base().length() + 1); // re-parse the stripped path - } else { - return json_message(CommandRet::ERROR, "unrecognized path", output); // error - } + return json_message(CommandRet::ERROR, "invalid path", output, path); // error } // re-calculate new path @@ -697,15 +686,21 @@ void Command::show_all(uuid::console::Shell & shell) { shell.println(); } -uint8_t Command::json_message(uint8_t error_code, const char * message, const JsonObject output) { +// creates a single json document with an error message +// object is optional +uint8_t Command::json_message(uint8_t error_code, const char * message, const JsonObject output, const char * object) { output.clear(); - output["message"] = message; + if (object) { + output["message"] = std::string(message) + " " + object; + } else { + output["message"] = message; + } return error_code; } -// -// SUrlParser class -// +// ************************** +// **** SUrlParser class **** +// ************************** // Extract only the path component from the passed URI and normalized it // e.g. //one/two////three/// becomes /one/two/three From 78a0fc2091d5bbf128ae367a1e9941fe72b3b9ff Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Jul 2024 13:25:19 +0200 Subject: [PATCH 7/9] add optional object to be included in error message --- src/command.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command.h b/src/command.h index 564d43b21..38a54b405 100644 --- a/src/command.h +++ b/src/command.h @@ -143,7 +143,7 @@ class Command { static std::vector cmdfunctions_; // the list of commands - static uint8_t json_message(uint8_t error_code, const char * message, const JsonObject output); + static uint8_t json_message(uint8_t error_code, const char * message, JsonObject output, const char * object = nullptr); }; class SUrlParser { From 7a3300b8f8a9c2774ab704ca14355ad647ba1635 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Jul 2024 13:25:30 +0200 Subject: [PATCH 8/9] rename console "Command executed" --- src/console.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.cpp b/src/console.cpp index 53eb61691..25dea0dd0 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -575,7 +575,7 @@ static void setup_commands(std::shared_ptr & commands) { return; } else { // show message if no data returned (e.g. for analogsensor, temperaturesensor, custom) - shell.println("Command executed. Check log for messages."); + shell.println("Command executed"); return; } } else if (return_code == CommandRet::NOT_FOUND) { From 65a5eeee6935d983125215295b95b02182536894 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Jul 2024 13:25:44 +0200 Subject: [PATCH 9/9] debug text changes --- src/modbus.cpp | 2 +- src/mqtt.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modbus.cpp b/src/modbus.cpp index fafd54958..aeaaf5da3 100644 --- a/src/modbus.cpp +++ b/src/modbus.cpp @@ -438,7 +438,7 @@ ModbusMessage Modbus::handleWrite(const ModbusMessage & request) { if (output.size()) { snprintf(error, sizeof(error), - "Modbus write command failed with error: %s (%s)", + "Modbus write command failed with error %s (%s)", (const char *)output["message"], Command::return_code_string(return_code)); } else { diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 2833c1a16..c161b3e49 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -228,9 +228,9 @@ void Mqtt::on_message(const char * topic, const uint8_t * payload, size_t len) { #if defined(EMSESP_DEBUG) if (len) { - LOG_DEBUG("Received topic `%s` => payload `%s` (length %d)", topic, message, len); + LOG_DEBUG("Received topic %s => payload '%s' (length %d)", topic, message, len); } else { - LOG_DEBUG("Received topic `%s`", topic); + LOG_DEBUG("Received topic %s", topic); } #endif // remove HA topics if we don't use discovery