Compare commits
	
		
			3 Commits
		
	
	
		
			1.08
			...
			b024bb66a9
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b024bb66a9 | |||
| 58e9a97804 | |||
| f966f2df14 | 
							
								
								
									
										1
									
								
								Software/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								Software/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,6 @@
 | 
				
			|||||||
data/
 | 
					data/
 | 
				
			||||||
data_src/version
 | 
					data_src/version
 | 
				
			||||||
 | 
					node_modules/
 | 
				
			||||||
.pio
 | 
					.pio
 | 
				
			||||||
.vscode/.browse.c_cpp.db*
 | 
					.vscode/.browse.c_cpp.db*
 | 
				
			||||||
.vscode/c_cpp_properties.json
 | 
					.vscode/c_cpp_properties.json
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,3 @@
 | 
				
			|||||||
import glob
 | 
					 | 
				
			||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
import gzip
 | 
					import gzip
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
@@ -8,23 +7,40 @@ from os import popen
 | 
				
			|||||||
Import("env")
 | 
					Import("env")
 | 
				
			||||||
Import("projenv")
 | 
					Import("projenv")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Überprüfe die Betriebssystemplattform
 | 
					def resolve_tool(name):
 | 
				
			||||||
if platform.system() == "Windows":
 | 
					    local_bin = os.path.join(env['PROJECT_DIR'], 'node_modules', '.bin', name)
 | 
				
			||||||
    # Setze die Pfade zu den Tools für Windows
 | 
					    if platform.system() == "Windows":
 | 
				
			||||||
    html_minifier_path = os.path.join(os.getenv("APPDATA"), "npm", "html-minifier.cmd")
 | 
					        local_bin += ".cmd"
 | 
				
			||||||
    uglifyjs_path = os.path.join(os.getenv("APPDATA"), "npm", "uglifyjs.cmd")
 | 
					    if os.path.exists(local_bin):
 | 
				
			||||||
    terser_path = os.path.join(os.getenv("APPDATA"), "npm", "terser.cmd")
 | 
					        return local_bin
 | 
				
			||||||
    cssnano_path = os.path.join(os.getenv("APPDATA"), "npm", "cssnano.cmd")
 | 
					 | 
				
			||||||
elif platform.system() == "Linux":
 | 
					 | 
				
			||||||
    # Setze die Namen der Tools für Linux
 | 
					 | 
				
			||||||
    html_minifier_path = "html-minifier"
 | 
					 | 
				
			||||||
    uglifyjs_path = "uglifyjs"
 | 
					 | 
				
			||||||
    terser_path = "terser"
 | 
					 | 
				
			||||||
    cssnano_path = "cssnano"
 | 
					 | 
				
			||||||
