From 77a94de2ebdb8a91c41a67b50bf6b09174b21939 Mon Sep 17 00:00:00 2001 From: Marcel Peterkau Date: Thu, 23 Feb 2023 23:14:58 +0100 Subject: [PATCH] new debugger and websockets --- Software/data_src/index.htm | 14 ++ Software/data_src/static/js/websocket.js | 68 ++++++ Software/platformio.ini | 1 + Software/src/can.cpp | 1 + Software/src/config.cpp | 33 +-- Software/src/debugger.cpp | 258 ++++++++++++++++++++++ Software/src/debugger.h | 25 +++ Software/src/dtc.cpp | 7 +- Software/src/globals.cpp | 11 + Software/src/globals.h | 2 + Software/src/gps.cpp | 2 +- Software/src/main.cpp | 270 ++--------------------- Software/src/webui.cpp | 101 +++++++-- Software/src/webui.h | 6 + 14 files changed, 516 insertions(+), 283 deletions(-) create mode 100644 Software/data_src/static/js/websocket.js create mode 100644 Software/src/debugger.cpp create mode 100644 Software/src/debugger.h create mode 100644 Software/src/globals.cpp diff --git a/Software/data_src/index.htm b/Software/data_src/index.htm index 2492679..4fb60f8 100644 --- a/Software/data_src/index.htm +++ b/Software/data_src/index.htm @@ -10,6 +10,7 @@ + @@ -523,6 +524,19 @@


+

+

Live Debug

+
+ +
+
+
+ + +
+
+

