From 94e407208ecd254706dacee1d983a6685334966e Mon Sep 17 00:00:00 2001 From: Marcel Peterkau Date: Thu, 11 Jan 2024 22:06:32 +0100 Subject: [PATCH] most settings working via Websocket --- Software/data_src/index.htm | 126 ++++------ Software/data_src/static/js/websocket.js | 13 +- Software/include/common.h | 4 + Software/src/webui.cpp | 280 +++++++++++++---------- 4 files changed, 208 insertions(+), 215 deletions(-) diff --git a/Software/data_src/index.htm b/Software/data_src/index.htm index b751fef..f4d9d20 100644 --- a/Software/data_src/index.htm +++ b/Software/data_src/index.htm @@ -102,37 +102,33 @@

Ölvorrat

-
- %TANK_REMAIN_CAPACITY%% + style="width: 0%">0%
- +
-


Entlüftung

-
- +
Pulse
@@ -141,11 +137,9 @@
- - +
-

@@ -153,13 +147,11 @@

Einmessen

-
- +
Pulse
@@ -168,11 +160,10 @@
- - + +
-

@@ -185,8 +176,8 @@
- - + +

@@ -197,7 +188,7 @@

Gerät neustarten

- +

@@ -212,11 +203,10 @@

Signalquelle

-
- +
- @@ -233,24 +223,21 @@
- +
-

-
+

Einstellungen Impulseingang

-
-
- +
mm
@@ -262,7 +249,7 @@
- +
mm
@@ -273,7 +260,7 @@
- +
"
@@ -284,63 +271,48 @@
- +
-
-
- -
-
-

-
+

Einstellungen CAN-Bus

-
-
-
-
- -
-
-

-
+

Einstellungen GPS

-
-
- +
-

@@ -348,13 +320,12 @@

Dosierung

-
- +
m
@@ -365,32 +336,25 @@
- +
m
-
-
- -
-
-


Öltank

-
-
ml @@ -402,7 +366,7 @@
-
% @@ -414,7 +378,7 @@
-
µl @@ -422,24 +386,17 @@
-
-
- -
-
-


LED Einstellungen

-
- + @@ -450,8 +407,7 @@
- +
@@ -459,19 +415,21 @@
- +
-
-
- -
-
-

+ +
+

+

+
+ +
+
+

