Compare commits

..

2 Commits

Author SHA1 Message Date
a849e65f9a improved build script. 2025-06-15 21:17:55 +02:00
b6f9de2894 some tweaks regarding washMode and Debugger 2025-06-15 21:17:32 +02:00
6 changed files with 201 additions and 91 deletions

View File

@ -22,16 +22,22 @@ def ensure_node_tool(package_name, binary_name=None):
os.makedirs(tools_dir, exist_ok=True)
# Wenn Binary schon vorhanden ist, einfach zurückgeben
if os.path.isfile(local_bin):
return local_bin
print(f"🛠️ Installing missing node tool: {package_name}")
# Initialisiere npm, falls noch nicht geschehen
if not os.path.isfile(os.path.join(tools_dir, 'package.json')):
print("🛠️ Initializing local npm project in tools_node...")
print("📦 Initializing local npm project...")
subprocess.run(['npm', 'init', '-y'], cwd=tools_dir, check=True)
# Installiere Tool (idempotent)
try:
subprocess.run(['npm', 'install', package_name], cwd=tools_dir, check=True)
except Exception as e:
print(f"❌ Fehler beim Installieren von {package_name}: {e}")
return binary_name # Fallback: globale binary
return local_bin if os.path.isfile(local_bin) else binary_name

View File

@ -33,6 +33,7 @@ typedef struct Globals_s
bool measurementActive; /**< Flag indicating active measurement */
uint32_t measuredPulses; /**< Number of measured pulses */
bool toggle_wifi;
uint16_t isr_debug;
} Globals_t;
extern Globals_t globals; /**< Global variable struct */

View File

@ -25,9 +25,7 @@ void ButtonAction_StartPurge()
void ButtonAction_ToggleWiFi()
{
extern void toggleWiFiAP(bool shutdown = false);
toggleWiFiAP();
globals.toggle_wifi = true;
Debug_pushMessage("Toggling WiFi\n");
}
@ -40,8 +38,9 @@ void ButtonAction_WashMode()
// Liste der Aktionen, sortiert nach Mindest-Haltezeit (ms)
const ButtonActionEntry buttonActions[] = {
{500, LED_RAIN_COLOR, ButtonAction_ToggleMode},
{3500, LED_PURGE_COLOR, ButtonAction_StartPurge},
{6500, LED_WIFI_COLOR, ButtonAction_ToggleWiFi},
{9500, LED_WASH_COLOR, ButtonAction_WashMode}};
{3500, LED_WASH_COLOR, ButtonAction_WashMode},
{6500, LED_PURGE_COLOR, ButtonAction_StartPurge},
{9500, LED_WIFI_COLOR, ButtonAction_ToggleWiFi},
};
const uint8_t buttonActionCount = sizeof(buttonActions) / sizeof(ButtonActionEntry);

View File