+
diff --git a/Software/data_src/static/js/websocket.js b/Software/data_src/static/js/websocket.js new file mode 100644 index 0000000..b8912ba --- /dev/null +++ b/Software/data_src/static/js/websocket.js @@ -0,0 +1,68 @@ +var gateway = `ws://${window.location.hostname}/ws`; +var websocket; + +window.addEventListener("load", onLoad); + +function initWebSocket() { + console.log("Trying to open a WebSocket connection..."); + websocket = new WebSocket(gateway); + websocket.onopen = onOpen; + websocket.onclose = onClose; + websocket.onmessage = onMessage; // <-- add this line +} + +function initButtons() { + document + .getElementById("btn-ws-stop") + .addEventListener("click", livedebug_stop); + document + .getElementById("btn-ws-start") + .addEventListener("click", livedebug_start); +} + +function onOpen(event) { + console.log("Connection opened"); +} + +function onClose(event) { + console.log("Connection closed"); + setTimeout(initWebSocket, 2000); +} + +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); +} + +function onLoad(event) { + initWebSocket(); + initButtons(); +} + +function livedebug_start() { + websocket.send("start"); +} + +function livedebug_stop() { + websocket.send("stop"); +} + +function do_resize(textbox) { + var maxrows = 15; + var minrows = 3; + var txt = textbox.value; + var cols = textbox.cols; + + var arraytxt = txt.split("\n"); + var rows = arraytxt.length; + + for (i = 0; i < arraytxt.length; i++) + rows += parseInt(arraytxt[i].length / cols); + + if (rows > maxrows) textbox.rows = maxrows; + else if (rows < minrows) textbox.rows = minrows; + else textbox.rows = rows; +} diff --git a/Software/platformio.ini b/Software/platformio.ini index ef210bb..609b740 100644 --- a/Software/platformio.ini +++ b/Software/platformio.ini @@ -37,6 +37,7 @@ build_flags = -DFEATURE_ENABLE_OLED -DFEATURE_ENABLE_CAN ;-DFEATURE_ENABLE_GPS + -DFEATURE_ENABLE_WEBSOCKETS -DPCB_REV=4 -DNO_MODE_FLASH diff --git a/Software/src/can.cpp b/Software/src/can.cpp index ae8907f..78a5da7 100644 --- a/Software/src/can.cpp +++ b/Software/src/can.cpp @@ -27,6 +27,7 @@ uint32_t Process_CAN_WheelSpeed() if (CAN0.readMsgBuf(&canMsg.can_id, &canMsg.can_dlc, canMsg.data) == CAN_OK) { + RearWheelSpeed_raw = (uint16_t)canMsg.data[5] << 8 | canMsg.data[6]; // raw / FACTOR_RWP_KMH_890ADV -> km/h * 100000 -> cm/h / 3600 -> cm/s // raw * 500 -> cm/s diff --git a/Software/src/config.cpp b/Software/src/config.cpp index 0de4ccd..ef2b8b9 100644 --- a/Software/src/config.cpp +++ b/Software/src/config.cpp @@ -1,4 +1,5 @@ #include "config.h" +#include "debugger.h" I2C_eeprom ee(0x50, EEPROM_SIZE_BYTES); @@ -25,45 +26,45 @@ void EEPROM_Process() case EE_CFG_SAVE: StoreConfig_EEPROM(); globals.requestEEAction = EE_IDLE; - Serial.println("Stored EEPROM CFG"); + Debug_pushMessage("Stored EEPROM CFG\n"); break; case EE_CFG_LOAD: GetConfig_EEPROM(); globals.requestEEAction = EE_IDLE; - Serial.println("Loaded EEPROM CFG"); + Debug_pushMessage("Loaded EEPROM CFG\n"); break; case EE_CFG_FORMAT: FormatConfig_EEPROM(); globals.requestEEAction = EE_IDLE; globals.systemStatus = sysStat_Shutdown; - Serial.println("Formated EEPROM CFG"); + Debug_pushMessage("Formated EEPROM CFG\n"); break; case EE_PDS_SAVE: StorePersistence_EEPROM(); globals.requestEEAction = EE_IDLE; - Serial.println("Stored EEPROM PDS"); + Debug_pushMessage("Stored EEPROM PDS\n"); break; case EE_PDS_LOAD: GetPersistence_EEPROM(); globals.requestEEAction = EE_IDLE; - Serial.println("Loaded EEPROM PDS"); + Debug_pushMessage("Loaded EEPROM PDS\n"); break; case EE_PDS_FORMAT: FormatPersistence_EEPROM(); globals.requestEEAction = EE_IDLE; - Serial.println("Formated EEPROM PDS"); + Debug_pushMessage("Formated EEPROM PDS\n"); break; case EE_FORMAT_ALL: FormatConfig_EEPROM(); FormatPersistence_EEPROM(); globals.requestEEAction = EE_IDLE; - Serial.println("Formated EEPROM ALL"); + Debug_pushMessage("Formated EEPROM ALL\n"); break; case EE_ALL_SAVE: StorePersistence_EEPROM(); StoreConfig_EEPROM(); globals.requestEEAction = EE_IDLE; - Serial.println("Stored EEPROM ALL"); + Debug_pushMessage("Stored EEPROM ALL\n"); break; case EE_IDLE: default: @@ -153,7 +154,7 @@ void GetPersistence_EEPROM() void FormatConfig_EEPROM() { - Serial.println("Formatting Config-Partition"); + Debug_pushMessage("Formatting Config-Partition\n"); LubeConfig = LubeConfig_defaults; LubeConfig.EEPROM_Version = eeVersion; StoreConfig_EEPROM(); @@ -161,7 +162,7 @@ void FormatConfig_EEPROM() void FormatPersistence_EEPROM() { - Serial.println("Formatting Persistance-Partition"); + Debug_pushMessage("Formatting Persistance-Partition\n"); memset(&PersistenceData, 0, sizeof(PersistenceData)); StorePersistence_EEPROM(); } @@ -211,9 +212,9 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length) char ascii_buf[BLOCK_TO_LENGTH + 1]; sprintf(ascii_buf, "%*s", BLOCK_TO_LENGTH, "ASCII"); - Serial.print(PSTR("\nAddress ")); + Debug_pushMessage(PSTR("\nAddress ")); for (int x = 0; x < BLOCK_TO_LENGTH; x++) - Serial.printf("%3d", x); + Debug_pushMessage("%3d", x); memoryAddress = memoryAddress / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH; length = (length + BLOCK_TO_LENGTH - 1) / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH; @@ -224,16 +225,16 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length) if (blockpoint == 0) { ascii_buf[BLOCK_TO_LENGTH] = 0; - Serial.printf(" %s", ascii_buf); - Serial.printf("\n0x%05X:", memoryAddress); + Debug_pushMessage(" %s", ascii_buf); + Debug_pushMessage("\n0x%05X:", memoryAddress); } ascii_buf[blockpoint] = ee.readByte(memoryAddress); - Serial.printf(" %02X", ascii_buf[blockpoint]); + Debug_pushMessage(" %02X", ascii_buf[blockpoint]); if (ascii_buf[blockpoint] < 0x20 || ascii_buf[blockpoint] > 0x7E) ascii_buf[blockpoint] = '.'; memoryAddress++; } - Serial.println(); + Debug_pushMessage("\n"); } boolean checkEEPROMavailable() diff --git a/Software/src/debugger.cpp b/Software/src/debugger.cpp new file mode 100644 index 0000000..013c5c1 --- /dev/null +++ b/Software/src/debugger.cpp @@ -0,0 +1,258 @@ +#include "debugger.h" + +Debugger_t debugger; + +#ifdef FEATURE_ENABLE_REMOTE_DEBUG +RemoteDebug Debug; +String IpAddress2String(const IPAddress &ipAddress); +void processCmdRemoteDebug(); +void RemoteDebug_formatCFG(); +void RemoteDebug_formatPersistence(); +void RemotDebug_printSystemInfo(); +void RemoteDebug_printWifiInfo(); +void RemoteDebug_CheckEEPOM(); +void RemoteDebug_dumpConfig(); +void RemoteDebug_dumpPersistance(); +void RemoteDebug_ShowDTCs(); +void RemoteDebug_dumpGlobals(); +#endif + +void initDebugger() +{ + debugger.serial_debug_enabled = false; + debugger.webui_live_debug_enabled = false; + + Serial.setDebugOutput(false); + +#ifdef FEATURE_ENABLE_REMOTE_DEBUG + Debug.begin(globals.DeviceName); + Debug.setResetCmdEnabled(true); + Debug.showProfiler(false); + Debug.showColors(true); + Debug.setPassword(QUOTE(ADMIN_PASSWORD)); + Debug.setSerialEnabled(true); + Debug.showDebugLevel(true); + + Debug.setHelpProjectsCmds(helpCmd); + Debug.setCallBackProjectCmds(&processCmdRemoteDebug); +#endif +} + +void Debugger_Process() +{ +#ifdef FEATURE_ENABLE_REMOTE_DEBUG + Debug.handle(); +#endif +} + +void Debug_pushMessage(const char *format, ...) +{ + char buff[64]; + va_list arg; + va_start(arg, format); + vsnprintf(buff, sizeof(buff), format, arg); + va_end(arg); + + if (debugger.serial_debug_enabled == true) + { + Serial.print(buff); + } + if (debugger.webui_live_debug_enabled == true) + { + Websocket_PushLiveDebug(String(buff)); + } +} + +void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data[]) +{ + if (debugger.webui_live_debug_enabled == true) + { + char buff[100]; + char *p = buff; + p += snprintf(p, sizeof(buff), "CAN: 0x%08X | %d | ", id, dlc); + for (int i = 0; i < dlc; i++) + { + p += snprintf(p, sizeof(buff) - (p - buff), "%02X ", data[i]); + } + *(p++) = '\n'; + *p = '\0'; + Websocket_PushLiveDebug(String(buff)); + } +} + +#ifdef FEATURE_ENABLE_REMOTE_DEBUG +void processCmdRemoteDebug() +{ + String lastCmd = Debug.getLastCommand(); + + if (lastCmd == "sysinfo") + RemotDebug_printSystemInfo(); + else if (lastCmd == "netinfo") + RemoteDebug_printWifiInfo(); + else if (lastCmd == "formatCFG") + RemoteDebug_formatCFG(); + else if (lastCmd == "formatPDS") + RemoteDebug_formatPersistence(); + else if (lastCmd == "checkEE") + RemoteDebug_CheckEEPOM(); + else if (lastCmd == "dumpEE1k") + dumpEEPROM(0, 1024); + else if (lastCmd == "dumpEE") + dumpEEPROM(0, EEPROM_SIZE_BYTES); + else if (lastCmd == "resetPageEE") + MovePersistencePage_EEPROM(true); + else if (lastCmd == "dumpCFG") + RemoteDebug_dumpConfig(); + else if (lastCmd == "dumpPDS") + RemoteDebug_dumpPersistance(); + else if (lastCmd == "saveEE") + globals.requestEEAction = EE_ALL_SAVE; + else if (lastCmd == "showdtc") + RemoteDebug_ShowDTCs(); + else if (lastCmd == "dumpGlobals") + RemoteDebug_dumpGlobals(); +} + +void RemoteDebug_formatCFG() +{ + debugA("Formatting Config-EEPROM and reseting to default"); + FormatConfig_EEPROM(); +} + +void RemoteDebug_formatPersistence() +{ + debugA("Formatting Persistence-EEPROM and reseting to default"); + FormatPersistence_EEPROM(); +} + +void RemotDebug_printSystemInfo() +{ + debugA("Souko's ChainOiler Mk1"); + debugA("Hostname: %s", globals.DeviceName); + + FlashMode_t ideMode = ESP.getFlashChipMode(); + debugA("Sdk version: %s", ESP.getSdkVersion()); + debugA("Core Version: %s", ESP.getCoreVersion().c_str()); + debugA("Boot Version: %u", ESP.getBootVersion()); + debugA("Boot Mode: %u", ESP.getBootMode()); + debugA("CPU Frequency: %u MHz", ESP.getCpuFreqMHz()); + debugA("Reset reason: %s", ESP.getResetReason().c_str()); + debugA("Flash Size: %d", ESP.getFlashChipRealSize()); + debugA("Flash Size IDE: %d", ESP.getFlashChipSize()); + debugA("Flash ide mode: %s", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT" + : ideMode == FM_DIO ? "DIO" + : ideMode == FM_DOUT ? "DOUT" + : "UNKNOWN")); + debugA("OTA-Pass: %s", QUOTE(ADMIN_PASSWORD)); + debugA("Git-Revison: %s", GIT_REV); + debugA("Sw-Version: %s", QUOTE(SW_VERSION)); +} + +void RemoteDebug_dumpConfig() +{ + debugA("DistancePerLube_Default: %d", LubeConfig.DistancePerLube_Default); + debugA("DistancePerLube_Rain: %d", LubeConfig.DistancePerLube_Rain); + debugA("tankCapacity_ml: %d", LubeConfig.tankCapacity_ml); + debugA("amountPerDose_microL: %d", LubeConfig.amountPerDose_microL); + debugA("TankRemindAtPercentage: %d", LubeConfig.TankRemindAtPercentage); + debugA("PulsePerRevolution: %d", LubeConfig.PulsePerRevolution); + debugA("TireWidth_mm: %d", LubeConfig.TireWidth_mm); + debugA("TireWidthHeight_Ratio: %d", LubeConfig.TireWidth_mm); + debugA("RimDiameter_Inch: %d", LubeConfig.RimDiameter_Inch); + debugA("DistancePerRevolution_mm: %d", LubeConfig.DistancePerRevolution_mm); + debugA("BleedingPulses: %d", LubeConfig.BleedingPulses); + debugA("SpeedSource: %d", LubeConfig.SpeedSource); +#ifdef FEATURE_ENABLE_GPS + debugA("GPSBaudRate: %d", LubeConfig.GPSBaudRate); +#endif +#ifdef FEATURE_ENABLE_CAN + debugA("CANSource: %d", LubeConfig.CANSource); +#endif + debugA("checksum: 0x%08X", LubeConfig.checksum); +} + +void RemoteDebug_dumpGlobals() +{ + debugA("systemStatus: %d", globals.systemStatus); + debugA("resumeStatus: %d", globals.resumeStatus); + debugA("systemStatustxt: %s", globals.systemStatustxt); + debugA("purgePulses: %d", globals.purgePulses); + debugA("requestEEAction: %d", globals.requestEEAction); + debugA("DeviceName: %s", globals.DeviceName); + debugA("FlashVersion: %s", globals.FlashVersion); + debugA("eePersistanceAdress: %d", globals.eePersistanceAdress); + debugA("TankPercentage: %d", globals.TankPercentage); + debugA("hasDTC: %d", globals.hasDTC); +} + +void RemoteDebug_dumpPersistance() +{ + debugA("writeCycleCounter: %d", PersistenceData.writeCycleCounter); + debugA("tankRemain_microL: %d", PersistenceData.tankRemain_microL); + debugA("TravelDistance_highRes_mm: %d", PersistenceData.TravelDistance_highRes_mm); + debugA("checksum: %d", PersistenceData.checksum); + debugA("PSD Adress: 0x%04X", globals.eePersistanceAdress); +} + +void RemoteDebug_printWifiInfo() +{ +} + +void RemoteDebug_CheckEEPOM() +{ + uint32_t checksum = PersistenceData.checksum; + PersistenceData.checksum = 0; + + if (Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) == checksum) + { + debugA("PersistenceData EEPROM Checksum OK\n"); + } + else + { + debugA("PersistenceData EEPROM Checksum BAD\n"); + } + + PersistenceData.checksum = checksum; + + checksum = LubeConfig.checksum; + LubeConfig.checksum = 0; + + if (Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) == checksum) + { + debugA("LubeConfig EEPROM Checksum OK\n"); + } + else + { + debugA("LubeConfig EEPROM Checksum BAD\n"); + } + LubeConfig.checksum = checksum; +} + +void RemoteDebug_ShowDTCs() +{ + char buff_timestamp[16]; // Format: DD-hh:mm:ss:xxx + char buff_active[9]; + + 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 + + if (DTCStorage[i].active == DTC_ACTIVE) + strcpy(buff_active, "active"); + else if (DTCStorage[i].active == DTC_PREVIOUS) + strcpy(buff_active, "previous"); + else + strcpy(buff_active, "none"); + + debugA("%s \t %6d \t %s", buff_timestamp, DTCStorage[i].Number, buff_active); + } + } +} +#endif \ No newline at end of file diff --git a/Software/src/debugger.h b/Software/src/debugger.h new file mode 100644 index 0000000..f4e9d2f --- /dev/null +++ b/Software/src/debugger.h @@ -0,0 +1,25 @@ +#ifndef _DEBUGGER_H_ +#define _DEBUGGER_H_ + +#include +#include "webui.h" + +#ifdef FEATURE_ENABLE_REMOTE_DEBUG +#include +#include "rmtdbghelp.h" +#endif + +typedef struct Debugger_s +{ + bool webui_live_debug_enabled; + bool serial_debug_enabled; +} Debugger_t; + +extern Debugger_t debugger; + +void initDebugger(); +void Debugger_Process(); +void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data[]); +void Debug_pushMessage(const char *format, ...); + +#endif \ No newline at end of file diff --git a/Software/src/dtc.cpp b/Software/src/dtc.cpp index 9d0d9c6..677cd34 100644 --- a/Software/src/dtc.cpp +++ b/Software/src/dtc.cpp @@ -1,4 +1,5 @@ #include "dtc.h" +#include "debugger.h" DTCEntry_s DTCStorage[MAX_DTC_STORAGE]; @@ -10,7 +11,7 @@ void MaintainDTC(DTCNums_t DTC_no, DTCSeverity_t DTC_severity, boolean active, u { if (active && DTCStorage[i].active != DTC_ACTIVE) { - Serial.printf("DTC gone active: %d, DebugVal: %d\n", DTC_no, DebugValue); + Debug_pushMessage("DTC gone active: %d, DebugVal: %d\n", DTC_no, DebugValue); DTCStorage[i].timestamp = millis(); DTCStorage[i].active = DTC_ACTIVE; DTCStorage[i].severity = DTC_severity; @@ -18,7 +19,7 @@ void MaintainDTC(DTCNums_t DTC_no, DTCSeverity_t DTC_severity, boolean active, u } if (!active && DTCStorage[i].active == DTC_ACTIVE) { - Serial.printf("DTC gone previous: %d\n", DTC_no); + Debug_pushMessage("DTC gone previous: %d\n", DTC_no); DTCStorage[i].active = DTC_PREVIOUS; } return; @@ -33,7 +34,7 @@ void MaintainDTC(DTCNums_t DTC_no, DTCSeverity_t DTC_severity, boolean active, u { if (DTCStorage[i].Number == DTC_LAST_DTC) { - Serial.printf("new DTC registered: %d, DebugVal: %d\n", DTC_no, DebugValue); + Debug_pushMessage("new DTC registered: %d, DebugVal: %d\n", DTC_no, DebugValue); DTCStorage[i].Number = DTC_no; DTCStorage[i].timestamp = millis(); DTCStorage[i].active = DTC_ACTIVE; diff --git a/Software/src/globals.cpp b/Software/src/globals.cpp new file mode 100644 index 0000000..8886874 --- /dev/null +++ b/Software/src/globals.cpp @@ -0,0 +1,11 @@ +#include "globals.h" + +Globals_t globals; + +void initGlobals() +{ + globals.purgePulses = 0; + globals.requestEEAction = EE_IDLE; + globals.resumeStatus = sysStat_Normal; + globals.systemStatus = sysStat_Startup; +} diff --git a/Software/src/globals.h b/Software/src/globals.h index d508023..6933c59 100644 --- a/Software/src/globals.h +++ b/Software/src/globals.h @@ -43,4 +43,6 @@ typedef struct Globals_s extern Globals_t globals; +void initGlobals(); + #endif \ No newline at end of file diff --git a/Software/src/gps.cpp b/Software/src/gps.cpp index 7c82c11..1e83905 100644 --- a/Software/src/gps.cpp +++ b/Software/src/gps.cpp @@ -19,7 +19,7 @@ void Init_GPS() break; } - Serial.printf(PSTR("Init GPS with Baud %d\n"), baudrate); + Debug_pushMessage(PSTR("Init GPS with Baud %d\n"), baudrate); Serial.begin(baudrate); } diff --git a/Software/src/main.cpp b/Software/src/main.cpp index b685bb4..f2e6641 100644 --- a/Software/src/main.cpp +++ b/Software/src/main.cpp @@ -17,6 +17,7 @@ #include "webui.h" #include "config.h" #include "globals.h" +#include "debugger.h" #ifdef FEATURE_ENABLE_CAN #include "can.h" #endif @@ -25,14 +26,6 @@ #endif #include "dtc.h" -#ifdef FEATURE_ENABLE_REMOTE_DEBUG -#include -#include "rmtdbghelp.h" -#else -#define debugV Serial.println -#define debugE Serial.println -#endif - #ifdef FEATURE_ENABLE_WIFI_CLIENT #include @@ -44,8 +37,6 @@ ESP8266WiFiMulti wifiMulti; #endif bool startSetupMode = false; - -Globals_t globals; volatile uint32_t wheel_pulse = 0; CRGB leds[1]; @@ -62,22 +53,6 @@ void toggleWiFiAP(boolean shutdown = false); void SystemShutdown(); uint32_t Process_Impulse_WheelSpeed(); void EEPROMCyclicPDS_callback(); -void initGlobals(); - -#ifdef FEATURE_ENABLE_REMOTE_DEBUG -RemoteDebug Debug; -String IpAddress2String(const IPAddress &ipAddress); -void processCmdRemoteDebug(); -void RemoteDebug_formatCFG(); -void RemoteDebug_formatPersistence(); -void RemotDebug_printSystemInfo(); -void RemoteDebug_printWifiInfo(); -void RemoteDebug_CheckEEPOM(); -void RemoteDebug_dumpConfig(); -void RemoteDebug_dumpPersistance(); -void RemoteDebug_ShowDTCs(); -void RemoteDebug_dumpGlobals(); -#endif #ifdef FEATURE_ENABLE_WIFI_CLIENT void wifiMaintainConnectionTicker_callback(); @@ -103,8 +78,6 @@ void setup() #endif Serial.begin(115200); - Serial.setDebugOutput(false); - Serial.println("\n\nSouko's ChainLube Mk1"); Serial.println(globals.DeviceName); @@ -137,26 +110,13 @@ void setup() break; #endif default: - debugE("Source Setting N/A"); + Debug_pushMessage("Source Setting N/A"); break; } pinMode(GPIO_BUTTON, INPUT_PULLUP); pinMode(GPIO_PUMP, OUTPUT); -#ifdef FEATURE_ENABLE_REMOTE_DEBUG - Debug.begin(globals.DeviceName); - Debug.setResetCmdEnabled(true); - Debug.showProfiler(false); - Debug.showColors(true); - Debug.setPassword(QUOTE(ADMIN_PASSWORD)); - Debug.setSerialEnabled(true); - Debug.showDebugLevel(true); - - Debug.setHelpProjectsCmds(helpCmd); - Debug.setCallBackProjectCmds(&processCmdRemoteDebug); -#endif - ArduinoOTA.setPort(8266); ArduinoOTA.setHostname(globals.DeviceName); ArduinoOTA.setPassword(QUOTE(ADMIN_PASSWORD)); @@ -232,11 +192,11 @@ void loop() Button_Process(); LED_Process(); EEPROM_Process(); + Webserver_Process(); + Debugger_Process(); ArduinoOTA.handle(); -#ifdef FEATURE_ENABLE_REMOTE_DEBUG - Debug.handle(); -#endif + #ifdef FEATURE_ENABLE_WIFI_CLIENT WiFiMaintainConnectionTicker.update(); #endif @@ -253,163 +213,6 @@ String IpAddress2String(const IPAddress &ipAddress) String(ipAddress[3]); } -void initGlobals() -{ - globals.purgePulses = 0; - globals.requestEEAction = EE_IDLE; - globals.resumeStatus = sysStat_Normal; - globals.systemStatus = sysStat_Startup; -} - -#ifdef FEATURE_ENABLE_REMOTE_DEBUG -void processCmdRemoteDebug() -{ - String lastCmd = Debug.getLastCommand(); - - if (lastCmd == "sysinfo") - RemotDebug_printSystemInfo(); - else if (lastCmd == "netinfo") - RemoteDebug_printWifiInfo(); - else if (lastCmd == "formatCFG") - RemoteDebug_formatCFG(); - else if (lastCmd == "formatPDS") - RemoteDebug_formatPersistence(); - else if (lastCmd == "checkEE") - RemoteDebug_CheckEEPOM(); - else if (lastCmd == "dumpEE1k") - dumpEEPROM(0, 1024); - else if (lastCmd == "dumpEE") - dumpEEPROM(0, EEPROM_SIZE_BYTES); - else if (lastCmd == "resetPageEE") - MovePersistencePage_EEPROM(true); - else if (lastCmd == "dumpCFG") - RemoteDebug_dumpConfig(); - else if (lastCmd == "dumpPDS") - RemoteDebug_dumpPersistance(); - else if (lastCmd == "saveEE") - globals.requestEEAction = EE_ALL_SAVE; - else if (lastCmd == "showdtc") - RemoteDebug_ShowDTCs(); - else if (lastCmd == "dumpGlobals") - RemoteDebug_dumpGlobals(); -} - -void RemoteDebug_formatCFG() -{ - debugA("Formatting Config-EEPROM and reseting to default"); - FormatConfig_EEPROM(); -} - -void RemoteDebug_formatPersistence() -{ - debugA("Formatting Persistence-EEPROM and reseting to default"); - FormatPersistence_EEPROM(); -} - -void RemotDebug_printSystemInfo() -{ - debugA("Souko's ChainOiler Mk1"); - debugA("Hostname: %s", globals.DeviceName); - - FlashMode_t ideMode = ESP.getFlashChipMode(); - debugA("Sdk version: %s", ESP.getSdkVersion()); - debugA("Core Version: %s", ESP.getCoreVersion().c_str()); - debugA("Boot Version: %u", ESP.getBootVersion()); - debugA("Boot Mode: %u", ESP.getBootMode()); - debugA("CPU Frequency: %u MHz", ESP.getCpuFreqMHz()); - debugA("Reset reason: %s", ESP.getResetReason().c_str()); - debugA("Flash Size: %d", ESP.getFlashChipRealSize()); - debugA("Flash Size IDE: %d", ESP.getFlashChipSize()); - debugA("Flash ide mode: %s", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT" - : ideMode == FM_DIO ? "DIO" - : ideMode == FM_DOUT ? "DOUT" - : "UNKNOWN")); - debugA("OTA-Pass: %s", QUOTE(ADMIN_PASSWORD)); - debugA("Git-Revison: %s", GIT_REV); - debugA("Sw-Version: %s", QUOTE(SW_VERSION)); -} - -void RemoteDebug_dumpConfig() -{ - debugA("DistancePerLube_Default: %d", LubeConfig.DistancePerLube_Default); - debugA("DistancePerLube_Rain: %d", LubeConfig.DistancePerLube_Rain); - debugA("tankCapacity_ml: %d", LubeConfig.tankCapacity_ml); - debugA("amountPerDose_microL: %d", LubeConfig.amountPerDose_microL); - debugA("TankRemindAtPercentage: %d", LubeConfig.TankRemindAtPercentage); - debugA("PulsePerRevolution: %d", LubeConfig.PulsePerRevolution); - debugA("TireWidth_mm: %d", LubeConfig.TireWidth_mm); - debugA("TireWidthHeight_Ratio: %d", LubeConfig.TireWidth_mm); - debugA("RimDiameter_Inch: %d", LubeConfig.RimDiameter_Inch); - debugA("DistancePerRevolution_mm: %d", LubeConfig.DistancePerRevolution_mm); - debugA("BleedingPulses: %d", LubeConfig.BleedingPulses); - debugA("SpeedSource: %d", LubeConfig.SpeedSource); -#ifdef FEATURE_ENABLE_GPS - debugA("GPSBaudRate: %d", LubeConfig.GPSBaudRate); -#endif -#ifdef FEATURE_ENABLE_CAN - debugA("CANSource: %d", LubeConfig.CANSource); -#endif - debugA("checksum: 0x%08X", LubeConfig.checksum); -} - -void RemoteDebug_dumpGlobals() -{ - debugA("systemStatus: %d", globals.systemStatus); - debugA("resumeStatus: %d", globals.resumeStatus); - debugA("systemStatustxt: %s", globals.systemStatustxt); - debugA("purgePulses: %d", globals.purgePulses); - debugA("requestEEAction: %d", globals.requestEEAction); - debugA("DeviceName: %s", globals.DeviceName); - debugA("FlashVersion: %s", globals.FlashVersion); - debugA("eePersistanceAdress: %d", globals.eePersistanceAdress); - debugA("TankPercentage: %d", globals.TankPercentage); - debugA("hasDTC: %d", globals.hasDTC); -} - -void RemoteDebug_dumpPersistance() -{ - debugA("writeCycleCounter: %d", PersistenceData.writeCycleCounter); - debugA("tankRemain_microL: %d", PersistenceData.tankRemain_microL); - debugA("TravelDistance_highRes_mm: %d", PersistenceData.TravelDistance_highRes_mm); - debugA("checksum: %d", PersistenceData.checksum); - debugA("PSD Adress: 0x%04X", globals.eePersistanceAdress); -} - -void RemoteDebug_printWifiInfo() -{ -} - -void RemoteDebug_CheckEEPOM() -{ - uint32_t checksum = PersistenceData.checksum; - PersistenceData.checksum = 0; - - if (Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) == checksum) - { - debugA("PersistenceData EEPROM Checksum OK\n"); - } - else - { - debugA("PersistenceData EEPROM Checksum BAD\n"); - } - - PersistenceData.checksum = checksum; - - checksum = LubeConfig.checksum; - LubeConfig.checksum = 0; - - if (Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) == checksum) - { - debugA("LubeConfig EEPROM Checksum OK\n"); - } - else - { - debugA("LubeConfig EEPROM Checksum BAD\n"); - } - LubeConfig.checksum = checksum; -} -#endif - #ifdef FEATURE_ENABLE_WIFI_CLIENT void wifiMaintainConnectionTicker_callback() { @@ -428,7 +231,7 @@ void wifiMaintainConnectionTicker_callback() } else { - debugV("WiFi not connected! - Start AP"); + Debug_pushMessage("WiFi not connected! - Start AP"); toggleWiFiAP(); } } @@ -474,7 +277,7 @@ void LED_Process(uint8_t override, CRGB SetColor) if (LED_Status != LED_Override) { LED_ResumeOverrideStatus = LED_Status; - debugV("Override LED_Status"); + Debug_pushMessage("Override LED_Status"); } LED_Status = LED_Override; LED_override_color = SetColor; @@ -485,7 +288,7 @@ void LED_Process(uint8_t override, CRGB SetColor) if (LED_Status == LED_Override) { LED_Status = LED_ResumeOverrideStatus; - debugV("Resume LED_Status"); + Debug_pushMessage("Resume LED_Status"); } } @@ -495,25 +298,25 @@ void LED_Process(uint8_t override, CRGB SetColor) { case sysStat_Startup: LED_Status = LED_Startup; - debugV("sysStat: Startup"); + Debug_pushMessage("sysStat: Startup"); break; case sysStat_Normal: timestamp = timer + 3500; LED_Status = LED_Confirm_Normal; - debugV("sysStat: Normal"); + Debug_pushMessage("sysStat: Normal"); break; case sysStat_Rain: timestamp = timer + 3500; LED_Status = LED_Confirm_Rain; - debugV("sysStat: Rain"); + Debug_pushMessage("sysStat: Rain"); break; case sysStat_Purge: LED_Status = LED_Purge; - debugV("sysStat: Purge"); + Debug_pushMessage("sysStat: Purge"); break; case sysStat_Error: LED_Status = LED_Error; - debugV("sysStat: Error"); + Debug_pushMessage("sysStat: Error"); break; case sysStat_Shutdown: default: @@ -540,7 +343,7 @@ void LED_Process(uint8_t override, CRGB SetColor) { LED_Status = LED_Normal; FastLED.setBrightness(64); - debugV("LED_Status: Confirm -> Normal"); + Debug_pushMessage("LED_Status: Confirm -> Normal"); } break; @@ -564,7 +367,7 @@ void LED_Process(uint8_t override, CRGB SetColor) { LED_Status = LED_Rain; FastLED.setBrightness(64); - debugV("LED_Status: Confirm -> Rain"); + Debug_pushMessage("LED_Status: Confirm -> Rain"); } break; @@ -694,13 +497,13 @@ void Button_Process() { case BTN_TOGGLEWIFI: toggleWiFiAP(); - debugV("Starting WiFi AP"); + Debug_pushMessage("Starting WiFi AP"); break; case BTN_STARTPURGE: globals.systemStatus = sysStat_Purge; globals.purgePulses = LubeConfig.BleedingPulses; - debugV("Starting Purge"); + Debug_pushMessage("Starting Purge"); break; case BTN_TOGGLEMODE: @@ -718,12 +521,12 @@ void Button_Process() default: break; } - debugV("Toggling Mode"); + Debug_pushMessage("Toggling Mode"); break; case BTN_NOTHING: default: - debugV("Nothing or invalid"); + Debug_pushMessage("Nothing or invalid"); break; } LED_Process(2); @@ -738,7 +541,7 @@ void toggleWiFiAP(boolean shutdown) if (WiFi.getMode() != WIFI_OFF) { WiFi.mode(WIFI_OFF); - debugV("WiFi turned off"); + Debug_pushMessage("WiFi turned off"); #ifdef FEATURE_ENABLE_WIFI_CLIENT WiFiMaintainConnectionTicker.stop(); #endif @@ -750,9 +553,9 @@ void toggleWiFiAP(boolean shutdown) WiFi.softAP(globals.DeviceName, QUOTE(WIFI_AP_PASSWORD)); #ifdef FEATURE_ENABLE_WIFI_CLIENT WiFiMaintainConnectionTicker.stop(); - debugV("WiFi AP started, stopped Maintain-Timer"); + Debug_pushMessage("WiFi AP started, stopped Maintain-Timer"); #else - debugV("WiFi AP started"); + Debug_pushMessage("WiFi AP started"); #endif } } @@ -784,32 +587,3 @@ uint32_t Process_Impulse_WheelSpeed() return add_milimeters; } -#ifdef FEATURE_ENABLE_REMOTE_DEBUG -void RemoteDebug_ShowDTCs() -{ - char buff_timestamp[16]; // Format: DD-hh:mm:ss:xxx - char buff_active[9]; - - 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 - - if (DTCStorage[i].active == DTC_ACTIVE) - strcpy(buff_active, "active"); - else if (DTCStorage[i].active == DTC_PREVIOUS) - strcpy(buff_active, "previous"); - else - strcpy(buff_active, "none"); - - debugA("%s \t %6d \t %s", buff_timestamp, DTCStorage[i].Number, buff_active); - } - } -} -#endif \ No newline at end of file diff --git a/Software/src/webui.cpp b/Software/src/webui.cpp index 85796b1..b360392 100644 --- a/Software/src/webui.cpp +++ b/Software/src/webui.cpp @@ -13,11 +13,20 @@ 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); + +#endif + void initWebUI() { if (!LittleFS.begin()) { - Serial.println("An Error has occurred while mounting LittleFS"); + Debug_pushMessage("An Error has occurred while mounting LittleFS\n"); MaintainDTC(DTC_FLASHFS_ERROR, DTC_CRITICAL, true); return; } @@ -33,6 +42,11 @@ void initWebUI() MDNS.addService("telnet", "tcp", 23); 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) { request->redirect("/index.htm"); }); @@ -48,6 +62,13 @@ void initWebUI() webServer.begin(); } +void Webserver_Process() +{ +#ifdef FEATURE_ENABLE_WEBSOCKETS + webSocket.cleanupClients(); +#endif +} + String processor(const String &var) { if (var == "TANK_REMAIN_CAPACITY") @@ -241,14 +262,14 @@ void WebserverPOST_Callback(AsyncWebServerRequest *request) for (int i = 0; i < paramsNr; i++) { AsyncWebParameter *p = request->getParam(i); - Serial.printf("%s : %s\n", p->name().c_str(), p->value().c_str()); + 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(); - Serial.printf("temp: %d", temp); - Serial.printf("SpeedSource: %d", LubeConfig.SpeedSource); + Debug_pushMessage("temp: %d", temp); + Debug_pushMessage("SpeedSource: %d", LubeConfig.SpeedSource); if (LubeConfig.SpeedSource != temp) { LubeConfig.SpeedSource = temp; @@ -332,7 +353,7 @@ void WebserverPOST_Callback(AsyncWebServerRequest *request) globals.systemStatus = sysStat_Purge; globals.purgePulses = LubeConfig.BleedingPulses; } - if(p->name() == "reboot") + if (p->name() == "reboot") { globals.systemStatus = sysStat_Shutdown; } @@ -367,7 +388,7 @@ void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const Stri if (!index) { - Serial.println("Update"); + Debug_pushMessage("Update"); size_t content_len = request->contentLength(); int cmd = (filename.indexOf(".fs") > -1) ? U_FS : U_FLASH; Update.runAsync(true); @@ -383,7 +404,7 @@ void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const Stri } else { - Serial.printf("Progress: %d%%\n", (Update.progress() * 100) / Update.size()); + Debug_pushMessage("Progress: %d%%\n", (Update.progress() * 100) / Update.size()); } if (final) @@ -398,8 +419,7 @@ void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const Stri } else { - Serial.println("Update complete"); - Serial.flush(); + Debug_pushMessage("Update complete\n"); globals.systemStatus = sysStat_Shutdown; } } @@ -413,14 +433,14 @@ void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &f if (!index) { - Serial.println("EEPROM restore"); - //size_t content_len = request->contentLength(); + Debug_pushMessage("EEPROM restore\n"); + // size_t content_len = request->contentLength(); validext = (filename.indexOf(".ee.json") > -1); } if (validext) { - Serial.println("Restoring EEPROM-Stuff"); + Debug_pushMessage("Restoring EEPROM-Stuff\n"); } if (final) @@ -431,8 +451,7 @@ void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &f request->send(response); if (ee_done) { - Serial.println("Update complete"); - Serial.flush(); + Debug_pushMessage("Update complete"); globals.systemStatus = sysStat_Shutdown; } else @@ -500,4 +519,56 @@ void WebServerEEJSON_Callback(AsyncWebServerRequest *request) response->addHeader("Content-disposition", "attachment; filename=backup.ee.json"); request->send(response); -} \ No newline at end of file +} + +#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()); + break; + case WS_EVT_DISCONNECT: + Debug_pushMessage("WebSocket client #%u disconnected\n", client->id()); + break; + case WS_EVT_DATA: + Websocket_HandleMessage(arg, data, len); + break; + case WS_EVT_PONG: + case WS_EVT_ERROR: + break; + } +} + +void Websocket_HandleMessage(void *arg, uint8_t *data, size_t len) +{ + AwsFrameInfo *info = (AwsFrameInfo *)arg; + if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) + { + data[len] = 0; + + Debug_pushMessage("Got WebSocket Message: %s \n", (char *)data); + + if (strcmp((char *)data, "start") == 0) + { + Debug_pushMessage("Got WebSocket Message 'start' from client\n"); + debugger.webui_live_debug_enabled = true; + } + else if (strcmp((char *)data, "stop") == 0) + { + Debug_pushMessage("Got WebSocket Message 'stop' from client\n"); + debugger.webui_live_debug_enabled = false; + } + else if (strcmp((char *)data, "foo") == 0) + { + Debug_pushMessage("Got WebSocket Message 'foo' from client\n"); + } + } +} + +void Websocket_PushLiveDebug(String Message) +{ + webSocket.textAll(Message + "\n"); +} +#endif \ No newline at end of file diff --git a/Software/src/webui.h b/Software/src/webui.h index 170c5b1..2552ad5 100644 --- a/Software/src/webui.h +++ b/Software/src/webui.h @@ -15,7 +15,13 @@ #include "globals.h" #include "dtc.h" #include "common.h" +#include "debugger.h" void initWebUI(); +void Webserver_Process(); + +#ifdef FEATURE_ENABLE_WEBSOCKETS +void Websocket_PushLiveDebug(String Message); +#endif #endif \ No newline at end of file