From 3479f04d7e497b0a4f907d2577fbdc0f650d2dd7 Mon Sep 17 00:00:00 2001 From: ewowi Date: Mon, 16 Feb 2026 13:02:24 +0100 Subject: [PATCH 1/4] Add PIR support pio.ini: Latest FastLED Backend ======= - IO: add pin_PIR and use in board_LuxceoMood1XiaoMod (pin 4) - LightsControl: support PIR --- platformio.ini | 6 +-- src/MoonBase/Modules/ModuleIO.h | 4 +- src/MoonLight/Modules/ModuleLightsControl.h | 57 +++++++++++++++------ 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/platformio.ini b/platformio.ini index 9e7336ff..ea0534b0 100644 --- a/platformio.ini +++ b/platformio.ini @@ -57,7 +57,7 @@ build_flags = -D BUILD_TARGET=\"$PIOENV\" -D APP_NAME=\"MoonLight\" ; 🌙 Must only contain characters from [a-zA-Z0-9-_] as this is converted into a filename -D APP_VERSION=\"0.8.1\" ; semver compatible version string - -D APP_DATE=\"20260214\" ; 🌙 + -D APP_DATE=\"20260215\" ; 🌙 -D PLATFORM_VERSION=\"pioarduino-55.03.37\" ; 🌙 make sure it matches with above plaftform @@ -155,9 +155,9 @@ build_flags = -D DRIVERS_STACK_SIZE=4096 ; psramFound() ? 4 * 1024 : 3 * 1024, 4096 is sufficient for now ; -D FASTLED_TESTING ; causes duplicate definition of initSpiHardware(); - workaround: removed implementation in spi_hw_manager_esp32.cpp.hpp - -D FASTLED_BUILD=\"20260212\" + -D FASTLED_BUILD=\"20260216\" lib_deps = - https://github.com/FastLED/FastLED#fcdbb572b3d84394845209f2bcd8fa77c2cb4ee2 ; master 20260215 + https://github.com/FastLED/FastLED#a4ef74eb9cc217e81f49784649d3b0b5f47dc005 ; master 20260216 https://github.com/ewowi/WLED-sync#25f280b5e8e47e49a95282d0b78a5ce5301af4fe ; sourceIP + fftUdp.clear() if arduino >=3 (20251104) ; 💫 currently only enabled on s3 as esp32dev runs over 100% diff --git a/src/MoonBase/Modules/ModuleIO.h b/src/MoonBase/Modules/ModuleIO.h index 48593ab3..9b61062c 100644 --- a/src/MoonBase/Modules/ModuleIO.h +++ b/src/MoonBase/Modules/ModuleIO.h @@ -69,6 +69,7 @@ enum IO_PinUsageEnum { pin_Dig_Input, // Digital Input pin type. May contains some protection circuit pin_Exposed, pin_Reserved, + pin_PIR, // support for PIR (passive infrared) sensor pin_count }; @@ -609,8 +610,9 @@ class ModuleIO : public Module { for (uint8_t gpio : ledPins) pinAssigner.assignPin(gpio, pin_LED); } else if (boardID == board_LuxceoMood1XiaoMod) { newState["maxPower"] = 50; - uint8_t ledPins[] = {1, 2, 3, 4}; + uint8_t ledPins[] = {1, 2, 3}; for (uint8_t gpio : ledPins) pinAssigner.assignPin(gpio, pin_LED); + pinAssigner.assignPin(4, pin_PIR); pinAssigner.assignPin(5, pin_I2C_SDA); pinAssigner.assignPin(6, pin_I2C_SCL); pinAssigner.assignPin(7, pin_SPI_SCK); diff --git a/src/MoonLight/Modules/ModuleLightsControl.h b/src/MoonLight/Modules/ModuleLightsControl.h index 5f88e4a2..21be0083 100644 --- a/src/MoonLight/Modules/ModuleLightsControl.h +++ b/src/MoonLight/Modules/ModuleLightsControl.h @@ -57,6 +57,7 @@ class ModuleLightsControl : public Module { uint8_t pinRelayLightsOn = UINT8_MAX; uint8_t pinPushButtonLightsOn = UINT8_MAX; uint8_t pinToggleButtonLightsOn = UINT8_MAX; + uint8_t pinPIR = UINT8_MAX; ModuleLightsControl(PsychicHttpServer* server, ESP32SvelteKit* sveltekit, FileManager* fileManager, ModuleIO* moduleIO) : Module("lightscontrol", server, sveltekit), // @@ -226,6 +227,7 @@ class ModuleLightsControl : public Module { pinRelayLightsOn = UINT8_MAX; pinPushButtonLightsOn = UINT8_MAX; pinToggleButtonLightsOn = UINT8_MAX; + pinPIR = UINT8_MAX; for (JsonObject pinObject : state.data["pins"].as()) { uint8_t usage = pinObject["usage"]; uint8_t gpio = pinObject["GPIO"]; @@ -253,6 +255,13 @@ class ModuleLightsControl : public Module { EXT_LOGD(ML_TAG, "pinToggleButtonLightsOn found %d", pinToggleButtonLightsOn); } else EXT_LOGE(MB_TAG, "gpio %d not valid", pinToggleButtonLightsOn); + } else if (usage == pin_PIR) { + if (GPIO_IS_VALID_GPIO(gpio)) { + pinPIR = gpio; + pinMode(pinPIR, INPUT_PULLUP); + EXT_LOGD(ML_TAG, "pinPIR found %d", pinPIR); + } else + EXT_LOGE(MB_TAG, "gpio %d not valid", pinPIR); } } // for (int i = 0; i < sizeof(pins); i++) EXT_LOGD(ML_TAG, "pin %d = %d", i, pins[i]); @@ -396,10 +405,10 @@ class ModuleLightsControl : public Module { // see pinPushButtonLightsOn unsigned long lastDebounceTime = 0; static constexpr unsigned long debounceDelay = 50; // 50ms debounce - int lastState = HIGH; + int lastButtonPinState = HIGH; void loop() override { - Module::loop(); + Module::loop(); // requestUIUpdate // process presetLoop uint8_t presetLoop = _state.data["presetLoop"]; if (presetLoop && millis() - lastPresetTime > presetLoop * 1000) { // every presetLoop seconds @@ -446,29 +455,47 @@ class ModuleLightsControl : public Module { } if (pinPushButtonLightsOn != UINT8_MAX) { - int state = digitalRead(pinPushButtonLightsOn); - if ((state != lastState) && ((((millis() - lastDebounceTime) > debounceDelay) || (millis() < lastDebounceTime)))) { + if ((millis() - lastDebounceTime) > debounceDelay || millis() < lastDebounceTime) { + lastDebounceTime = millis(); + int state = digitalRead(pinPushButtonLightsOn); + if (state != lastButtonPinState) { + // Trigger only on button press (HIGH to LOW transition for INPUT_PULLUP) + if (state == LOW) { + JsonDocument doc; + JsonObject newState = doc.to(); + newState["lightsOn"] = !_state.data["lightsOn"]; + update(newState, ModuleState::update, _moduleName); + } + lastButtonPinState = state; + } + } + } + + if (pinToggleButtonLightsOn != UINT8_MAX) { + if (((millis() - lastDebounceTime) > debounceDelay || millis() < lastDebounceTime)) { lastDebounceTime = millis(); - // Trigger only on button press (HIGH to LOW transition for INPUT_PULLUP) - if (state == LOW) { + int state = digitalRead(pinToggleButtonLightsOn); + if (state != lastButtonPinState) { JsonDocument doc; JsonObject newState = doc.to(); newState["lightsOn"] = !_state.data["lightsOn"]; update(newState, ModuleState::update, _moduleName); + lastButtonPinState = state; } - lastState = state; } } - if (pinToggleButtonLightsOn != UINT8_MAX) { - int state = digitalRead(pinToggleButtonLightsOn); - if ((state != lastState) && ((((millis() - lastDebounceTime) > debounceDelay) || (millis() < lastDebounceTime)))) { + if (pinPIR != UINT8_MAX) { + if ((millis() - lastDebounceTime) > debounceDelay || millis() < lastDebounceTime) { lastDebounceTime = millis(); - JsonDocument doc; - JsonObject newState = doc.to(); - newState["lightsOn"] = !_state.data["lightsOn"]; - update(newState, ModuleState::update, _moduleName); - lastState = state; + int state = digitalRead(pinPIR); + bool pirOn = state == HIGH; + if (pirOn != _state.data["lightsOn"]) { + JsonDocument doc; + JsonObject newState = doc.to(); + newState["lightsOn"] = pirOn; + update(newState, ModuleState::update, _moduleName); + } } } From ff1ff5399672650b691afa47e5e38975790cf954 Mon Sep 17 00:00:00 2001 From: ewowi Date: Mon, 16 Feb 2026 14:13:23 +0100 Subject: [PATCH 2/4] PIR fixes and loopxx() virtual function backend ======= main: use loopxx() virtual functions - modules: use loop20ms instead of loopms, add loop1s and loop10s - Module effects: loop1s: set sharedData - Lights control: PIR ffixes --- src/MoonBase/Module.h | 12 +-- src/MoonBase/Modules/ModuleDevices.h | 4 +- src/MoonBase/Modules/ModuleIO.h | 7 +- src/MoonBase/Modules/ModuleTasks.h | 2 +- src/MoonLight/Modules/ModuleDrivers.h | 4 +- src/MoonLight/Modules/ModuleEffects.h | 13 ++- src/MoonLight/Modules/ModuleLightsControl.h | 40 +++++---- src/MoonLight/Modules/ModuleLiveScripts.h | 2 +- src/main.cpp | 97 +++++++++------------ 9 files changed, 88 insertions(+), 93 deletions(-) diff --git a/src/MoonBase/Module.h b/src/MoonBase/Module.h index cde96133..b3d3e331 100644 --- a/src/MoonBase/Module.h +++ b/src/MoonBase/Module.h @@ -108,10 +108,9 @@ class Module : public StatefulService { // any Module that overrides begin() must continue to call Module::begin() (e.g., at the start of its own begin() virtual void begin(); - // any Module that overrides loop() must continue to call Module::loop() (e.g., at the start of its own loop() - virtual void loop() { - // run in sveltekit task - + // run in sveltekit task + virtual void loop() {} + virtual void loop20ms() { // any Module that overrides loop20ms() must continue to call Module::loop20ms() if (requestUIUpdate) { requestUIUpdate = false; // reset the flag EXT_LOGD(ML_TAG, "requestUIUpdate %s", _moduleName); @@ -124,12 +123,13 @@ class Module : public StatefulService { _moduleName); } } + virtual void loop1s() {} + virtual void loop10s() {} void processUpdatedItem(const UpdatedItem& updatedItem, const String& originId) { if (updatedItem.name == "swap") { onReOrderSwap(updatedItem.index[0], updatedItem.index[1]); - if (originId.toInt()) - saveNeeded = true; + if (originId.toInt()) saveNeeded = true; } else { // if (updatedItem.parent[0] != "devices" && updatedItem.parent[0] != "tasks" && updatedItem.name != "core0") EXT_LOGD(ML_TAG, "%s[%d]%s[%d].%s = %s -> %s", updatedItem.parent[0].c_str(), updatedItem.index[0], updatedItem.parent[1].c_str(), updatedItem.index[1], updatedItem.name.c_str(), updatedItem.oldValue.c_str(), updatedItem.value.as().c_str()); if (updatedItem.name != "channel") { // todo: fix the problem at channel, not here... diff --git a/src/MoonBase/Modules/ModuleDevices.h b/src/MoonBase/Modules/ModuleDevices.h index 6311076b..cf3d177b 100644 --- a/src/MoonBase/Modules/ModuleDevices.h +++ b/src/MoonBase/Modules/ModuleDevices.h @@ -116,7 +116,7 @@ class ModuleDevices : public Module { } } - void loop20ms() { + void loop20ms() override { if (!WiFi.localIP() && !ETH.localIP()) return; if (!deviceUDPConnected) return; @@ -124,7 +124,7 @@ class ModuleDevices : public Module { receiveUDP(); // and updateDevices } - void loop10s() { + void loop10s() override { if (!WiFi.localIP() && !ETH.localIP()) return; if (!deviceUDPConnected) { diff --git a/src/MoonBase/Modules/ModuleIO.h b/src/MoonBase/Modules/ModuleIO.h index 9b61062c..ccc1e74f 100644 --- a/src/MoonBase/Modules/ModuleIO.h +++ b/src/MoonBase/Modules/ModuleIO.h @@ -210,6 +210,7 @@ class ModuleIO : public Module { addControlValue(control, "Digital Input"); addControlValue(control, "Exposed"); addControlValue(control, "Reserved"); + addControlValue(control, "PIR ♨️"); control = addControl(rows, "index", "number", 1, 32); // max 32 of one type, e.g 32 led pins control["default"] = UINT8_MAX; @@ -715,9 +716,9 @@ class ModuleIO : public Module { } } - void loop() override { + void loop20ms() override { // run in sveltekit task - Module::loop(); + Module::loop20ms(); if (newBoardID != UINT8_MAX) { setBoardPresetDefaults(newBoardID); // run from sveltekit task @@ -940,7 +941,7 @@ class ModuleIO : public Module { adc_attenuation_t current_readout_current_adc_attenuation = ADC_11db; #endif - void loop1s() { + void loop1s() override { if (_triggerUpdateI2C != UINT8_MAX) { _updateI2CDevices(); _triggerUpdateI2C = UINT8_MAX; diff --git a/src/MoonBase/Modules/ModuleTasks.h b/src/MoonBase/Modules/ModuleTasks.h index 8d174d4b..c0a2ae23 100644 --- a/src/MoonBase/Modules/ModuleTasks.h +++ b/src/MoonBase/Modules/ModuleTasks.h @@ -46,7 +46,7 @@ class ModuleTasks : public Module { } } - void loop1s() { + void loop1s() override { if (!_socket->getConnectedClients()) return; // 🌙 No need for UI tasks if (!WiFi.localIP() && !ETH.localIP()) return; diff --git a/src/MoonLight/Modules/ModuleDrivers.h b/src/MoonLight/Modules/ModuleDrivers.h index 07811ab5..f645a9fc 100644 --- a/src/MoonLight/Modules/ModuleDrivers.h +++ b/src/MoonLight/Modules/ModuleDrivers.h @@ -188,8 +188,8 @@ class ModuleDrivers : public NodeManager { bool initPins = false; - void loop() override { - NodeManager::loop(); + void loop20ms() override { + NodeManager::loop20ms(); if (!initPins) { readPins(); // initially diff --git a/src/MoonLight/Modules/ModuleEffects.h b/src/MoonLight/Modules/ModuleEffects.h index 2733524b..eac5269c 100644 --- a/src/MoonLight/Modules/ModuleEffects.h +++ b/src/MoonLight/Modules/ModuleEffects.h @@ -295,8 +295,8 @@ class ModuleEffects : public NodeManager { return node; } - void loop() override { - NodeManager::loop(); + void loop20ms() override { + NodeManager::loop20ms(); if (triggerResetPreset) { triggerResetPreset = false; @@ -316,6 +316,15 @@ class ModuleEffects : public NodeManager { } } + void loop1s() override { + // set shared data (eg used in scrolling text effect), every second + sharedData.fps = esp32sveltekit.getAnalyticsService()->lps; + sharedData.connectionStatus = (uint8_t)esp32sveltekit.getConnectionStatus(); + sharedData.clientListSize = esp32sveltekit.getServer()->getClientList().size(); + sharedData.connectedClients = esp32sveltekit.getSocket()->getConnectedClients(); + sharedData.activeClients = esp32sveltekit.getSocket()->getActiveClients(); + } + bool triggerResetPreset = false; void onUpdate(const UpdatedItem& updatedItem, const String& originId) override { NodeManager::onUpdate(updatedItem, originId); diff --git a/src/MoonLight/Modules/ModuleLightsControl.h b/src/MoonLight/Modules/ModuleLightsControl.h index 21be0083..33b17f04 100644 --- a/src/MoonLight/Modules/ModuleLightsControl.h +++ b/src/MoonLight/Modules/ModuleLightsControl.h @@ -403,12 +403,16 @@ class ModuleLightsControl : public Module { unsigned long lastPresetTime = 0; // see pinPushButtonLightsOn - unsigned long lastDebounceTime = 0; static constexpr unsigned long debounceDelay = 50; // 50ms debounce - int lastButtonPinState = HIGH; - - void loop() override { - Module::loop(); // requestUIUpdate + unsigned long lastPushDebounceTime = 0; + unsigned long lastToggleDebounceTime = 0; + unsigned long lastPIRDebounceTime = 0; + int lastPushPinState = HIGH; + int lastTogglePinState = HIGH; + int lastPIRPinState = LOW; + + void loop20ms() override { + Module::loop20ms(); // requestUIUpdate // process presetLoop uint8_t presetLoop = _state.data["presetLoop"]; if (presetLoop && millis() - lastPresetTime > presetLoop * 1000) { // every presetLoop seconds @@ -455,10 +459,11 @@ class ModuleLightsControl : public Module { } if (pinPushButtonLightsOn != UINT8_MAX) { - if ((millis() - lastDebounceTime) > debounceDelay || millis() < lastDebounceTime) { - lastDebounceTime = millis(); + if ((millis() - lastPushDebounceTime) > debounceDelay) { + lastPushDebounceTime = millis(); int state = digitalRead(pinPushButtonLightsOn); - if (state != lastButtonPinState) { + if (state != lastPushPinState) { + lastPushPinState = state; // Trigger only on button press (HIGH to LOW transition for INPUT_PULLUP) if (state == LOW) { JsonDocument doc; @@ -466,34 +471,33 @@ class ModuleLightsControl : public Module { newState["lightsOn"] = !_state.data["lightsOn"]; update(newState, ModuleState::update, _moduleName); } - lastButtonPinState = state; } } } if (pinToggleButtonLightsOn != UINT8_MAX) { - if (((millis() - lastDebounceTime) > debounceDelay || millis() < lastDebounceTime)) { - lastDebounceTime = millis(); + if (((millis() - lastToggleDebounceTime) > debounceDelay)) { + lastToggleDebounceTime = millis(); int state = digitalRead(pinToggleButtonLightsOn); - if (state != lastButtonPinState) { + if (state != lastTogglePinState) { + lastTogglePinState = state; JsonDocument doc; JsonObject newState = doc.to(); newState["lightsOn"] = !_state.data["lightsOn"]; update(newState, ModuleState::update, _moduleName); - lastButtonPinState = state; } } } if (pinPIR != UINT8_MAX) { - if ((millis() - lastDebounceTime) > debounceDelay || millis() < lastDebounceTime) { - lastDebounceTime = millis(); + if ((millis() - lastPIRDebounceTime) > debounceDelay) { + lastPIRDebounceTime = millis(); int state = digitalRead(pinPIR); - bool pirOn = state == HIGH; - if (pirOn != _state.data["lightsOn"]) { + if (state != lastPIRPinState) { + lastPIRPinState = state; JsonDocument doc; JsonObject newState = doc.to(); - newState["lightsOn"] = pirOn; + newState["lightsOn"] = state == HIGH; update(newState, ModuleState::update, _moduleName); } } diff --git a/src/MoonLight/Modules/ModuleLiveScripts.h b/src/MoonLight/Modules/ModuleLiveScripts.h index 1723d667..bccc9d23 100644 --- a/src/MoonLight/Modules/ModuleLiveScripts.h +++ b/src/MoonLight/Modules/ModuleLiveScripts.h @@ -147,7 +147,7 @@ class ModuleLiveScripts : public Module { } // update scripts / read only values in the UI - void loop1s() { + void loop1s() override { if (!_socket->getConnectedClients()) return; if (!WiFi.localIP() && !ETH.localIP()) return; diff --git a/src/main.cpp b/src/main.cpp index 120ded79..5bd45ce9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -257,40 +257,6 @@ void setup() { safeModeMB = true; } - // // check sizes ... - // sizeof(esp32sveltekit); // 4152 -> 4376 - // sizeof(WiFiSettingsService); // 456 - // sizeof(SystemStatus); // 16 - // sizeof(UploadFirmwareService); // 32 - // sizeof(HttpEndpoint); // 152 - // sizeof(EventEndpoint); // 112 - // sizeof(SharedEventEndpoint); // 8 - // sizeof(WebSocketServer); // 488 - // sizeof(SharedWebSocketServer); // 352 -> 432 - // sizeof(FSPersistence); // 128 - // sizeof(PsychicHttpServer*); // 8 - // sizeof(HttpEndpoint); // 152 - // sizeof(SharedHttpEndpoint); // 16 -> 48 - // sizeof(FSPersistence); // 128 - // sizeof(APSettingsService); // 600; - // sizeof(PsychicWebSocketHandler); // 336 - // sizeof(fileManager); // 864 - // sizeof(Module); // 1144 -> 472 -> 208 ! - // sizeof(moduleDevices); // 1320 -> 392 - // sizeof(moduleIO); // 1144 -> 240 - // #if FT_ENABLED(FT_MOONLIGHT) - // sizeof(moduleEffects); // 1208 -> 264 - // sizeof(moduleDrivers); // 1216 -> 288 - // sizeof(moduleLightsControl); // 1176 -> 296 - // #if FT_ENABLED(FT_LIVESCRIPT) - // sizeof(moduleLiveScripts); // 1176 -> 240 - // #endif - // sizeof(moduleChannels); // 1144 -> 208 - // sizeof(moduleMoonLightInfo); // 1144 -> 208 - // sizeof(layerP.lights); // 56 -> 96 - // sizeof(layerP.lights.header); // 40 -> 64 - // #endif - // start ESP32-SvelteKit esp32sveltekit.begin(); @@ -374,41 +340,22 @@ void setup() { static unsigned long last20ms = 0; if (millis() - last20ms >= 20) { last20ms = millis(); - #if FT_ENABLED(FT_MOONLIGHT) - moduleDevices.loop20ms(); // In MoonLight for the time being, should move to MoonBase using moduleControlCenter ... - #endif + + for (Module* module : modules) module->loop20ms(); // every second static unsigned long lastSecond = 0; if (millis() - lastSecond >= 1000) { lastSecond = millis(); - moduleIO.loop1s(); - moduleTasks.loop1s(); - - // logYield(); - - #if FT_ENABLED(FT_MOONLIGHT) - // set shared data (eg used in scrolling text effect) - sharedData.fps = esp32sveltekit.getAnalyticsService()->lps; - sharedData.connectionStatus = (uint8_t)esp32sveltekit.getConnectionStatus(); - sharedData.clientListSize = esp32sveltekit.getServer()->getClientList().size(); - sharedData.connectedClients = esp32sveltekit.getSocket()->getConnectedClients(); - sharedData.activeClients = esp32sveltekit.getSocket()->getActiveClients(); - - #if FT_ENABLED(FT_LIVESCRIPT) - moduleLiveScripts.loop1s(); - #endif - #endif + for (Module* module : modules) module->loop1s(); // every 10 seconds static unsigned long last10Second = 0; if (millis() - last10Second >= 10000) { last10Second = millis(); - #if FT_ENABLED(FT_MOONLIGHT) - moduleDevices.loop10s(); // In MoonLight for the time being, should move to MoonBase using moduleControlCenter ... - #endif + for (Module* module : modules) module->loop10s(); } } } @@ -439,4 +386,38 @@ void loop() { // Delete Arduino loop task, as it is not needed vTaskDelete(NULL); #endif -} \ No newline at end of file + +// // check sizes ... +// sizeof(esp32sveltekit); // 4152 -> 4376 +// sizeof(WiFiSettingsService); // 456 +// sizeof(SystemStatus); // 16 +// sizeof(UploadFirmwareService); // 32 +// sizeof(HttpEndpoint); // 152 +// sizeof(EventEndpoint); // 112 +// sizeof(SharedEventEndpoint); // 8 +// sizeof(WebSocketServer); // 488 +// sizeof(SharedWebSocketServer); // 352 -> 432 +// sizeof(FSPersistence); // 128 +// sizeof(PsychicHttpServer*); // 8 +// sizeof(HttpEndpoint); // 152 +// sizeof(SharedHttpEndpoint); // 16 -> 48 +// sizeof(FSPersistence); // 128 +// sizeof(APSettingsService); // 600; +// sizeof(PsychicWebSocketHandler); // 336 +// sizeof(fileManager); // 864 +// sizeof(Module); // 1144 -> 472 -> 208 ! +// sizeof(moduleDevices); // 1320 -> 392 +// sizeof(moduleIO); // 1144 -> 240 +// #if FT_ENABLED(FT_MOONLIGHT) +// sizeof(moduleEffects); // 1208 -> 264 +// sizeof(moduleDrivers); // 1216 -> 288 +// sizeof(moduleLightsControl); // 1176 -> 296 +// #if FT_ENABLED(FT_LIVESCRIPT) +// sizeof(moduleLiveScripts); // 1176 -> 240 +// #endif +// sizeof(moduleChannels); // 1144 -> 208 +// sizeof(moduleMoonLightInfo); // 1144 -> 208 +// sizeof(layerP.lights); // 56 -> 96 +// sizeof(layerP.lights.header); // 40 -> 64 +// #endif +} From 27e4260d702856f367c9305a509bd89823a47656 Mon Sep 17 00:00:00 2001 From: ewowi Date: Tue, 17 Feb 2026 11:07:14 +0100 Subject: [PATCH 3/4] readPins fixes firmware ======== - pio.ini: latest FastLED Frontend ======== - Firmware manager: confirmGithubUpdate clearer message if no matching firmware found backend ======= - IO: callUpdateHandlers once in loop - Module Driver: addUpdateHandler in constructor, no initial readPins (see IO) --- .../update/GithubFirmwareManager.svelte | 14 +- lib/framework/SystemStatus.cpp | 1 + lib/framework/WWWData.h | 6235 ++++++++--------- platformio.ini | 4 +- src/MoonBase/Modules/ModuleDevices.h | 4 +- src/MoonBase/Modules/ModuleIO.h | 38 +- src/MoonLight/Modules/ModuleDrivers.h | 17 +- src/MoonLight/Modules/ModuleLightsControl.h | 9 +- src/MoonLight/Nodes/Drivers/D_Infrared.h | 2 +- src/main.cpp | 101 +- 10 files changed, 3231 insertions(+), 3194 deletions(-) diff --git a/interface/src/routes/system/update/GithubFirmwareManager.svelte b/interface/src/routes/system/update/GithubFirmwareManager.svelte index b031c5ba..b05bf25a 100644 --- a/interface/src/routes/system/update/GithubFirmwareManager.svelte +++ b/interface/src/routes/system/update/GithubFirmwareManager.svelte @@ -56,23 +56,23 @@ } } - function confirmGithubUpdate(assets: any) { + function confirmGithubUpdate(release: any) { // 🌙 use release instead of assets let url = ''; // iterate over assets and find the correct one - for (let i = 0; i < assets.length; i++) { + for (let i = 0; i < release.assets.length; i++) { // check if the asset is of type *.bin if ( - assets[i].name.includes('.bin') && - assets[i].name.includes(page.data.features.firmware_built_target) + release.assets[i].name.includes('.bin') && + release.assets[i].name.includes(page.data.features.firmware_built_target) ) { - url = assets[i].browser_download_url; + url = release.assets[i].browser_download_url; } } if (url === '') { modals.open(InfoDialog as unknown as ModalComponent, { title: 'No matching firmware found', message: - 'No matching firmware was found for the current device. Upload the firmware manually or build from sources.', + 'No matching firmware was found in ' + release.name + ' for ' + page.data.features.firmware_built_target, // 🌙 dismiss: { label: 'OK', icon: Check }, onDismiss: () => modals.close() }); @@ -157,7 +157,7 @@