@ -15,8 +15,7 @@
#include <map>
#include <functional>
#include <vector>
DebugStatus_t DebuggerStatus[dbg_cntElements];
#include <type_traits>
void processCmdDebug(String command);
void Debug_formatCFG();
@ -32,6 +31,9 @@ void Debug_printHelp();
void Debug_Purge();
void Debug_refillTank();
const char *uint32_to_binary_string(uint32_t num);
template<typename T>
void RegisterDebugPrintAuto(const T* ptr, const String& name, uint32_t interval_ms, uint32_t duration_ms);
void Debug_UpdateWatches();
/**
* @brief Initializes the debugger by setting the initial status for different debug ports.
@ -98,7 +100,8 @@ void Debug_Process()
}
// Check for input buffer overflow
if (inputCnt >= sizeof(inputBuffer) - 1) {
if (inputCnt >= sizeof(inputBuffer) - 1)
{
inputBuffer[sizeof(inputBuffer) - 1] = '\0';
inputCnt = 0;
InputProcessed = CMD_OVERFLOW;
@ -128,7 +131,11 @@ void Debug_Process()
Serial.print(">");
InputProcessed = IDLE;
Debug_UpdateWatches();
}
/**
* @brief Sets the status of a specific debug port (Serial or WebUI).
* Updates the status in the DebuggerStatus array and provides debug messages.
@ -150,8 +157,6 @@ void SetDebugportStatus(DebugPorts_t port, DebugStatus_t status)
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))
@ -248,17 +253,22 @@ void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data)
std::vector<String> splitArgs(const String &input)
{
std::vector<String> tokens;
int start = 0, end = 0;
while ((end = input.indexOf(' ', start)) != -1)
size_t start = 0;
while (true)
{
int end = input.indexOf(' ', start);
if (end == -1) break;
tokens.push_back(input.substring(start, end));
start = end + 1;
start = static_cast<size_t>(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 = "")
{
@ -273,19 +283,28 @@ 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 &) {
{"help", [](const String &)
{
Debug_log(LOG_INFO, "Available commands:\n");
for (const auto &entry : getCmdMap())
Debug_log(LOG_INFO, " - %s\n", entry.first.c_str());
}},
{"sysinfo", [](const String &) { 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) {
{"sysinfo", [](const String &)
{ 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)
{
int start = 0, len = EEPROM_SIZE_BYTES;
auto tokens = splitArgs(args);
if (tokens.size() >= 2)
@ -295,24 +314,42 @@ static const std::map<String, DebugCmdHandler> &getCmdMap()
}
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); }},
{"purge", [](const String &) { Debug_Purge(); }},
{"toggle_wifi", [](const String &) { globals.toggle_wifi = true; }},
{"dtc_add", [](const String &args) {
{"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); }},
{"purge", [](const String &)
{ Debug_Purge(); }},
{"toggle_wifi", [](const String &)
{ globals.toggle_wifi = true; }},
{"dtc_add", [](const String &args)
{
auto tokens = splitArgs(args);
if (!tokens.empty())
{
@ -320,7 +357,12 @@ static const std::map<String, DebugCmdHandler> &getCmdMap()
MaintainDTC((DTCNum_t)code, true, millis());
}
}},
{"tank_refill", [](const String &) { Debug_refillTank(); }},
{"tank_refill", [](const String &)
{ Debug_refillTank(); }},
{"isr_debug", [](const String &)
{
RegisterDebugPrintAuto(&globals.isr_debug, "isr_debug", 100, 20000);
}},
};
return cmdMap;
}
@ -531,7 +573,6 @@ void Debug_ShowDTCs()
}
}
/**
* @brief Start purging for 10 pulses.
*/
@ -579,3 +620,76 @@ const char *uint32_to_binary_string(uint32_t num)
binary_str[j] = '\0'; // Null terminator
return binary_str;
}
DebugStatus_t DebuggerStatus[dbg_cntElements];
struct DebugWatchEntry
{
const void *ptr;
String name;
uint32_t interval_ms;
uint32_t duration_ms;
uint32_t lastPrint_ms;
uint32_t start_ms;
std::function<void(const void*, const String&)> printer;
};
#define MAX_DEBUG_WATCHES 8
DebugWatchEntry debugWatches[MAX_DEBUG_WATCHES];
// === Typabhängige Druckfunktion ===
template<typename T>
void debugPrinterImpl(const void* ptr, const String& name) {
const T* typed = static_cast<const T*>(ptr);
if constexpr (std::is_same<T, bool>::value) {
Debug_pushMessage("%s = %s\n", name.c_str(), *typed ? "true" : "false");
} else if constexpr (std::is_floating_point<T>::value) {
Debug_pushMessage("%s = %.3f\n", name.c_str(), *typed);
} else if constexpr (std::is_signed<T>::value) {
Debug_pushMessage("%s = %ld\n", name.c_str(), static_cast<long>(*typed));
} else if constexpr (std::is_unsigned<T>::value) {
Debug_pushMessage("%s = %lu\n", name.c_str(), static_cast<unsigned long>(*typed));
}
}
// === Automatisches DebugPrint-Register ===
template<typename T>
void RegisterDebugPrintAuto(const T* ptr, const String& name, uint32_t interval_ms, uint32_t duration_ms)
{
for (int i = 0; i < MAX_DEBUG_WATCHES; ++i) {
if (debugWatches[i].ptr == nullptr) {
debugWatches[i] = {
ptr,
name,
interval_ms,
duration_ms,
0,
millis(),
debugPrinterImpl<T>
};
Debug_pushMessage("Registered Watch: %s\n", name.c_str());
return;
}
}
Debug_pushMessage("Debug Watch list full!\n");
}
// Debug-Ausgabe in Debug_Process():
void Debug_UpdateWatches() {
uint32_t now = millis();
for (int i = 0; i < MAX_DEBUG_WATCHES; ++i) {
auto& w = debugWatches[i];
if (!w.ptr) continue;
if (now - w.start_ms >= w.duration_ms) {
Debug_pushMessage("Watch expired: %s\n", w.name.c_str());
w.ptr = nullptr;
continue;
}
if (now - w.lastPrint_ms >= w.interval_ms) {
w.lastPrint_ms = now;
if (w.printer) w.printer(w.ptr, w.name);
}
}
}

View File