diff --git a/Software/data_src/static/js/websocket.js b/Software/data_src/static/js/websocket.js index 8bf2ec6..e1e8bd8 100644 --- a/Software/data_src/static/js/websocket.js +++ b/Software/data_src/static/js/websocket.js @@ -15,12 +15,11 @@ function initWebSocket() { } function initButtons() { - var elements = document.getElementsByClassName("btn-wsevent"); if (elements.length > 0) { for (var i = 0; i < elements.length; i++) { - var element = elements[i]; + let element = elements[i]; element.addEventListener("click", function () { websocket_sendevent("btn-" + element.id, 0); }); @@ -29,12 +28,11 @@ function initButtons() { } function initSettingInputs() { - - var elements = document.getElementsByClassName("btn-wssetting"); + var elements = document.getElementsByClassName("set-wsevent"); if (elements.length > 0) { for (var i = 0; i < elements.length; i++) { - var element = elements[i]; + let element = elements[i]; element.addEventListener("change", function () { websocket_sendevent("set-" + element.id, element.value); }); @@ -173,9 +171,10 @@ function fillValuesToHTML(dataset) { } else if (element.classList.contains("progress-bar")) { // Wenn das Element eine Fortschrittsleiste ist updateProgressBar(element, dataset[key]); - } else if (element.classList.contains("removeable")) { + } else if (element.classList.contains("hideable")) { // Wenn das Element ein Settingsabschnitt-div ist - if (dataset[key] == 0) element.remove(); + if (dataset[key] == 0) element.style.display = "none"; + else element.style.display = ""; } else { // Standardmäßig für Textfelder und andere Elemente element.value = dataset[key]; diff --git a/Software/include/common.h b/Software/include/common.h index f609d2c..a02c186 100644 --- a/Software/include/common.h +++ b/Software/include/common.h @@ -94,7 +94,11 @@ extern const size_t SpeedSourceString_Elements; // Enum for GPS baud rates typedef enum GPSBaudRate_e { + BAUD_4800, BAUD_9600, + BAUD_19200, + BAUD_38400, + BAUD_57600, BAUD_115200 } GPSBaudRate_t; diff --git a/Software/src/webui.cpp b/Software/src/webui.cpp index e93182a..f3b6c46 100644 --- a/Software/src/webui.cpp +++ b/Software/src/webui.cpp @@ -17,8 +17,9 @@ AsyncWebServer webServer(80); const char *PARAM_MESSAGE = "message"; +SpeedSource_t speedsourcePreselect; /**< Preselect Memory for change SourceAdress */ + String processor(const String &var); -void WebserverPOST_Callback(AsyncWebServerRequest *request); void WebserverNotFound_Callback(AsyncWebServerRequest *request); void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final); void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final); @@ -34,6 +35,8 @@ void Websocket_RefreshClientData_Status(uint32_t client_id, bool send_mapping = void Websocket_RefreshClientData_Static(uint32_t client_id, bool send_mapping = false); void Websocket_HandleButtons(uint8_t *data); void Websocket_HandleSettings(uint8_t *data); +void parseWebsocketString(char *data, char *identifierBuffer, size_t identifierBufferSize, char *valueBuffer, size_t valueBufferSize); +int findIndexByString(const char *searchString, const char *const *array, int arraySize); /** * @brief Initializes the web-based user interface (WebUI) for the ChainLube application. @@ -115,119 +118,6 @@ void Webserver_Process() } } -void WebserverPOST_Callback(AsyncWebServerRequest *request) -{ - request->send(LittleFS, "/post.htm", "text/html", false, processor); - - Debug_pushMessage("POST:\n"); - int paramsNr = request->params(); - for (int i = 0; i < paramsNr; i++) - { - AsyncWebParameter *p = request->getParam(i); - Debug_pushMessage("%s : %s\n", p->name().c_str(), p->value().c_str()); - - // begin: POST Form Source Changed - if (p->name() == "sourceselect") - { - SpeedSource_t temp = (SpeedSource_t)p->value().toInt(); - Debug_pushMessage("temp: %d", temp); - Debug_pushMessage("SpeedSource: %d", LubeConfig.SpeedSource); - if (LubeConfig.SpeedSource != temp) - { - LubeConfig.SpeedSource = temp; - globals.systemStatus = sysStat_Shutdown; - } - } - // end: POST Form Source Changed - // begin: POST Form Source Pulse Settings - if (p->name() == "tirewidth") - LubeConfig.TireWidth_mm = p->value().toInt(); - if (p->name() == "tireratio") - LubeConfig.TireWidthHeight_Ratio = p->value().toInt(); - if (p->name() == "tiredia") - LubeConfig.RimDiameter_Inch = p->value().toInt(); - if (p->name() == "pulserev") - LubeConfig.PulsePerRevolution = p->value().toInt(); - if (p->name() == "pulsesave") - globals.requestEEAction = EE_CFG_SAVE; - // end: POST Form Source Pulse Settings - // begin: POST Form Source GPS Settings - if (p->name() == "gpsbaud") - LubeConfig.GPSBaudRate = (GPSBaudRate_t)p->value().toInt(); - if (p->name() == "gpssave") - globals.requestEEAction = EE_CFG_SAVE; - // end: POST Form Source GPS Settings - // begin: POST Form Source CAN Settings - if (p->name() == "cansource") - LubeConfig.CANSource = (CANSource_t)p->value().toInt(); - if (p->name() == "cansave") - globals.requestEEAction = EE_CFG_SAVE; - // end: POST Form Source CAN Settings - // begin: POST Form Lubrication - if (p->name() == "lubedistancenormal") - LubeConfig.DistancePerLube_Default = p->value().toInt(); - if (p->name() == "lubedistancerain") - LubeConfig.DistancePerLube_Rain = p->value().toInt(); - if (p->name() == "lubesave") - globals.requestEEAction = EE_CFG_SAVE; - // end: POST Form Lubrication - // begin: POST Form Oiltank - if (p->name() == "tankcap") - LubeConfig.tankCapacity_ml = p->value().toInt(); - if (p->name() == "tankwarn") - LubeConfig.TankRemindAtPercentage = p->value().toInt(); - if (p->name() == "pumppulse") - LubeConfig.amountPerDose_microL = p->value().toInt(); - if (p->name() == "oilsave") - globals.requestEEAction = EE_CFG_SAVE; - // end: POST Form Oiltank - // begin: POST Form Maintenance - if (p->name() == "maintsave") - globals.requestEEAction = EE_CFG_SAVE; - if (p->name() == "resettank") - { - PersistenceData.tankRemain_microL = LubeConfig.tankCapacity_ml * 1000; - globals.requestEEAction = EE_PDS_SAVE; - } - if (p->name() == "reset_ee_btn") - { - if (request->hasParam("reset_ee_pds", true)) - { - AsyncWebParameter *param = request->getParam("reset_ee_pds", true); - if (param->value() == "on") - globals.requestEEAction = globals.requestEEAction == EE_CFG_FORMAT ? EE_FORMAT_ALL : EE_PDS_FORMAT; - } - if (request->hasParam("reset_ee_cfg", true)) - { - AsyncWebParameter *param = request->getParam("reset_ee_cfg", true); - if (param->value() == "on") - globals.requestEEAction = globals.requestEEAction == EE_PDS_FORMAT ? EE_FORMAT_ALL : EE_CFG_FORMAT; - } - } - // end: POST Form Maintenance - // begin: POST Form LED Settings - if (p->name() == "ledmaxbrightness") - LubeConfig.LED_Max_Brightness = p->value().toInt(); - if (p->name() == "ledminbrightness") - LubeConfig.LED_Min_Brightness = p->value().toInt(); - if (p->name() == "ledsave") - { - if (request->hasParam("ledmodeflash", true)) - { - AsyncWebParameter *param = request->getParam("ledmodeflash", true); - if (param->value() == "on") - LubeConfig.LED_Mode_Flash = true; - } - else - { - LubeConfig.LED_Mode_Flash = false; - } - globals.requestEEAction = EE_CFG_SAVE; - } - // end: POST Form LED SEttings - } -} - /** * @brief Callback function for handling HTTP 404 (Not Found) errors on the web server. * @@ -514,12 +404,13 @@ void Websocket_HandleMessage(void *arg, uint8_t *data, size_t len) if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) { data[len] = 0; + Debug_pushMessage("Websocket-Message (len: %d): %s\n", len, (char *)data); if (strncmp((char *)data, "btn-", strlen("btn-")) == 0) { Websocket_HandleButtons(data + strlen("btn-")); } - if (strncmp((char *)data, "set-", strlen("set-")) == 0) + else if (strncmp((char *)data, "set-", strlen("set-")) == 0) { Websocket_HandleSettings(data + strlen("set-")); } @@ -530,42 +421,101 @@ void Websocket_HandleMessage(void *arg, uint8_t *data, size_t len) } } +/** + * @brief Handle button commands received via WebSocket. + * + * This function parses a WebSocket string representing button commands, extracts + * the identifier and value components, and performs corresponding actions based on + * the received commands. + * + * @param data The WebSocket data containing button commands. + */ void Websocket_HandleButtons(uint8_t *data) { - if (strcmp((char *)data, "debugstart") == 0) + char identifier[32]; + char value[32]; + + parseWebsocketString((char *)data, identifier, sizeof(identifier), value, sizeof(value)); + + if (strcmp(identifier, "debugstart") == 0) { SetDebugportStatus(dbg_Webui, enabled); } - else if (strcmp((char *)data, "debugstop") == 0) + else if (strcmp(identifier, "debugstop") == 0) { SetDebugportStatus(dbg_Webui, disabled); } - else if (strcmp((char *)data, "measurereset") == 0) + else if (strcmp(identifier, "measurereset") == 0) { globals.measuredPulses = 0; } - else if (strcmp((char *)data, "measurestartstop") == 0) + else if (strcmp(identifier, "measurestartstop") == 0) { globals.measurementActive = !globals.measurementActive; } - else if (strcmp((char *)data, "purgenow") == 0) + else if (strcmp(identifier, "purgenow") == 0) { globals.systemStatus = sysStat_Purge; globals.purgePulses = LubeConfig.BleedingPulses; } - else if (strcmp((char *)data, "reboot") == 0) + else if (strcmp(identifier, "sourcesave") == 0) + { + LubeConfig.SpeedSource = speedsourcePreselect; + globals.requestEEAction = EE_CFG_SAVE; + globals.systemStatus = sysStat_Shutdown; + } + else if (strcmp(identifier, "settingssave") == 0) + { + globals.requestEEAction = EE_CFG_SAVE; + } + else if (strcmp(identifier, "reboot") == 0) { globals.systemStatus = sysStat_Shutdown; } else { - Debug_pushMessage("Got unknown Button-id '%s' from ws-client\n", (char *)data); + Debug_pushMessage("Got unknown Button-id '%s' from ws-client\n", identifier); } } +/** + * @brief Handle settings commands received via WebSocket. + * + * This function parses a WebSocket string representing settings commands, extracts + * the identifier and value components, and updates the system settings accordingly. + * + * @param data The WebSocket data containing settings commands. + */ void Websocket_HandleSettings(uint8_t *data) { - Debug_pushMessage("Got Settings-id and value '%s' from ws-client\n", (char *)data); + char identifier[32]; + char value[32]; + + parseWebsocketString((char *)data, identifier, sizeof(identifier), value, sizeof(value)); + + if (strcmp(identifier, "bleedingpulses") == 0) + { + LubeConfig.BleedingPulses = atoi(value); + } + else if (strcmp(identifier, "speedsource") == 0) + { + int index = findIndexByString(value, SpeedSourceString, SpeedSourceString_Elements); + speedsourcePreselect = (SpeedSource_t)index; + } + else if (strcmp(identifier, "cansource") == 0) + { + int index = findIndexByString(value, CANSourceString, CANSourceString_Elements); + LubeConfig.CANSource = (CANSource_t)index; + } + else if (strcmp(identifier, "gpsbaud") == 0) + { + int index = findIndexByString(value, GPSBaudRateString, GPSBaudRateString_Elements); + LubeConfig.GPSBaudRate = (GPSBaudRate_t)index; + } + else + { + Debug_pushMessage("Got unknown Settings-id and value '%s' from ws-client\n", identifier); + } } /** @@ -689,7 +639,7 @@ void Websocket_RefreshClientData_Static(uint32_t client_id, bool send_mapping) "tirewidth;" "tireratio;" "tiredia;" - "sourceselect;" + "speedsource;" "gpsbaud;" "cansource;" "ledmodeflash;" @@ -742,4 +692,86 @@ void Websocket_RefreshClientData_Static(uint32_t client_id, bool send_mapping) { webSocket.textAll(temp); } +} + +/** + * @brief Parse a WebSocket string into identifier and value components. + * + * This function takes a WebSocket string, separates it into identifier and value + * components using the ":" delimiter, and stores them in the specified buffers. + * If no ":" is found, the entire string is considered as the value, and the + * identifier buffer is set to an empty string. + * + * @param data The WebSocket string to parse. + * @param identifierBuffer The buffer to store the identifier component. + * @param identifierBufferSize The size of the identifier buffer. + * @param valueBuffer The buffer to store the value component. + * @param valueBufferSize The size of the value buffer. + */ +void parseWebsocketString(char *data, char *identifierBuffer, size_t identifierBufferSize, + char *valueBuffer, size_t valueBufferSize) +{ + // Zerlegen des Strings anhand des Trennzeichens ":" + char *token = strtok(data, ":"); + + // Falls der erste Teil des Strings vorhanden ist + if (token != NULL) + { + // Kopieren des ersten Teils in den Buffer für Identifier + strncpy(identifierBuffer, token, identifierBufferSize - 1); + identifierBuffer[identifierBufferSize - 1] = '\0'; // Null-Terminierung sicherstellen + + // Weitere Aufrufe von strtok, um den nächsten Teil zu erhalten + token = strtok(NULL, ":"); + + // Falls der zweite Teil des Strings vorhanden ist + if (token != NULL) + { + // Kopieren des zweiten Teils in den Buffer für Value + strncpy(valueBuffer, token, valueBufferSize - 1); + valueBuffer[valueBufferSize - 1] = '\0'; // Null-Terminierung sicherstellen + } + else + { + // Kein zweiter Teil vorhanden, setzen Sie den Buffer für Value auf leer + valueBuffer[0] = '\0'; + } + } + else + { + // Der erste Teil des Strings fehlt, setzen Sie den Buffer für Identifier auf leer + identifierBuffer[0] = '\0'; + + // Der gesamte String wird als Value betrachtet + strncpy(valueBuffer, data, valueBufferSize - 1); + valueBuffer[valueBufferSize - 1] = '\0'; // Null-Terminierung sicherstellen + } +} + +/** + * @brief Find the index of a string in an array. + * + * This function searches for the given string in the provided array and returns + * the index of the first occurrence. If the string is not found, it returns -1. + * + * @param searchString The string to search for in the array. + * @param array The array of strings to search within. + * @param arraySize The size of the array. + * + * @return The index of the first occurrence of the string in the array, + * or -1 if the string is not found. + */ +int findIndexByString(const char *searchString, const char *const *array, int arraySize) +{ + // Durchlaufe das Array und vergleiche jeden String + for (int i = 0; i < arraySize; ++i) + { + if (strcmp(array[i], searchString) == 0) + { + // String gefunden, gib den Index zurück + return i; + } + } + // String nicht gefunden, gib -1 zurück + return -1; } \ No newline at end of file