From a576c7b70c89428e1bc2bd813fe87aea1c17c7ac Mon Sep 17 00:00:00 2001
From: Marcel Peterkau
Date: Mon, 4 Dec 2023 02:18:16 +0100
Subject: [PATCH] DTC in WebUI now handled via Websocket
---
Software/data_src/index.htm | 23 ++----
Software/data_src/static/dtc_table.json | 15 ++++
Software/data_src/static/js/dtc_table.js | 101 ++++++++++++++++++++++-
Software/data_src/static/js/websocket.js | 41 +++++++--
Software/include/dtc_defs.h | 12 ++-
Software/src/debugger.cpp | 18 ++--
Software/src/dtc_defs.txt | 4 +-
Software/src/webui.cpp | 89 ++++++++------------
8 files changed, 220 insertions(+), 83 deletions(-)
diff --git a/Software/data_src/index.htm b/Software/data_src/index.htm
index afe8c22..24b4f28 100644
--- a/Software/data_src/index.htm
+++ b/Software/data_src/index.htm
@@ -75,11 +75,11 @@
-
+
Fehlercodes
-
+
Zeitstempel |
@@ -87,7 +87,6 @@
Schwere |
Aktiv |
- %DTC_TABLE%
@@ -803,18 +802,10 @@
nextSibling.innerText = fileName
});
- $(document).ready(function () {
- $("tr[data-dtc]").each(function (i) {
- $(this).attr('data-toggle', "modal");
- $(this).attr('data-target', "#dtcModal");
- });
- });
-
- $('#dtcModal').on('show.bs.modal', function (event) {
- var dtctr = $(event.relatedTarget)
- var dtc = dtctr.data('dtc')
- var debugval = dtctr.data('debugval')
- var modal = $(this)
+ $('table').on('click', 'tr[data-dtc]', function () {
+ var dtc = $(this).data('dtc');
+ var debugval = $(this).data('debugval');
+ var modal = $('#dtcModal');
getDescriptionForDTCNumber(dtc, function (error, title, description) {
if (error)
@@ -837,6 +828,8 @@
}
}
});
+ // Modal anzeigen
+ modal.modal('show');
});
diff --git a/Software/data_src/static/dtc_table.json b/Software/data_src/static/dtc_table.json
index 76fc5dc..a574e05 100644
--- a/Software/data_src/static/dtc_table.json
+++ b/Software/data_src/static/dtc_table.json
@@ -71,6 +71,21 @@
},
{
"num": 14,
+ "title": "Dummy-DTC Info",
+ "description": "Ein Dummy-DTC der Schwere \"Info\" für Debugging-Zwecke"
+ },
+ {
+ "num": 15,
+ "title": "Dummy-DTC Warnung",
+ "description": "Ein Dummy-DTC der Schwere \"Warnung\" für Debugging-Zwecke"
+ },
+ {
+ "num": 16,
+ "title": "Dummy-DTC Kritisch",
+ "description": "Ein Dummy-DTC der Schwere \"Kritisch\" für Debugging-Zwecke"
+ },
+ {
+ "num": 17,
"title": "Last Error",
"description": "Last Error"
}
diff --git a/Software/data_src/static/js/dtc_table.js b/Software/data_src/static/js/dtc_table.js
index c7e9255..9fde968 100644
--- a/Software/data_src/static/js/dtc_table.js
+++ b/Software/data_src/static/js/dtc_table.js
@@ -12,7 +12,11 @@ function getDescriptionForDTCNumber(number, callback) {
callback(null, title, description);
} else {
// Wenn die Nummer nicht gefunden wurde, geben Sie einen Fehler zurück
- callback(`Beschreibung für Nummer ${number} nicht gefunden.`,null, null);
+ callback(
+ `Beschreibung für Nummer ${number} nicht gefunden.`,
+ null,
+ null
+ );
}
})
.catch((error) => {
@@ -21,3 +25,98 @@ function getDescriptionForDTCNumber(number, callback) {
});
}
+function fillDTCTable(dtcArray) {
+ // Referenz auf das Tabellen-Element
+ var table = document.getElementById("dtc_table");
+ var tablediv = document.getElementById("dtc_container");
+
+ // Prüfen, ob DTC vorhanden sind
+ if (dtcArray.length === 0) {
+ // Verstecke das Tabellen-Div, wenn keine DTC vorhanden sind
+ tablediv.hidden = true;
+ return;
+ } else {
+ // Zeige das Tabellen-Div, wenn DTC vorhanden sind
+ tablediv.hidden = false;
+ }
+
+ // Tabelle leeren, bevor sie neu gefüllt wird
+ table.innerHTML = "";
+
+ // Überschriften für die Tabelle erstellen
+ var headerRow = table.insertRow(0);
+
+ // Definition der Klassen und Scopes für die Spalten
+ var columnDefinitions = [
+ { class: "col-6", scope: "Zeitstempel" },
+ { class: "col-2", scope: "Fehlercode" },
+ { class: "col-2", scope: "Schwere" },
+ { class: "col-2", scope: "Aktiv" },
+ ];
+
+ for (var i = 0; i < columnDefinitions.length; i++) {
+ var headerCell = headerRow.insertCell(i);
+ headerCell.className = `th ${columnDefinitions[i].class}`;
+ headerCell.scope = columnDefinitions[i].scope;
+ headerCell.innerHTML = columnDefinitions[i].scope;
+ }
+
+ // DTC-Daten in die Tabelle einfügen
+ for (var i = 0; i < dtcArray.length; i++) {
+ var dtcInfo = dtcArray[i].split(",");
+
+ var row = table.insertRow(i + 1); // +1 wegen der Überschriftenzeile
+
+ // Zeitstempel
+ var timestampCell = row.insertCell(0);
+ timestampCell.innerHTML = formatTimestamp(parseInt(dtcInfo[0]));
+
+ // Fehlercode
+ var errorCodeCell = row.insertCell(1);
+ errorCodeCell.innerHTML = dtcInfo[1];
+
+ // Schwere
+ var severityCell = row.insertCell(2);
+ var severity = parseInt(dtcInfo[2]);
+
+ // Schwere
+ switch (severity) {
+ case 1:
+ severityCell.innerHTML = '
';
+ break;
+ case 2:
+ severityCell.innerHTML =
+ '
';
+ break;
+ case 3:
+ severityCell.innerHTML =
+ '
';
+ break;
+ default:
+ severityCell.innerHTML =
+ '
';
+ }
+
+ row.setAttribute("data-dtc", dtcInfo[1]);
+ row.setAttribute("data-debugval", dtcInfo[4]);
+
+ // Aktivität
+ var activityCell = row.insertCell(3);
+ activityCell.innerHTML = parseInt(dtcInfo[3]) === 1 ? "active" : "previous";
+ }
+}
+
+function formatTimestamp(milliseconds) {
+ const date = new Date(milliseconds);
+
+ const days = String(date.getUTCDate() - 1).padStart(2, "0");
+ const hours = String(date.getUTCHours()).padStart(2, "0");
+ const minutes = String(date.getUTCMinutes()).padStart(2, "0");
+ const seconds = String(date.getUTCSeconds()).padStart(2, "0");
+ const millisecondsFormatted = String(date.getUTCMilliseconds()).padStart(
+ 3,
+ "0"
+ );
+
+ return `${days}-${hours}:${minutes}:${seconds}:${millisecondsFormatted}`;
+}
diff --git a/Software/data_src/static/js/websocket.js b/Software/data_src/static/js/websocket.js
index b8912ba..eccba0d 100644
--- a/Software/data_src/static/js/websocket.js
+++ b/Software/data_src/static/js/websocket.js
@@ -30,11 +30,26 @@ function onClose(event) {
}
function onMessage(event) {
- var livedebug_out = document.getElementById("livedebug-out");
- var textarea_heigth = livedebug_out.scrollHeight;
- livedebug_out.value += event.data;
- livedebug_out.scrollTop = livedebug_out.scrollHeight;
- do_resize(livedebug_out);
+ var data = event.data;
+ 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);
+ }
+ if (data.startsWith("DTC:")) {
+ const dtcs = data.slice(4);
+ const dtcArray = dtcs.trim() !== "" ? dtcs.split(";").filter(Boolean) : [];
+
+ if(dtcArray[0] != "0")
+ {
+ notifyMe();
+ fillDTCTable(dtcArray);
+ }
+ console.log(dtcArray + "\n");
+ }
+ console.log("ws_msg:" + event.data + "\n");
}
function onLoad(event) {
@@ -66,3 +81,19 @@ function do_resize(textbox) {
else if (rows < minrows) textbox.rows = minrows;
else textbox.rows = rows;
}
+
+function notifyMe() {
+ if (!("Notification" in window)) {
+ alert("This browser does not support desktop notification");
+ } else if (Notification.permission === "granted") {
+ const notification = new Notification("Hi there!");
+ // …
+ } else if (Notification.permission !== "denied") {
+ Notification.requestPermission().then((permission) => {
+ if (permission === "granted") {
+ const notification = new Notification("Hi there!");
+ // …
+ }
+ });
+ }
+}
diff --git a/Software/include/dtc_defs.h b/Software/include/dtc_defs.h
index 1eb07af..297cd5c 100644
--- a/Software/include/dtc_defs.h
+++ b/Software/include/dtc_defs.h
@@ -1,4 +1,4 @@
-// Auto-generated by script on 2023-10-20 12:04:36
+// Auto-generated by script on 2023-12-04 02:10:49
#ifndef DTC_DEFS_H
#define DTC_DEFS_H
@@ -40,7 +40,10 @@ typedef struct {
#define DTC_CAN_TRANSCEIVER_FAILED 11
#define DTC_NO_CAN_SIGNAL 12
#define DTC_EEPROM_CFG_SANITY 13
-#define DTC_LAST_DTC 14
+#define DTC_FAKE_DTC_INFO 14
+#define DTC_FAKE_DTC_WARN 15
+#define DTC_FAKE_DTC_CRIT 16
+#define DTC_LAST_DTC 17
const DTC_t dtc_definitions[] = {
{ DTC_NO_DTC , DTC_NONE }, // No Error
@@ -57,9 +60,12 @@ const DTC_t dtc_definitions[] = {
{ DTC_CAN_TRANSCEIVER_FAILED , DTC_CRITICAL }, // Es konnte keine Verbindung zum CAN-Transceiver hergestellt werden. Prüfen Sie die Hardware auf Defekte
{ DTC_NO_CAN_SIGNAL , DTC_WARN }, // Es konnte kein CAN-Signal empfangen werden. Prüfen sie die Verbindung und die Einstellungen
{ DTC_EEPROM_CFG_SANITY , DTC_WARN }, // Ein oder mehrer Einstellungswerte sind ausserhalb plausibler Werte. Prüfen Sie Ihre Einstellungen
+ { DTC_FAKE_DTC_INFO , DTC_INFO }, // Ein Dummy-DTC der Schwere "Info" für Debugging-Zwecke
+ { DTC_FAKE_DTC_WARN , DTC_WARN }, // Ein Dummy-DTC der Schwere "Warnung" für Debugging-Zwecke
+ { DTC_FAKE_DTC_CRIT , DTC_CRITICAL }, // Ein Dummy-DTC der Schwere "Kritisch" für Debugging-Zwecke
{ DTC_LAST_DTC , DTC_NONE } // Last Error
};
-const uint32_t dtc_generation_timestamp = 1697796276;
+const uint32_t dtc_generation_timestamp = 1701652249;
#endif // DTC_DEFS_H
\ No newline at end of file
diff --git a/Software/src/debugger.cpp b/Software/src/debugger.cpp
index 9a5f4b6..88d30be 100644
--- a/Software/src/debugger.cpp
+++ b/Software/src/debugger.cpp
@@ -175,12 +175,20 @@ void processCmdDebug(String command)
Debug_dumpPersistance();
else if (command == "saveEE")
globals.requestEEAction = EE_ALL_SAVE;
- else if (command == "showdtc")
- Debug_ShowDTCs();
else if (command == "dumpGlobals")
Debug_dumpGlobals();
else if (command == "sdbg")
SetDebugportStatus(dbg_Serial, enabled);
+ else if (command == "dtc_show")
+ Debug_ShowDTCs();
+ else if (command == "dtc_clear")
+ ClearAllDTC();
+ else if (command == "dtc_crit")
+ MaintainDTC(DTC_FAKE_DTC_CRIT, true, millis());
+ else if (command == "dtc_warn")
+ MaintainDTC(DTC_FAKE_DTC_WARN, true, millis());
+ else if (command == "dtc_info")
+ MaintainDTC(DTC_FAKE_DTC_INFO, true, millis());
else
Debug_pushMessage("unknown Command\n");
}
@@ -212,9 +220,9 @@ void Debug_printSystemInfo()
Debug_pushMessage("Flash Size: %d\n", ESP.getFlashChipRealSize());
Debug_pushMessage("Flash Size IDE: %d\n", ESP.getFlashChipSize());
Debug_pushMessage("Flash ide mode: %s\n", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT"
- : ideMode == FM_DIO ? "DIO"
- : ideMode == FM_DOUT ? "DOUT"
- : "UNKNOWN"));
+ : ideMode == FM_DIO ? "DIO"
+ : ideMode == FM_DOUT ? "DOUT"
+ : "UNKNOWN"));
Debug_pushMessage("OTA-Pass: %s\n", QUOTE(ADMIN_PASSWORD));
Debug_pushMessage("Git-Revison: %s\n", constants.GitHash);
Debug_pushMessage("Sw-Version: %d.%02d\n", constants.FW_Version_major, constants.FW_Version_minor);
diff --git a/Software/src/dtc_defs.txt b/Software/src/dtc_defs.txt
index c2ce06b..8702d78 100644
--- a/Software/src/dtc_defs.txt
+++ b/Software/src/dtc_defs.txt
@@ -13,4 +13,6 @@
11; DTC_CAN_TRANSCEIVER_FAILED; DTC_CRITICAL; CAN-Transceiver Error; Es konnte keine Verbindung zum CAN-Transceiver hergestellt werden. Prüfen Sie die Hardware auf Defekte
12; DTC_NO_CAN_SIGNAL; DTC_WARN; Keine CAN-Verbindung; Es konnte kein CAN-Signal empfangen werden. Prüfen sie die Verbindung und die Einstellungen
13; DTC_EEPROM_CFG_SANITY; DTC_WARN; Config-Validierung; Ein oder mehrer Einstellungswerte sind ausserhalb plausibler Werte. Prüfen Sie Ihre Einstellungen
-
+ 14; DTC_FAKE_DTC_INFO; DTC_INFO; Dummy-DTC Info; Ein Dummy-DTC der Schwere "Info" für Debugging-Zwecke
+ 15; DTC_FAKE_DTC_WARN; DTC_WARN; Dummy-DTC Warnung; Ein Dummy-DTC der Schwere "Warnung" für Debugging-Zwecke
+ 16; DTC_FAKE_DTC_CRIT; DTC_CRITICAL; Dummy-DTC Kritisch; Ein Dummy-DTC der Schwere "Kritisch" für Debugging-Zwecke
\ No newline at end of file
diff --git a/Software/src/webui.cpp b/Software/src/webui.cpp
index 322d51d..71f8f23 100644
--- a/Software/src/webui.cpp
+++ b/Software/src/webui.cpp
@@ -67,7 +67,15 @@ 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();
+ previousMillis = millis();
+ }
#endif
}
@@ -161,58 +169,6 @@ String processor(const String &var)
#else
return "hidden";
#endif
- if (var == "SHOW_DTC_TABLE")
- return globals.hasDTC ? "" : "hidden";
-
- if (var == "DTC_TABLE")
- {
- String temp = "";
- char buff_timestamp[16]; // Format: DD-hh:mm:ss:xxx
-
- for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++)
- {
- if (DTCStorage[i].Number < DTC_LAST_DTC)
- {
- sprintf(buff_timestamp, "%02d-%02d:%02d:%02d:%03d",
- DTCStorage[i].timestamp / 86400000, // Days
- DTCStorage[i].timestamp / 360000 % 24, // Hours
- DTCStorage[i].timestamp / 60000 % 60, // Minutes
- DTCStorage[i].timestamp / 1000 % 60, // Seconds
- DTCStorage[i].timestamp % 1000); // milliseconds
-
- temp = temp + "" + String(buff_timestamp);
- temp = temp + " | " + String(DTCStorage[i].Number) + " | ";
- temp = temp + " | ";
-
- if (DTCStorage[i].active == DTC_ACTIVE)
- temp = temp + "active";
- else if (DTCStorage[i].active == DTC_PREVIOUS)
- temp = temp + "previous";
- else
- temp = temp + "none";
-
- temp = temp + " |
";
- }
- }
- return temp;
- }
if (var == "SOURCE_SELECT_OPTIONS")
{
@@ -685,6 +641,33 @@ void Websocket_HandleMessage(void *arg, uint8_t *data, size_t len)
void Websocket_PushLiveDebug(String Message)
{
- webSocket.textAll(Message + "\n");
+ webSocket.textAll("DEBUG:" + Message);
+}
+
+void Websocket_RefreshClientData_DTCs()
+{
+ String temp = "";
+
+ // Build DTC-String
+ if (globals.hasDTC != true)
+ {
+ temp = "DTC:" + 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) + ";";
+ }
+ }
+ }
+ webSocket.textAll(temp);
}
#endif
\ No newline at end of file