-
+
Pulse
diff --git a/Software/data_src/static/js/websocket.js b/Software/data_src/static/js/websocket.js
index 8c9147b..1efe75f 100644
--- a/Software/data_src/static/js/websocket.js
+++ b/Software/data_src/static/js/websocket.js
@@ -1,6 +1,9 @@
var gateway = `ws://${window.location.hostname}/ws`;
var websocket;
+var statusMapping;
+var staticMapping;
+
window.addEventListener("load", onLoad);
function initWebSocket() {
@@ -31,25 +34,79 @@ function onClose(event) {
function onMessage(event) {
var data = event.data;
+ console.log("ws_msg:" + event.data + "\n");
+
if (data.startsWith("DEBUG:")) {
var addtext = data.slice(6);
var livedebug_out = document.getElementById("livedebug-out");
livedebug_out.value += addtext;
livedebug_out.scrollTop = livedebug_out.scrollHeight;
do_resize(livedebug_out);
+ return;
}
+
if (data.startsWith("DTC:")) {
const dtcs = data.slice(4);
const dtcArray = dtcs.trim() !== "" ? dtcs.split(";").filter(Boolean) : [];
- if(dtcArray[0] != "0")
- {
+ if (dtcArray[0] != "0") {
processDTCNotifications(dtcArray);
fillDTCTable(dtcArray);
}
- console.log(dtcArray + "\n");
+ return;
}
- console.log("ws_msg:" + event.data + "\n");
+
+ if (data.startsWith("MAPPING_STATUS:")) {
+ const data_sliced = data.slice(15);
+ statusMapping = createMapping(data_sliced);
+ }
+
+ if (data.startsWith("MAPPING_STATIC:")) {
+ const data_sliced = data.slice(15);
+ staticMapping = createMapping(data_sliced);
+ }
+
+ if (data.startsWith("STATUS:")) {
+ const data_sliced = data.slice(7);
+ const result = processDataString(data_sliced, statusMapping);
+ console.log("STATUS:");
+ console.log(JSON.stringify(result, null, 2));
+ fillValuestoHTML(result);
+ return;
+ }
+
+ if (data.startsWith("STATIC:")) {
+ const data_sliced = data.slice(7);
+ const result = processDataString(data_sliced, staticMapping);
+ console.log("STATIC:");
+ console.log(JSON.stringify(result, null, 2));
+ fillValuestoHTML(result);
+ return;
+ }
+}
+
+function createMapping(mappingString) {
+ const mappingArray = mappingString.split(";");
+ const mapping = [];
+
+ mappingArray.forEach((variable) => {
+ if (variable !== null) mapping.push(variable.trim());
+ });
+ return mapping;
+}
+
+function processDataString(dataString, mapping) {
+ const valuesArray = dataString.split(";");
+ const dataObject = {};
+
+ valuesArray.forEach((value, index) => {
+ const variable = mapping[index];
+ if (variable) {
+ dataObject[variable] = value.trim();
+ }
+ });
+
+ return dataObject;
}
function onLoad(event) {
@@ -82,4 +139,11 @@ function do_resize(textbox) {
else textbox.rows = rows;
}
-
+function fillValuestoHTML(dataset) {
+ for (var key in dataset) {
+ var inputElement = document.getElementById(key);
+ if (inputElement) {
+ inputElement.value = dataset[key];
+ }
+ }
+}
diff --git a/Software/src/webui.cpp b/Software/src/webui.cpp
index 71f8f23..5d4068f 100644
--- a/Software/src/webui.cpp
+++ b/Software/src/webui.cpp
@@ -13,15 +13,13 @@ void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &f
void WebServerEEJSON_Callback(AsyncWebServerRequest *request);
void GetFlashVersion(char *buff, size_t buff_size);
-#ifdef FEATURE_ENABLE_WEBSOCKETS
-
AsyncWebSocket webSocket("/ws");
void WebsocketEvent_Callback(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len);
void Websocket_HandleMessage(void *arg, uint8_t *data, size_t len);
-void Websocket_RefreshClientData_DTCs();
-
-#endif
+void Websocket_RefreshClientData_DTCs(uint32_t client_id);
+void Websocket_RefreshClientData_Status(uint32_t client_id, bool send_mapping = false);
+void Websocket_RefreshClientData_Static(uint32_t client_id, bool send_mapping = false);
void initWebUI()
{
@@ -44,10 +42,8 @@ void initWebUI()
MDNS.begin(globals.DeviceName);
MDNS.addService("http", "tcp", 80);
-#ifdef FEATURE_ENABLE_WEBSOCKETS
webSocket.onEvent(WebsocketEvent_Callback);
webServer.addHandler(&webSocket);
-#endif
webServer.serveStatic("/static/", LittleFS, "/static/").setCacheControl("max-age=360000");
webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
@@ -66,17 +62,16 @@ void initWebUI()
void Webserver_Process()
{
-#ifdef FEATURE_ENABLE_WEBSOCKETS
static uint32_t previousMillis = 0;
webSocket.cleanupClients();
if ((webSocket.count() > 0) && (millis() - previousMillis >= 10000))
{
- Websocket_RefreshClientData_DTCs();
+ Websocket_RefreshClientData_DTCs(0);
+ Websocket_RefreshClientData_Status(0);
previousMillis = millis();
}
-#endif
}
String processor(const String &var)
@@ -110,17 +105,9 @@ String processor(const String &var)
if (var == "SPEED_SOURCE")
return String(SpeedSourceString[LubeConfig.SpeedSource]);
if (var == "GPS_BAUD")
-#ifdef FEATURE_ENABLE_GPS
return String(GPSBaudRateString[LubeConfig.GPSBaudRate]);
-#else
- return "Feature N/A";
-#endif
if (var == "CAN_SOURCE")
-#ifdef FEATURE_ENABLE_CAN
return String(CANSourceString[LubeConfig.CANSource]);
-#else
- return "Feature N/A";
-#endif
if (var == "LED_MODE_FLASH")
return String(LubeConfig.LED_Mode_Flash);
if (var == "LEDFLASHCHECKED")
@@ -158,17 +145,9 @@ String processor(const String &var)
if (var == "SHOW_IMPULSE_SETTINGS")
return LubeConfig.SpeedSource == SOURCE_IMPULSE ? "" : "hidden";
if (var == "SHOW_CAN_SETTINGS")
-#ifdef FEATURE_ENABLE_CAN
return LubeConfig.SpeedSource == SOURCE_CAN ? "" : "hidden";
-#else
- return "hidden";
-#endif
if (var == "SHOW_GPS_SETTINGS")
-#ifdef FEATURE_ENABLE_GPS
return LubeConfig.SpeedSource == SOURCE_GPS ? "" : "hidden";
-#else
- return "hidden";
-#endif
if (var == "SOURCE_SELECT_OPTIONS")
{
@@ -181,7 +160,6 @@ String processor(const String &var)
return temp;
}
-#ifdef FEATURE_ENABLE_CAN
if (var == "CANSOURCE_SELECT_OPTIONS")
{
String temp;
@@ -192,8 +170,7 @@ String processor(const String &var)
}
return temp;
}
-#endif
-#ifdef FEATURE_ENABLE_GPS
+
if (var == "GPSBAUD_SELECT_OPTIONS")
{
String temp;
@@ -204,7 +181,6 @@ String processor(const String &var)
}
return temp;
}
-#endif
if (var == "SYSTEM_STATUS")
return String(globals.systemStatustxt);
@@ -274,23 +250,19 @@ void WebserverPOST_Callback(AsyncWebServerRequest *request)
LubeConfig.PulsePerRevolution = p->value().toInt();
if (p->name() == "pulsesave")
globals.requestEEAction = EE_CFG_SAVE;
- // end: POST Form Source Pulse Settings
-#ifdef FEATURE_ENABLE_GPS
+ // 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
-#endif
-#ifdef FEATURE_ENABLE_CAN
+ // 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
-#endif
+ // end: POST Form Source CAN Settings
// begin: POST Form Lubrication
if (p->name() == "lubedistancenormal")
LubeConfig.DistancePerLube_Default = p->value().toInt();
@@ -489,12 +461,8 @@ void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &f
LubeConfig.DistancePerRevolution_mm = doc["config"]["DistancePerRevolution_mm"].as
();
LubeConfig.BleedingPulses = doc["config"]["BleedingPulses"].as();
LubeConfig.SpeedSource = (SpeedSource_t)doc["config"]["SpeedSource"].as();
-#ifdef FEATURE_ENABLE_GPS
LubeConfig.GPSBaudRate = (GPSBaudRate_t)doc["config"]["GPSBaudRate"].as();
-#endif
-#ifdef FEATURE_ENABLE_CAN
LubeConfig.CANSource = (CANSource_t)doc["config"]["CANSource"].as();
-#endif
LubeConfig.LED_Mode_Flash = doc["config"]["LED_Mode_Flash"].as();
LubeConfig.LED_Max_Brightness = doc["config"]["LED_Max_Brightness"].as();
LubeConfig.LED_Min_Brightness = doc["config"]["LED_Min_Brightness"].as();
@@ -522,9 +490,6 @@ void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &f
Debug_pushMessage("Update complete");
globals.systemStatus = sysStat_Shutdown;
}
- else
- {
- }
}
}
@@ -559,14 +524,10 @@ void WebServerEEJSON_Callback(AsyncWebServerRequest *request)
config["BleedingPulses"] = LubeConfig.BleedingPulses;
config["SpeedSource"] = LubeConfig.SpeedSource;
config["SpeedSource_Str"] = SpeedSourceString[LubeConfig.SpeedSource];
-#ifdef FEATURE_ENABLE_GPS
config["GPSBaudRate"] = LubeConfig.GPSBaudRate;
config["GPSBaudRate_Str"] = GPSBaudRateString[LubeConfig.GPSBaudRate];
-#endif
-#ifdef FEATURE_ENABLE_CAN
config["CANSource"] = LubeConfig.CANSource;
config["CANSource_Str"] = CANSourceString[LubeConfig.CANSource];
-#endif
config["LED_Mode_Flash"] = LubeConfig.LED_Mode_Flash;
config["LED_Max_Brightness"] = LubeConfig.LED_Max_Brightness;
config["LED_Min_Brightness"] = LubeConfig.LED_Min_Brightness;
@@ -595,13 +556,15 @@ void WebServerEEJSON_Callback(AsyncWebServerRequest *request)
request->send(response);
}
-#ifdef FEATURE_ENABLE_WEBSOCKETS
void WebsocketEvent_Callback(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len)
{
switch (type)
{
case WS_EVT_CONNECT:
Debug_pushMessage("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
+ Websocket_RefreshClientData_Status(client->id(), true);
+ Websocket_RefreshClientData_Static(client->id(), true);
+ Websocket_RefreshClientData_DTCs(client->id());
break;
case WS_EVT_DISCONNECT:
Debug_pushMessage("WebSocket client #%u disconnected\n", client->id());
@@ -644,30 +607,151 @@ void Websocket_PushLiveDebug(String Message)
webSocket.textAll("DEBUG:" + Message);
}
-void Websocket_RefreshClientData_DTCs()
+void Websocket_RefreshClientData_DTCs(uint32_t client_id)
{
- String temp = "";
+ String temp = "DTC:";
// Build DTC-String
if (globals.hasDTC != true)
{
- temp = "DTC:" + String(DTC_NO_DTC) + ";";
+ temp.concat(String(DTC_NO_DTC) + ";");
}
else
{
- temp = "DTC:";
for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++)
{
if (DTCStorage[i].Number < DTC_LAST_DTC)
{
- temp = temp + String(DTCStorage[i].timestamp) + ",";
- temp = temp + String(DTCStorage[i].Number) + ",";
- temp = temp + String(getSeverityForDTC(DTCStorage[i].Number)) + ",";
- temp = temp + String(DTCStorage[i].active) + ",";
- temp = temp + String(DTCStorage[i].debugVal) + ";";
+ temp.concat(String(DTCStorage[i].timestamp) + ",");
+ temp.concat(String(DTCStorage[i].Number) + ",");
+ temp.concat(String(getSeverityForDTC(DTCStorage[i].Number)) + ",");
+ temp.concat(String(DTCStorage[i].active) + ",");
+ temp.concat(String(DTCStorage[i].debugVal) + ";");
}
}
}
- webSocket.textAll(temp);
+ if (client_id > 0)
+ {
+ webSocket.text(client_id, temp);
+ }
+ else
+ {
+ webSocket.textAll(temp);
+ }
}
-#endif
\ No newline at end of file
+
+void Websocket_RefreshClientData_Status(uint32_t client_id, bool send_mapping)
+{
+
+ if (send_mapping)
+ {
+ const char mapping[] = "MAPPING_STATUS:"
+ "SystemStatus;"
+ "TankRemain;"
+ "TravelDistance_hr;"
+ "Odometer;"
+ "Odometer_mm;"
+ "writeCycleCounter;"
+ "BleedingPulses;"
+ "TankPercent;";
+
+ if (client_id > 0)
+ webSocket.text(client_id, mapping);
+ else
+ webSocket.textAll(mapping);
+ }
+
+ String temp = "STATUS:";
+
+ temp.concat(String(globals.systemStatustxt) + ";");
+ temp.concat(String(PersistenceData.tankRemain_microL) + ";");
+ temp.concat(String(PersistenceData.TravelDistance_highRes_mm) + ";");
+ temp.concat(String(PersistenceData.odometer) + ";");
+ temp.concat(String(PersistenceData.odometer_mm / 1000) + ";");
+ temp.concat(String(PersistenceData.writeCycleCounter) + ";");
+ temp.concat(String(LubeConfig.BleedingPulses) + ";");
+ temp.concat(String((PersistenceData.tankRemain_microL / 10) / LubeConfig.tankCapacity_ml) + ";");
+
+ if (client_id > 0)
+ {
+ webSocket.text(client_id, temp);
+ }
+ else
+ {
+ webSocket.textAll(temp);
+ }
+}
+
+void Websocket_RefreshClientData_Static(uint32_t client_id, bool send_mapping)
+{
+
+ if (send_mapping)
+ {
+ const char mapping[] = "MAPPING_STATIC:"
+ "DeviceName;"
+ "EEPROM_Version;"
+ "ConfigChecksum;"
+ "DistanceDefault;"
+ "DistanceRain;"
+ "tankCapacity;"
+ "amountPerDose;"
+ "TankRemindAtPercentage;"
+ "PulsePerRevolution;"
+ "TireWidth_mm;"
+ "TireWidthHeight_Ratio;"
+ "RimDiameter_Inch;"
+ "DistancePerRevolution_mm;"
+ "SpeedSourceString;"
+ "GPSBaudRateString;"
+ "CANSourceString;"
+ "LED_Mode_Flash;"
+ "LED_Max;"
+ "LED_Min;"
+ "eePersistanceAdress;"
+ "PersisChecksum";
+
+ if (client_id > 0)
+ webSocket.text(client_id, mapping);
+ else
+ webSocket.textAll(mapping);
+ }
+
+ String temp = "STATIC:";
+
+ temp.concat(String(globals.DeviceName) + ";");
+ temp.concat(String(LubeConfig.EEPROM_Version) + ";");
+ temp.concat(String(LubeConfig.checksum) + ";");
+ temp.concat(String(LubeConfig.DistancePerLube_Default) + ";");
+ temp.concat(String(LubeConfig.DistancePerLube_Rain) + ";");
+ temp.concat(String(LubeConfig.tankCapacity_ml) + ";");
+ temp.concat(String(LubeConfig.amountPerDose_microL) + ";");
+ temp.concat(String(LubeConfig.TankRemindAtPercentage) + ";");
+ temp.concat(String(LubeConfig.PulsePerRevolution) + ";");
+ temp.concat(String(LubeConfig.TireWidth_mm) + ";");
+ temp.concat(String(LubeConfig.TireWidthHeight_Ratio) + ";");
+ temp.concat(String(LubeConfig.RimDiameter_Inch) + ";");
+ temp.concat(String(LubeConfig.DistancePerRevolution_mm) + ";");
+ temp.concat(String(SpeedSourceString[LubeConfig.SpeedSource]) + ";");
+ temp.concat(String(GPSBaudRateString[LubeConfig.GPSBaudRate]) + ";");
+ temp.concat(String(CANSourceString[LubeConfig.CANSource]) + ";");
+ temp.concat(String(LubeConfig.LED_Mode_Flash) + ";");
+ temp.concat(String(LubeConfig.LED_Max_Brightness) + ";");
+ temp.concat(String(LubeConfig.LED_Min_Brightness) + ";");
+ temp.concat(String(globals.eePersistanceAdress) + ";");
+ temp.concat(String(PersistenceData.checksum) + ";");
+
+ for (uint32_t i = 0; i < SpeedSourceString_Elements; i++)
+ {
+ temp.concat(String(SpeedSourceString[i]) + ",");
+ }
+ temp.concat(";");
+
+ if (client_id > 0)
+ {
+ webSocket.text(client_id, temp);
+ }
+ else
+ {
+ webSocket.textAll(temp);
+ }
+}
\ No newline at end of file