else:
 | 
					 | 
				
			||||||
    # Hier könntest du weitere Bedingungen für andere Betriebssysteme hinzufügen
 | 
					 | 
				
			||||||
    raise Exception("Unterstütztes Betriebssystem nicht erkannt")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    found = shutil.which(name)
 | 
				
			||||||
 | 
					    if found:
 | 
				
			||||||
 | 
					        return found
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    raise FileNotFoundError(f"{name} wurde nicht gefunden. Bitte `npm install` ausführen.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def ensure_npm_dependencies():
 | 
				
			||||||
 | 
					    node_modules_bin = os.path.join(env['PROJECT_DIR'], 'node_modules', '.bin')
 | 
				
			||||||
 | 
					    required_tools = ["html-minifier", "terser", "cleancss"]
 | 
				
			||||||
 | 
					    missing = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for tool in required_tools:
 | 
				
			||||||
 | 
					        path = os.path.join(node_modules_bin, tool + ('.cmd' if platform.system() == "Windows" else ''))
 | 
				
			||||||
 | 
					        if not os.path.exists(path):
 | 
				
			||||||
 | 
					            missing = True
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if missing:
 | 
				
			||||||
 | 
					        print("NPM-Abhängigkeiten fehlen – führe `npm install` aus...")
 | 
				
			||||||
 | 
					        subprocess.run(["npm", "install"], cwd=env['PROJECT_DIR'], check=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ensure_npm_dependencies()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					html_minifier_path = resolve_tool("html-minifier")
 | 
				
			||||||
 | 
					terser_path = resolve_tool("terser")
 | 
				
			||||||
 | 
					cleancss_path = resolve_tool("cleancss")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def minify_html(input_path, output_path):
 | 
					def minify_html(input_path, output_path):
 | 
				
			||||||
    subprocess.run([html_minifier_path, '--collapse-whitespace', '--remove-comments', input_path, '-o', output_path])
 | 
					    subprocess.run([html_minifier_path, '--collapse-whitespace', '--remove-comments', input_path, '-o', output_path])
 | 
				
			||||||
@@ -33,7 +49,7 @@ def minify_js(input_path, output_path):
 | 
				
			|||||||
    subprocess.run([terser_path, input_path, '-o', output_path, '-c', '-m'])
 | 
					    subprocess.run([terser_path, input_path, '-o', output_path, '-c', '-m'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def minify_css(input_path, output_path):
 | 
					def minify_css(input_path, output_path):
 | 
				
			||||||
    subprocess.run([cssnano_path, '--no-discardUnused', input_path, output_path])
 | 
					    subprocess.run([cleancss_path, '--no-discardUnused', input_path, output_path])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def process_file(src_path, dest_path):
 | 
					def process_file(src_path, dest_path):
 | 
				
			||||||
    _, file_extension = os.path.splitext(src_path)
 | 
					    _, file_extension = os.path.splitext(src_path)
 | 
				
			||||||
@@ -152,7 +168,8 @@ def gzip_webfiles(source, target, env):
 | 
				
			|||||||
            target_file_path = data_dir_path + filename_subdir
 | 
					            target_file_path = data_dir_path + filename_subdir
 | 
				
			||||||
            os.makedirs(os.path.dirname(target_file_path), exist_ok=True)
 | 
					            os.makedirs(os.path.dirname(target_file_path), exist_ok=True)
 | 
				
			||||||
            print('GZIP: Compressed... ' + target_file_path)
 | 
					            print('GZIP: Compressed... ' + target_file_path)
 | 
				
			||||||
            gzip_file(source_file_path, target_file_path + ".gz")
 | 
					            gzip_target_path = target_file_path + ".gz"
 | 
				
			||||||
 | 
					            gzip_file(source_file_path, gzip_target_path)
 | 
				
			||||||
    except IOError as e:
 | 
					    except IOError as e:
 | 
				
			||||||
        was_error = True
 | 
					        was_error = True
 | 
				
			||||||
        print('GZIP: Failed to compress file: ' + source_file_path)
 | 
					        print('GZIP: Failed to compress file: ' + source_file_path)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,7 +70,4 @@ typedef enum batteryType_e
 | 
				
			|||||||
extern const char *BatteryString[];
 | 
					extern const char *BatteryString[];
 | 
				
			||||||
extern const size_t BatteryString_Elements;
 | 
					extern const size_t BatteryString_Elements;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STARTUP_DELAY 2500
 | 
					 | 
				
			||||||
#define SHUTDOWN_DELAY_MS 2500
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,9 @@
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * @file debugger.h
 | 
					 * @file debugger.h
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @brief Header file for debugging functions and status in the DE-Timer application.
 | 
					 * @brief Header file for debugging functions and status in the ChainLube application.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This file declares functions and status definitions for debugging purposes in the DE-Timer project.
 | 
					 * This file declares functions and status definitions for debugging purposes in the ChainLube project.
 | 
				
			||||||
 * It includes functions to print system information, WiFi information, format EEPROM data,
 | 
					 * It includes functions to print system information, WiFi information, format EEPROM data,
 | 
				
			||||||
 * handle debug messages, and manage the status of different debug ports.
 | 
					 * handle debug messages, and manage the status of different debug ports.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -16,22 +16,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <Arduino.h>
 | 
					#include <Arduino.h>
 | 
				
			||||||
#include "webui.h"
 | 
					#include "webui.h"
 | 
				
			||||||
const char PROGMEM helpCmd[] = "sysinfo     - System Info\n"
 | 
					 | 
				
			||||||
                               "reboot      - System Reboot\n"
 | 
					 | 
				
			||||||
                               "netinfo     - WiFi Info\n"
 | 
					 | 
				
			||||||
                               "formatPDS   - Format Persistence EEPROM Data\n"
 | 
					 | 
				
			||||||
                               "formatCFG   - Format Configuration EEPROM Data\n"
 | 
					 | 
				
			||||||
                               "checkEE     - Check EEPROM with checksum\n"
 | 
					 | 
				
			||||||
                               "dumpEE1k    - dump the first 1kb of EEPROM to Serial\n"
 | 
					 | 
				
			||||||
                               "dumpEE      - dump the whole EPPROM to Serial\n"
 | 
					 | 
				
			||||||
                               "killEE      - kill the first 1024 byte of EEPROM\n"
 | 
					 | 
				
			||||||
                               "zeroEE      - zero the first 1024 byte of EEPROM\n"
 | 
					 | 
				
			||||||
                               "resetPageEE - Reset the PersistenceData Page\n"
 | 
					 | 
				
			||||||
                               "dumpCFG     - print Config struct\n"
 | 
					 | 
				
			||||||
                               "dumpPDS     - print PersistanceStruct\n"
 | 
					 | 
				
			||||||
                               "saveEE      - save EE-Data\n"
 | 
					 | 
				
			||||||
                               "showdtc     - Show all DTCs\n"
 | 
					 | 
				
			||||||
                               "dumpGlobals - print globals\n";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum DebugStatus_e
 | 
					typedef enum DebugStatus_e
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -52,8 +36,14 @@ const char sDebugPorts[dbg_cntElements][7] = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern DebugStatus_t DebuggerStatus[dbg_cntElements];
 | 
					extern DebugStatus_t DebuggerStatus[dbg_cntElements];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum LogLevel
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    LOG_INFO,
 | 
				
			||||||
 | 
					    LOG_WARN,
 | 
				
			||||||
 | 
					    LOG_ERROR
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void initDebugger();
 | 
					void initDebugger();
 | 
				
			||||||
void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data);
 | 
					 | 
				
			||||||
void Debug_pushMessage(const char *format, ...);
 | 
					void Debug_pushMessage(const char *format, ...);
 | 
				
			||||||
void SetDebugportStatus(DebugPorts_t port, DebugStatus_t status);
 | 
					void SetDebugportStatus(DebugPorts_t port, DebugStatus_t status);
 | 
				
			||||||
void Debug_Process();
 | 
					void Debug_Process();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ typedef struct Globals_s
 | 
				
			|||||||
  int loadvoltage_mV = 0;
 | 
					  int loadvoltage_mV = 0;
 | 
				
			||||||
  int battery_level = 0;
 | 
					  int battery_level = 0;
 | 
				
			||||||
  bool timer_disabled = false;
 | 
					  bool timer_disabled = false;
 | 
				
			||||||
 | 
					  bool toggle_wifi = false;
 | 
				
			||||||
} Globals_t;
 | 
					} Globals_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern Globals_t globals; /**< Global variable struct */
 | 
					extern Globals_t globals; /**< Global variable struct */
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								Software/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Software/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "name": "pio-build-tools",
 | 
				
			||||||
 | 
					  "private": true,
 | 
				
			||||||
 | 
					  "devDependencies": {
 | 
				
			||||||
 | 
					    "html-minifier": "^4.0.0",
 | 
				
			||||||
 | 
					    "terser": "^5.0.0",
 | 
				
			||||||
 | 
					    "clean-css-cli": "^5.0.0"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -12,22 +12,15 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "debugger.h"
 | 
					#include "debugger.h"
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					#include <functional>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
#include "utilities.h"
 | 
					#include "utilities.h"
 | 
				
			||||||
#include <pgmspace.h>
 | 
					#include <pgmspace.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DebugStatus_t DebuggerStatus[dbg_cntElements];
 | 
					DebugStatus_t DebuggerStatus[dbg_cntElements];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Funktionszeiger
 | 
					void processCmdDebug(String command);
 | 
				
			||||||
typedef void (*CommandFunction)();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Struktur zur Zuordnung von Commands zu Funktionen
 | 
					 | 
				
			||||||
struct CommandMapping
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    const char *command;
 | 
					 | 
				
			||||||
    CommandFunction function;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void processCmdDebug(const char *command);
 | 
					 | 
				
			||||||
void Debug_formatCFG();
 | 
					void Debug_formatCFG();
 | 
				
			||||||
void Debug_formatPersistence();
 | 
					void Debug_formatPersistence();
 | 
				
			||||||
void Debug_printSystemInfo();
 | 
					void Debug_printSystemInfo();
 | 
				
			||||||
@@ -39,93 +32,9 @@ void Debug_ShowDTCs();
 | 
				
			|||||||
void Debug_dumpGlobals();
 | 
					void Debug_dumpGlobals();
 | 
				
			||||||
void Debug_printHelp();
 | 
					void Debug_printHelp();
 | 
				
			||||||
void Debug_Reboot();
 | 
					void Debug_Reboot();
 | 
				
			||||||
 | 
					void Debug_setBatteryType(int batterytype);
 | 
				
			||||||
const char *uint32_to_binary_string(uint32_t num);
 | 
					const char *uint32_to_binary_string(uint32_t num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Adapter-Functions for Debug-Commands
 | 
					 | 
				
			||||||
void adapterCheckEEPOM() { Debug_CheckEEPOM(false); }
 | 
					 | 
				
			||||||
void adapterCheckEEPOMFix() { Debug_CheckEEPOM(true); }
 | 
					 | 
				
			||||||
void adapterDumpEEPROM1k() { dumpEEPROM(0, 1024); }
 | 
					 | 
				
			||||||
void adapterDumpEEPROMAll() { dumpEEPROM(0, EEPROM_SIZE_BYTES); }
 | 
					 | 
				
			||||||
void adapterKillEEPROM() { writeSequentialToEEPROM(0, 1024); }
 | 
					 | 
				
			||||||
void adapterZeroEEPROM() { writeZeroToEEPROM(0, 1024); }
 | 
					 | 
				
			||||||
void adapterResetPageEEPROM() { MovePersistencePage_EEPROM(true); }
 | 
					 | 
				
			||||||
void adapterSaveEEPROM() { globals.requestEEAction = EE_ALL_SAVE; }
 | 
					 | 
				
			||||||
void adapterSetDebugPort() { SetDebugportStatus(dbg_Serial, enabled); }
 | 
					 | 
				
			||||||
void adapterCritDTC() { MaintainDTC(DTC_FAKE_DTC_CRIT, true, millis()); }
 | 
					 | 
				
			||||||
void adapterWarnDTC() { MaintainDTC(DTC_FAKE_DTC_WARN, true, millis()); }
 | 
					 | 
				
			||||||
void adapterInfoDTC() { MaintainDTC(DTC_FAKE_DTC_INFO, true, millis()); }
 | 
					 | 
				
			||||||
void adapterNotifyError() { Websocket_PushNotification("Debug Error Notification", error); }
 | 
					 | 
				
			||||||
void adapterNotifyWarning() { Websocket_PushNotification("Debug Warning Notification", warning); }
 | 
					 | 
				
			||||||
void adapterNotifySuccess() { Websocket_PushNotification("Debug Success Notification", success); }
 | 
					 | 
				
			||||||
void adapterNotifyInfo() { Websocket_PushNotification("Debug Info Notification", info); }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Definition der Command-Mapping-Tabelle
 | 
					 | 
				
			||||||
const CommandMapping commandMappings[] = {
 | 
					 | 
				
			||||||
    {"help", Debug_printHelp},
 | 
					 | 
				
			||||||
    {"reboot", Debug_Reboot},
 | 
					 | 
				
			||||||
    {"sysinfo", Debug_printSystemInfo},
 | 
					 | 
				
			||||||
    {"netinfo", Debug_printWifiInfo},
 | 
					 | 
				
			||||||
    {"formatCFG", Debug_formatCFG},
 | 
					 | 
				
			||||||
    {"formatPDS", Debug_formatPersistence},
 | 
					 | 
				
			||||||
    {"checkEE", adapterCheckEEPOM},
 | 
					 | 
				
			||||||
    {"checkEEfix", adapterCheckEEPOMFix},
 | 
					 | 
				
			||||||
    {"dumpEE1k", adapterDumpEEPROM1k},
 | 
					 | 
				
			||||||
    {"dumpEE", adapterDumpEEPROMAll},
 | 
					 | 
				
			||||||
    {"killEE", adapterKillEEPROM},
 | 
					 | 
				
			||||||
    {"zeroEE", adapterZeroEEPROM},
 | 
					 | 
				
			||||||
    {"resetPageEE", adapterResetPageEEPROM},
 | 
					 | 
				
			||||||
    {"dumpCFG", Debug_dumpConfig},
 | 
					 | 
				
			||||||
    {"dumpPDS", Debug_dumpPersistance},
 | 
					 | 
				
			||||||
    {"saveEE", adapterSaveEEPROM},
 | 
					 | 
				
			||||||
    {"dumpGlobals", Debug_dumpGlobals},
 | 
					 | 
				
			||||||
    {"sdbg", adapterSetDebugPort},
 | 
					 | 
				
			||||||
    {"dtc_show", Debug_ShowDTCs},
 | 
					 | 
				
			||||||
    {"dtc_clear", ClearAllDTC},
 | 
					 | 
				
			||||||
    {"dtc_crit", adapterCritDTC},
 | 
					 | 
				
			||||||
    {"dtc_warn", adapterWarnDTC},
 | 
					 | 
				
			||||||
    {"dtc_info", adapterInfoDTC},
 | 
					 | 
				
			||||||
    {"notify_error", adapterNotifyError},
 | 
					 | 
				
			||||||
    {"notify_warning", adapterNotifyWarning},
 | 
					 | 
				
			||||||
    {"notify_success", adapterNotifySuccess},
 | 
					 | 
				
			||||||
    {"notify_info", adapterNotifyInfo},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const size_t NUM_COMMANDS = sizeof(commandMappings) / sizeof(commandMappings[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const char helpText[][64] PROGMEM = {
 | 
					 | 
				
			||||||
    "help           - Print this help text",
 | 
					 | 
				
			||||||
    "sysinfo        - System Info",
 | 
					 | 
				
			||||||
    "reboot         - System Reboot",
 | 
					 | 
				
			||||||
    "netinfo        - WiFi Info",
 | 
					 | 
				
			||||||
    "formatPDS      - Format Persistence EEPROM Data",
 | 
					 | 
				
			||||||
    "formatCFG      - Format Configuration EEPROM Data",
 | 
					 | 
				
			||||||
    "checkEE        - Check EEPROM with checksum",
 | 
					 | 
				
			||||||
    "checkEEfix     - Check and fix EEPROM with checksum",
 | 
					 | 
				
			||||||
    "dumpEE1k       - Dump the first 1kb of EEPROM to Serial",
 | 
					 | 
				
			||||||
    "dumpEE         - Dump the whole EEPROM to Serial",
 | 
					 | 
				
			||||||
    "killEE         - Kill the first 1024 bytes of EEPROM",
 | 
					 | 
				
			||||||
    "zeroEE         - Zero the first 1024 bytes of EEPROM",
 | 
					 | 
				
			||||||
    "resetPageEE    - Reset the PersistenceData Page",
 | 
					 | 
				
			||||||
    "dumpCFG        - Print Config struct",
 | 
					 | 
				
			||||||
    "dumpPDS        - Print PersistenceStruct",
 | 
					 | 
				
			||||||
    "saveEE         - Save EE-Data",
 | 
					 | 
				
			||||||
    "dumpGlobals    - Print globals",
 | 
					 | 
				
			||||||
    "sdbg           - Set debug port status",
 | 
					 | 
				
			||||||
    "dtc_show       - Show all DTCs",
 | 
					 | 
				
			||||||
    "dtc_clear      - Clear all DTCs",
 | 
					 | 
				
			||||||
    "dtc_crit       - Maintain critical DTC",
 | 
					 | 
				
			||||||
    "dtc_warn       - Maintain warning DTC",
 | 
					 | 
				
			||||||
    "dtc_info       - Maintain info DTC",
 | 
					 | 
				
			||||||
    "notify_error   - Send error notification",
 | 
					 | 
				
			||||||
    "notify_warning - Send warning notification",
 | 
					 | 
				
			||||||
    "notify_success - Send success notification",
 | 
					 | 
				
			||||||
    "notify_info    - Send info notification"};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const size_t NUM_HELP_LINES = sizeof(helpText) / sizeof(helpText[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Überprüfen, ob die Anzahl der Commands und Hilfetext-Zeilen übereinstimmen
 | 
					 | 
				
			||||||
static_assert(NUM_COMMANDS == NUM_HELP_LINES, "Number of commands and help text lines do not match!");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Initializes the debugger by setting the initial status for different debug ports.
 | 
					 * @brief Initializes the debugger by setting the initial status for different debug ports.
 | 
				
			||||||
 *        Serial debug output is turned off.
 | 
					 *        Serial debug output is turned off.
 | 
				
			||||||
@@ -180,7 +89,7 @@ void Debug_Process()
 | 
				
			|||||||
            InputProcessed = CMD_ABORT;
 | 
					            InputProcessed = CMD_ABORT;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case 0x21 ... 0x7E: // it's a real letter or sign and not some control-chars
 | 
					        case 0x20 ... 0x7E: // it's a real letter or sign and not some control-chars
 | 
				
			||||||
            inputBuffer[inputCnt] = inputChar;
 | 
					            inputBuffer[inputCnt] = inputChar;
 | 
				
			||||||
            inputCnt++;
 | 
					            inputCnt++;
 | 
				
			||||||
            Serial.write(inputChar);
 | 
					            Serial.write(inputChar);
 | 
				
			||||||
@@ -191,10 +100,10 @@ void Debug_Process()
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Check for input buffer overflow
 | 
					        // Check for input buffer overflow
 | 
				
			||||||
        if (inputCnt > sizeof(inputBuffer))
 | 
					        if (inputCnt >= sizeof(inputBuffer) - 1)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            inputBuffer[sizeof(inputBuffer) - 1] = '\0';
 | 
				
			||||||
            inputCnt = 0;
 | 
					            inputCnt = 0;
 | 
				
			||||||
            inputBuffer[sizeof(inputBuffer) - 1] = 0; // terminate the String
 | 
					 | 
				
			||||||
            InputProcessed = CMD_OVERFLOW;
 | 
					            InputProcessed = CMD_OVERFLOW;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -207,7 +116,7 @@ void Debug_Process()
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case CMD_COMPLETE:
 | 
					    case CMD_COMPLETE:
 | 
				
			||||||
        processCmdDebug(inputBuffer);
 | 
					        processCmdDebug(String(inputBuffer));
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case CMD_OVERFLOW:
 | 
					    case CMD_OVERFLOW:
 | 
				
			||||||
@@ -244,6 +153,27 @@ void SetDebugportStatus(DebugPorts_t port, DebugStatus_t status)
 | 
				
			|||||||
        Debug_pushMessage("Enabled DebugPort %s\n", sDebugPorts[port]);
 | 
					        Debug_pushMessage("Enabled DebugPort %s\n", sDebugPorts[port]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Debug_log(LogLevel level, const char *format, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ((DebuggerStatus[dbg_Serial] == enabled) || (DebuggerStatus[dbg_Webui] == enabled))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        char buff[128];
 | 
				
			||||||
 | 
					        va_list arg;
 | 
				
			||||||
 | 
					        va_start(arg, format);
 | 
				
			||||||
 | 
					        vsnprintf(buff, sizeof(buff), format, arg);
 | 
				
			||||||
 | 
					        va_end(arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (DebuggerStatus[dbg_Serial] == enabled)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Serial.print(buff);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (DebuggerStatus[dbg_Webui] == enabled)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Websocket_PushLiveDebug(String(buff));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Pushes a formatted debug message to the enabled debug ports (Serial or WebUI).
 | 
					 * @brief Pushes a formatted debug message to the enabled debug ports (Serial or WebUI).
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -277,27 +207,134 @@ void Debug_pushMessage(const char *format, ...)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					// === splitArgs Helper ===
 | 
				
			||||||
 * @brief Processes a debug command and performs corresponding actions.
 | 
					std::vector<String> splitArgs(const String &input)
 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @param command The debug command to be processed.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void processCmdDebug(const char *command)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    bool commandFound = false;
 | 
					    std::vector<String> tokens;
 | 
				
			||||||
    for (size_t i = 0; i < NUM_COMMANDS; ++i)
 | 
					    int start = 0, end = 0;
 | 
				
			||||||
 | 
					    while ((end = input.indexOf(' ', start)) != -1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (strcmp(command, commandMappings[i].command) == 0)
 | 
					        tokens.push_back(input.substring(start, end));
 | 
				
			||||||
 | 
					        start = end + 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (start < input.length())
 | 
				
			||||||
 | 
					        tokens.push_back(input.substring(start));
 | 
				
			||||||
 | 
					    return tokens;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// === getArg helper ===
 | 
				
			||||||
 | 
					String getArg(const std::vector<String> &args, size_t index, const String &defaultVal = "")
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (index < args.size())
 | 
				
			||||||
 | 
					        return args[index];
 | 
				
			||||||
 | 
					    return defaultVal;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// === Command Handler Map ===
 | 
				
			||||||
 | 
					typedef std::function<void(const String &args)> DebugCmdHandler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const std::map<String, DebugCmdHandler> &getCmdMap()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static const std::map<String, DebugCmdHandler> cmdMap = {
 | 
				
			||||||
 | 
					        {"help", [](const String &)
 | 
				
			||||||
         {
 | 
					         {
 | 
				
			||||||
            commandMappings[i].function();
 | 
					             Debug_log(LOG_INFO, "Available commands:\n");
 | 
				
			||||||
            commandFound = true;
 | 
					             for (const auto &entry : getCmdMap())
 | 
				
			||||||
            break;
 | 
					                 Debug_log(LOG_INFO, " - %s\n", entry.first.c_str());
 | 
				
			||||||
        }
 | 
					         }},
 | 
				
			||||||
    }
 | 
					        {"sysinfo", [](const String &)
 | 
				
			||||||
    if (!commandFound)
 | 
					         { Debug_printSystemInfo(); }},
 | 
				
			||||||
 | 
					        {"netinfo", [](const String &)
 | 
				
			||||||
 | 
					         { Debug_printWifiInfo(); }},
 | 
				
			||||||
 | 
					        {"formatCFG", [](const String &)
 | 
				
			||||||
 | 
					         { Debug_formatCFG(); }},
 | 
				
			||||||
 | 
					        {"formatPDS", [](const String &)
 | 
				
			||||||
 | 
					         { Debug_formatPersistence(); }},
 | 
				
			||||||
 | 
					        {"checkEE", [](const String &)
 | 
				
			||||||
 | 
					         { Debug_CheckEEPOM(false); }},
 | 
				
			||||||
 | 
					        {"checkEEfix", [](const String &)
 | 
				
			||||||
 | 
					         { Debug_CheckEEPOM(true); }},
 | 
				
			||||||
 | 
					        {"dumpEE1k", [](const String &)
 | 
				
			||||||
 | 
					         { dumpEEPROM(0, 1024); }},
 | 
				
			||||||
 | 
					        {"dumpEE", [](const String &args)
 | 
				
			||||||
         {
 | 
					         {
 | 
				
			||||||
        Debug_pushMessage("unknown Command\n");
 | 
					             int start = 0, len = EEPROM_SIZE_BYTES;
 | 
				
			||||||
 | 
					             auto tokens = splitArgs(args);
 | 
				
			||||||
 | 
					             if (tokens.size() >= 2)
 | 
				
			||||||
 | 
					             {
 | 
				
			||||||
 | 
					                 start = tokens[0].toInt();
 | 
				
			||||||
 | 
					                 len = tokens[1].toInt();
 | 
				
			||||||
             }
 | 
					             }
 | 
				
			||||||
 | 
					             dumpEEPROM(start, len);
 | 
				
			||||||
 | 
					         }},
 | 
				
			||||||
 | 
					        {"resetPageEE", [](const String &)
 | 
				
			||||||
 | 
					         { MovePersistencePage_EEPROM(true); }},
 | 
				
			||||||
 | 
					        {"dumpCFG", [](const String &)
 | 
				
			||||||
 | 
					         { Debug_dumpConfig(); }},
 | 
				
			||||||
 | 
					        {"dumpPDS", [](const String &)
 | 
				
			||||||
 | 
					         { Debug_dumpPersistance(); }},
 | 
				
			||||||
 | 
					        {"saveEE", [](const String &)
 | 
				
			||||||
 | 
					         { globals.requestEEAction = EE_ALL_SAVE; }},
 | 
				
			||||||
 | 
					        {"dumpGlobals", [](const String &)
 | 
				
			||||||
 | 
					         { Debug_dumpGlobals(); }},
 | 
				
			||||||
 | 
					        {"sdbg", [](const String &)
 | 
				
			||||||
 | 
					         { SetDebugportStatus(dbg_Serial, enabled); }},
 | 
				
			||||||
 | 
					        {"dtc_show", [](const String &)
 | 
				
			||||||
 | 
					         { Debug_ShowDTCs(); }},
 | 
				
			||||||
 | 
					        {"dtc_clear", [](const String &)
 | 
				
			||||||
 | 
					         { ClearAllDTC(); }},
 | 
				
			||||||
 | 
					        {"dtc_crit", [](const String &)
 | 
				
			||||||
 | 
					         { MaintainDTC(DTC_FAKE_DTC_CRIT, true, millis()); }},
 | 
				
			||||||
 | 
					        {"dtc_warn", [](const String &)
 | 
				
			||||||
 | 
					         { MaintainDTC(DTC_FAKE_DTC_WARN, true, millis()); }},
 | 
				
			||||||
 | 
					        {"dtc_info", [](const String &)
 | 
				
			||||||
 | 
					         { MaintainDTC(DTC_FAKE_DTC_INFO, true, millis()); }},
 | 
				
			||||||
 | 
					        {"notify_error", [](const String &)
 | 
				
			||||||
 | 
					         { Websocket_PushNotification("Debug Error Notification", error); }},
 | 
				
			||||||
 | 
					        {"notify_warning", [](const String &)
 | 
				
			||||||
 | 
					         { Websocket_PushNotification("Debug Warning Notification", warning); }},
 | 
				
			||||||
 | 
					        {"notify_success", [](const String &)
 | 
				
			||||||
 | 
					         { Websocket_PushNotification("Debug Success Notification", success); }},
 | 
				
			||||||
 | 
					        {"notify_info", [](const String &)
 | 
				
			||||||
 | 
					         { Websocket_PushNotification("Debug Info Notification", info); }},
 | 
				
			||||||
 | 
					        {"reboot", [](const String &)
 | 
				
			||||||
 | 
					         { Debug_Reboot(); }},
 | 
				
			||||||
 | 
					        {"toggle_wifi", [](const String &)
 | 
				
			||||||
 | 
					         { globals.toggle_wifi = true; }},
 | 
				
			||||||
 | 
					        {"dtc_add", [](const String &args)
 | 
				
			||||||
 | 
					         {
 | 
				
			||||||
 | 
					             auto tokens = splitArgs(args);
 | 
				
			||||||
 | 
					             if (!tokens.empty())
 | 
				
			||||||
 | 
					             {
 | 
				
			||||||
 | 
					                 int code = tokens[0].toInt();
 | 
				
			||||||
 | 
					                 MaintainDTC((DTCNum_t)code, true, millis());
 | 
				
			||||||
 | 
					             }
 | 
				
			||||||
 | 
					         }},
 | 
				
			||||||
 | 
					        {"set_battery", [](const String &args)
 | 
				
			||||||
 | 
					         {
 | 
				
			||||||
 | 
					             auto tokens = splitArgs(args);
 | 
				
			||||||
 | 
					             if (!tokens.empty())
 | 
				
			||||||
 | 
					             {
 | 
				
			||||||
 | 
					                 int batteryType = tokens[0].toInt();
 | 
				
			||||||
 | 
					                 Debug_setBatteryType(batteryType);
 | 
				
			||||||
 | 
					             }
 | 
				
			||||||
 | 
					         }}};
 | 
				
			||||||
 | 
					    return cmdMap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void processCmdDebug(String input)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    input.trim();
 | 
				
			||||||
 | 
					    int splitIndex = input.indexOf(' ');
 | 
				
			||||||
 | 
					    String command = splitIndex == -1 ? input : input.substring(0, splitIndex);
 | 
				
			||||||
 | 
					    String args = splitIndex == -1 ? "" : input.substring(splitIndex + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto &cmdMap = getCmdMap();
 | 
				
			||||||
 | 
					    auto it = cmdMap.find(command);
 | 
				
			||||||
 | 
					    if (it != cmdMap.end())
 | 
				
			||||||
 | 
					        it->second(args);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        Debug_log(LOG_WARN, "Unknown command: '%s'\n", command.c_str());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -414,6 +451,26 @@ void Debug_printWifiInfo()
 | 
				
			|||||||
    Debug_pushMessage("WiFi AP Pw: %s\n", buffer);
 | 
					    Debug_pushMessage("WiFi AP Pw: %s\n", buffer);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Debug_setBatteryType(int batterytype)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (batterytype)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    case 2:
 | 
				
			||||||
 | 
					        ConfigData.batteryType = BATTERY_LIPO_2S;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case 3:
 | 
				
			||||||
 | 
					        ConfigData.batteryType = BATTERY_LIPO_3S;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        ConfigData.batteryType = BATTERY_UNDEFINED;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Debug_pushMessage("Set BatteryType to : %d\n", batterytype);
 | 
				
			||||||
 | 
					    globals.requestEEAction = EE_CFG_SAVE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Checks the EEPROM data integrity by calculating and comparing checksums.
 | 
					 * @brief Checks the EEPROM data integrity by calculating and comparing checksums.
 | 
				
			||||||
 *        Prints the result to the debug output.
 | 
					 *        Prints the result to the debug output.
 | 
				
			||||||
@@ -471,7 +528,7 @@ void Debug_ShowDTCs()
 | 
				
			|||||||
    char buff_active[9];
 | 
					    char buff_active[9];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Header for the DTC display
 | 
					    // Header for the DTC display
 | 
				
			||||||
    Debug_pushMessage("\n      timestamp | DTC-Nr. |   status | debugval\n");
 | 
					    Debug_pushMessage("\n      timestamp | DTC-Nr. |   status | severity\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Iterate through DTCStorage and display each entry
 | 
					    // Iterate through DTCStorage and display each entry
 | 
				
			||||||
    for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++)
 | 
					    for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++)
 | 
				
			||||||
@@ -495,25 +552,11 @@ void Debug_ShowDTCs()
 | 
				
			|||||||
                strcpy(buff_active, "none");
 | 
					                strcpy(buff_active, "none");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Display DTC information
 | 
					            // Display DTC information
 | 
				
			||||||
            Debug_pushMessage("%s   %7d   %8s   %8d\n", buff_timestamp, DTCStorage[i].Number, buff_active, DTCStorage[i].debugVal);
 | 
					            Debug_pushMessage("%s   %7d   %8s   %8d\n", buff_timestamp, DTCStorage[i].Number, buff_active);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @brief Prints the help information stored in PROGMEM.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void Debug_printHelp()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    char buffer[64];
 | 
					 | 
				
			||||||
    for (size_t i = 0; i < NUM_HELP_LINES; ++i)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        strncpy_P(buffer, helpText[i], sizeof(buffer));
 | 
					 | 
				
			||||||
        buffer[sizeof(buffer) - 1] = '\0'; // Sicherstellen, dass der String nullterminiert ist
 | 
					 | 
				
			||||||
        Serial.println(buffer);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Initiates a system reboot by setting the system status to shutdown.
 | 
					 * @brief Initiates a system reboot by setting the system status to shutdown.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,4 +7,5 @@ void initGlobals()
 | 
				
			|||||||
  globals.systemStatus = sysStat_Startup;
 | 
					  globals.systemStatus = sysStat_Startup;
 | 
				
			||||||
  globals.requestEEAction = EE_IDLE;
 | 
					  globals.requestEEAction = EE_IDLE;
 | 
				
			||||||
  globals.systemStatustxt[0] = 0;
 | 
					  globals.systemStatustxt[0] = 0;
 | 
				
			||||||
 | 
					  globals.toggle_wifi = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -101,28 +101,42 @@ void LoRa_Process()
 | 
				
			|||||||
    int receivedSize = 0;
 | 
					    int receivedSize = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (SerialLoRa.available() && !packageReceived)
 | 
					    while (SerialLoRa.available() && !packageReceived)
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (bufferPtr < sizeof(packageInput) - 1)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        char c = SerialLoRa.read();
 | 
					        char c = SerialLoRa.read();
 | 
				
			||||||
            packageInput[bufferPtr] = c;
 | 
					
 | 
				
			||||||
            packageInput[bufferPtr + 1] = '\0'; // always terminate string
 | 
					        // CR ignorieren (falls CRLF)
 | 
				
			||||||
 | 
					        if (c == '\r')
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (c == '\n')
 | 
					        if (c == '\n')
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
                packageReceived = true;
 | 
					            // Zeilenende: String sauber terminieren, Größe setzen
 | 
				
			||||||
 | 
					            packageInput[bufferPtr] = '\0';
 | 
				
			||||||
            receivedSize = bufferPtr;
 | 
					            receivedSize = bufferPtr;
 | 
				
			||||||
            bufferPtr = 0;
 | 
					            bufferPtr = 0;
 | 
				
			||||||
 | 
					            packageReceived = true;
 | 
				
			||||||
            Debug_pushMessage("Got LoRa UART: %s\n", packageInput);
 | 
					            Debug_pushMessage("Got LoRa UART: %s\n", packageInput);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
            else if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == ' ' || c == ',' || c == '.')) // Accept numbers, uppercase letters, and some special chars
 | 
					
 | 
				
			||||||
 | 
					        // Optional: in Uppercase wandeln (macht Kommandos robust)
 | 
				
			||||||
 | 
					        if (c >= 'a' && c <= 'z')
 | 
				
			||||||
 | 
					            c = (char)(c - 'a' + 'A');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Erlaubte Zeichen (Ziffern, Großbuchstaben, Space, Komma, Punkt, Semikolon)
 | 
				
			||||||
 | 
					        bool allowed =
 | 
				
			||||||
 | 
					            (c >= '0' && c <= '9') ||
 | 
				
			||||||
 | 
					            (c >= 'A' && c <= 'Z') ||
 | 
				
			||||||
 | 
					            (c == ' ' || c == ',' || c == '.' || c == ';');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (allowed)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
                bufferPtr++;
 | 
					            if (bufferPtr < sizeof(packageInput) - 1)
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Debug_pushMessage("Invalid character received: %c\n", c);
 | 
					                packageInput[bufferPtr++] = c;
 | 
				
			||||||
            }
 | 
					                packageInput[bufferPtr] = '\0'; // immer NUL-terminiert halten
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -130,9 +144,15 @@ void LoRa_Process()
 | 
				
			|||||||
                bufferPtr = 0;
 | 
					                bufferPtr = 0;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug_pushMessage("Invalid character received: %c\n", c);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (packageReceived)
 | 
					    if (packageReceived)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        // Hinweis: receivedSize ist jetzt strlen(packageInput), ohne \n/\r
 | 
				
			||||||
        Parse_LoRa_UartCommand(packageInput, receivedSize);
 | 
					        Parse_LoRa_UartCommand(packageInput, receivedSize);
 | 
				
			||||||
        packageReceived = false;
 | 
					        packageReceived = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -244,41 +264,57 @@ void printParameters(struct Configuration configuration)
 | 
				
			|||||||
    Serial.println("----------------------------------------");
 | 
					    Serial.println("----------------------------------------");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef FEATURE_ENABLE_UARTLORA
 | 
					#ifdef FEATURE_ENABLE_UARTLORA
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void rstrip(char *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    size_t n = strlen(s);
 | 
				
			||||||
 | 
					    while (n && (s[n - 1] == '\r' || s[n - 1] == '\n' || isspace((unsigned char)s[n - 1])))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        s[--n] = '\0';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static void lstrip(char *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    size_t i = 0, n = strlen(s);
 | 
				
			||||||
 | 
					    while (i < n && isspace((unsigned char)s[i]))
 | 
				
			||||||
 | 
					        i++;
 | 
				
			||||||
 | 
					    if (i)
 | 
				
			||||||
 | 
					        memmove(s, s + i, n - i + 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Parse_LoRa_UartCommand(char input[], int size)
 | 
					void Parse_LoRa_UartCommand(char input[], int size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Debug_pushMessage("Start parsing, size: %d\n", size);
 | 
					    Debug_pushMessage("Start parsing, size: %d\n", size);
 | 
				
			||||||
    char delimiter[] = ";";
 | 
					
 | 
				
			||||||
 | 
					    // Auf mehreren Delimitern splitten: ;, CR, LF, Tabs/Spaces
 | 
				
			||||||
 | 
					    const char *delims = ";\r\n\t ";
 | 
				
			||||||
    char *ptr;
 | 
					    char *ptr;
 | 
				
			||||||
    char command[8];
 | 
					 | 
				
			||||||
    char value[8];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ptr = strtok(input, delimiter);
 | 
					    // erstes Token (Kommando)
 | 
				
			||||||
 | 
					    ptr = strtok(input, delims);
 | 
				
			||||||
    ptr = strtok(input, delimiter);
 | 
					    if (!ptr)
 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (ptr != NULL)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        strncpy(command, ptr, sizeof(command) - 1); // Platz für Nullterminator lassen
 | 
					        Debug_pushMessage("No command token\n");
 | 
				
			||||||
        command[sizeof(command) - 1] = '\0';        // Nullterminator setzen
 | 
					        return;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        ptr = strtok(NULL, delimiter);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (ptr != NULL)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            strncpy(value, ptr, sizeof(value) - 1); // Platz für Nullterminator lassen
 | 
					 | 
				
			||||||
            value[sizeof(value) - 1] = '\0';        // Nullterminator setzen
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // Wenn ptr NULL ist, setze value auf leeren String
 | 
					 | 
				
			||||||
            value[0] = '\0';
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Hier kannst du den Wert und das Kommando verarbeiten
 | 
					    char command[16];
 | 
				
			||||||
        Debug_pushMessage("Command: %s, Value: %s\n", command, value);
 | 
					    strncpy(command, ptr, sizeof(command) - 1);
 | 
				
			||||||
 | 
					    command[sizeof(command) - 1] = '\0';
 | 
				
			||||||
 | 
					    lstrip(command);
 | 
				
			||||||
 | 
					    rstrip(command);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // zweites Token (optional: Wert)
 | 
				
			||||||
 | 
					    ptr = strtok(NULL, delims);
 | 
				
			||||||
 | 
					    char value[16] = {0};
 | 
				
			||||||
 | 
					    if (ptr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        strncpy(value, ptr, sizeof(value) - 1);
 | 
				
			||||||
 | 
					        value[sizeof(value) - 1] = '\0';
 | 
				
			||||||
 | 
					        lstrip(value);
 | 
				
			||||||
 | 
					        rstrip(value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Debug_pushMessage("Parsed LoRa UART Command: %s  Value: %s\n", command, value);
 | 
					    Debug_pushMessage("Parsed LoRa UART Command: %s  Value: %s\n", command, value);
 | 
				
			||||||
@@ -329,5 +365,9 @@ void Parse_LoRa_UartCommand(char input[], int size)
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        PersistenceData.activeFaction = FACTION_3;
 | 
					        PersistenceData.activeFaction = FACTION_3;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Debug_pushMessage("Unknown command: %s\n", command);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -247,6 +247,13 @@ void loop()
 | 
				
			|||||||
	DTC_Process();
 | 
						DTC_Process();
 | 
				
			||||||
	Debug_Process();
 | 
						Debug_Process();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (globals.toggle_wifi == true)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							globals.toggle_wifi = false;
 | 
				
			||||||
 | 
							toggleWiFiAP();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(FEATURE_ENABLE_LORA) || defined(FEATURE_ENABLE_UARTLORA)
 | 
					#if defined(FEATURE_ENABLE_LORA) || defined(FEATURE_ENABLE_UARTLORA)
 | 
				
			||||||
	LoRa_Process();
 | 
						LoRa_Process();
 | 
				
			||||||
	tmrStatusSender.update();
 | 
						tmrStatusSender.update();
 | 
				
			||||||
@@ -269,10 +276,11 @@ void loop()
 | 
				
			|||||||
			lastStatus = globals.systemStatus;
 | 
								lastStatus = globals.systemStatus;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Transition to Normal status after startup delay
 | 
							// Transition to Normal status after startup delay
 | 
				
			||||||
		if (millis() > STARTUP_DELAY)
 | 
							if (millis() > STARTUP_DELAY_MS)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			globals.systemStatus = sysStat_Normal;
 | 
								globals.systemStatus = sysStat_Normal;
 | 
				
			||||||
			globals.resumeStatus = sysStat_Normal;
 | 
								globals.resumeStatus = sysStat_Normal;
 | 
				
			||||||
 | 
								Debug_pushMessage("sysstat = Normal");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -713,7 +721,7 @@ void ProcessKeyCombos(bool *btnState)
 | 
				
			|||||||
		else if (keyCount_Fac2 == 4 && keyCount_Fac3 == 0)
 | 
							else if (keyCount_Fac2 == 4 && keyCount_Fac3 == 0)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Debug_pushMessage("KeyCombo: Reset Timer\n");
 | 
								Debug_pushMessage("KeyCombo: Reset Timer\n");
 | 
				
			||||||
			if (globals.systemStatus == sysStat_Startup)
 | 
								if (millis() < STARTUP_DELAY_MS)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				OverrideDisplay(5000, "RST ", "    ", "    ");
 | 
									OverrideDisplay(5000, "RST ", "    ", "    ");
 | 
				
			||||||
				PersistenceData.faction_1_timer = 0;
 | 
									PersistenceData.faction_1_timer = 0;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user