@ -29,7 +29,7 @@ uint32_t lubePulseTimestamp = 0;
void RunLubeApp(uint32_t add_milimeters)
{
static tSystem_Status lastSystemStatus = sysStat_Startup;
static uint16_t washModeDistance = 0;
static uint16_t washModeRemainDistance = 0;
// Calculate and update tank percentage
globals.TankPercentage = PersistenceData.tankRemain_microL / (LubeConfig.tankCapacity_ml * 10);
@ -46,7 +46,7 @@ void RunLubeApp(uint32_t add_milimeters)
if (PersistenceData.odometer_mm >= 1000000)
{
PersistenceData.odometer++;
PersistenceData.odometer_mm = 0;
PersistenceData.odometer_mm -= 1000000;
}
// Handle different system statuses
@ -106,7 +106,7 @@ void RunLubeApp(uint32_t add_milimeters)
case sysStat_Wash:
if (lastSystemStatus != globals.systemStatus)
{
washModeDistance = LubeConfig.WashMode_Distance;
washModeRemainDistance = LubeConfig.WashMode_Distance;
strcpy_P(globals.systemStatustxt, PSTR("Wash"));
LEDControl_SetBasic(LED_WASH_COLOR, LED_PATTERN_BREATH);
lastSystemStatus = globals.systemStatus;
@ -118,9 +118,10 @@ void RunLubeApp(uint32_t add_milimeters)
LubePulse();
PersistenceData.TravelDistance_highRes_mm = 0;
if (washModeDistance >= LubeConfig.WashMode_Distance)
if (washModeRemainDistance >= LubeConfig.WashMode_Interval)
{
washModeDistance = washModeDistance - LubeConfig.WashMode_Interval;
washModeRemainDistance -= LubeConfig.WashMode_Interval;
Debug_pushMessage("Wash Distance remain: %d\n", washModeRemainDistance);
}
else
{

View File

@ -43,7 +43,6 @@
#include "button_actions.h"
#include "ledcontrol.h"
#ifdef FEATURE_ENABLE_WIFI_CLIENT
#include <ESP8266WiFiMulti.h>
@ -260,7 +259,8 @@ void loop()
DTC_Process();
Debug_Process();
if (globals.toggle_wifi == true){
if (globals.toggle_wifi == true)
{
globals.toggle_wifi = false;
toggleWiFiAP();
@ -339,12 +339,19 @@ void EEPROMCyclicPDS_callback()
* This ISR is called whenever a pulse is detected from the wheel speed sensor. It increments
* the `wheel_pulse` variable, which is used to track the number of pulses received.
*/
void trigger_ISR()
volatile uint32_t lastTriggerMicros = 0;
void IRAM_ATTR trigger_ISR()
{
uint32_t now = micros();
if (now - lastTriggerMicros < 2500)
return;
lastTriggerMicros = now;
globals.isr_debug++;
wheel_pulse++;
}
#ifdef FEATURE_ENABLE_OLED
/**
* @brief Manages the display content based on the current system status and updates the OLED display.
@ -372,7 +379,19 @@ void Display_Process()
u8x8.setCursor(0, 1);
// Calculate remaining lubrication distance based on system mode
uint32_t DistRemain = globals.systemStatus == sysStat_Normal ? LubeConfig.DistancePerLube_Default : LubeConfig.DistancePerLube_Rain;
uint32_t DistRemain = 0;
switch (globals.systemStatus)
{
case sysStat_Normal:
DistRemain = LubeConfig.DistancePerLube_Default;
break;
case sysStat_Rain:
DistRemain = LubeConfig.DistancePerLube_Rain;
break;
case sysStat_Wash:
DistRemain = LubeConfig.WashMode_Interval;
break;
}
DistRemain = DistRemain - (PersistenceData.TravelDistance_highRes_mm / 1000);
// Display relevant information on the OLED screen based on system status
@ -479,36 +498,6 @@ void SystemShutdown(bool restart)
}
}
void onToggleMode()
{
if (globals.systemStatus == sysStat_Normal)
{
globals.systemStatus = sysStat_Rain;
globals.resumeStatus = sysStat_Rain;
}
else if (globals.systemStatus == sysStat_Rain)
{
globals.systemStatus = sysStat_Normal;
globals.resumeStatus = sysStat_Normal;
}
Debug_pushMessage("Toggling Mode\n");
}
void onStartPurge()
{
globals.systemStatus = sysStat_Purge;
globals.purgePulses = LubeConfig.BleedingPulses;
Debug_pushMessage("Starting Purge\n");
}
void onWashMode()
{
Debug_pushMessage("Wash mode start\n");
// Hier könntest du später gezieltes Nachölen implementieren
}
/**
* @brief Processes the impulses from the wheel speed sensor and converts them into traveled distance.
*