From efc50241c7f864d719a78c11f45cb1b0a981b125 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 20 Dec 2024 23:56:20 -0500 Subject: [PATCH 01/10] Use the output buffer as an SD data buffer. --- src/FileMgr.cpp | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/FileMgr.cpp b/src/FileMgr.cpp index 799f797d5..5048e7f72 100644 --- a/src/FileMgr.cpp +++ b/src/FileMgr.cpp @@ -23,6 +23,7 @@ #include "FileMgr.hpp" #include "network/NetworkMgr.hpp" +#include "output/OutputMgr.hpp" SdFs sd; const int8_t DISABLE_CS_PIN = -1; @@ -1465,7 +1466,10 @@ void c_FileMgr::CloseSdFile (FileId& FileHandle, bool LockStatus) if (nullptr != FileList[FileListIndex].buffer.DataBuffer) { - free(FileList[FileListIndex].buffer.DataBuffer); + if(FileList[FileListIndex].buffer.DataBuffer != OutputMgr.GetBufferAddress()) + { + free(FileList[FileListIndex].buffer.DataBuffer); + } } FileList[FileListIndex].buffer.DataBuffer = nullptr; FileList[FileListIndex].buffer.size = 0; @@ -1553,15 +1557,18 @@ size_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, size } #endif // defined (ARDUINO_ARCH_ESP32) - delay(10); - FeedWDT(); - // are we using a buffer in front of the SD card? if(nullptr == FileList[FileListIndex].buffer.DataBuffer) { + delay(10); + FeedWDT(); + // DEBUG_V("Not using buffers"); NumBytesWritten = FileList[FileListIndex].fsFile.write(FileData, NumBytesToWrite); FileList[FileListIndex].fsFile.flush(); + + delay(20); + FeedWDT(); } else // buffered mode { @@ -1574,12 +1581,16 @@ size_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, size // DEBUG_V(String(" Offset: ") + String(FileList[FileListIndex].buffer.offset)); if(WontFit || WriteRemainder) { + delay(10); + FeedWDT(); // DEBUG_V("Buffer cant hold this data. Write out the buffer"); size_t bufferWriteSize = FileList[FileListIndex].fsFile.write(FileData, FileList[FileListIndex].buffer.offset); FileList[FileListIndex].fsFile.flush(); + delay(20); + FeedWDT(); if(FileList[FileListIndex].buffer.offset != bufferWriteSize) { - logcon (String("WriteSdFileBuf:ERROR:SD Write Failed. Tried to write: ") + + logcon (String("WriteSdFileBuf:ERROR:SD Write Failed. Tried to write: ") + String(FileList[FileListIndex].buffer.offset) + " bytes. Actually wrote: " + String(bufferWriteSize)) NumBytesWritten = 0; @@ -1597,8 +1608,6 @@ size_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, size } // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); - delay(20); - FeedWDT(); if(NumBytesWritten != NumBytesToWrite) { @@ -1935,8 +1944,6 @@ bool c_FileMgr::handleFileUpload ( void c_FileMgr::handleFileUploadNewFile (const String & filename) { // DEBUG_START; - - // save the filename // DEBUG_V ("UploadStart: " + filename); fsUploadStartTime = millis(); @@ -1958,6 +1965,19 @@ void c_FileMgr::handleFileUploadNewFile (const String & filename) // Open the file for writing OpenSdFile (fsUploadFileName, FileMode::FileWrite, fsUploadFileHandle, -1 /*first access*/, false); + int FileListIndex; + // DEBUG_V (String("NumBytesToWrite: ") + String(NumBytesToWrite)); + if (-1 == (FileListIndex = FileListFindSdFileHandle (fsUploadFileHandle))) + { + logcon (String (F ("WriteSdFileBuf::ERROR::Invalid File Handle: ")) + String (fsUploadFileHandle)); + } + else + { + // DEBUG_V("Use the output buffer as a data buffer"); + FileList[FileListIndex].buffer.offset = 0; + FileList[FileListIndex].buffer.size = OutputMgr.GetBufferSize(); + FileList[FileListIndex].buffer.DataBuffer = OutputMgr.GetBufferAddress(); + } // DEBUG_END; From 20535389eb6d18c0a87efe2acd155ce5ad3638e1 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 26 Dec 2024 13:14:36 -0500 Subject: [PATCH 02/10] Updated debug info --- src/input/InputFPPRemote.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/input/InputFPPRemote.cpp b/src/input/InputFPPRemote.cpp index 442eb993d..59e85bdcb 100644 --- a/src/input/InputFPPRemote.cpp +++ b/src/input/InputFPPRemote.cpp @@ -2,7 +2,7 @@ * InputFPPRemote.cpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -372,18 +372,17 @@ void c_InputFPPRemote::StopPlaying () // handle re entrancy if(Stopping) { - // already in the process of stopping + // DEBUG_V("already in the process of stopping"); break; } Stopping = true; - // DEBUG_V (); + // DEBUG_V ("Disable FPP Discovery"); FPPDiscovery.Disable (); FPPDiscovery.ForgetInputFPPRemotePlayFile (); if(PlayingFile()) { - // DEBUG_V(String("pInputFPPRemotePlayItem: ") = String(uint32_t(pInputFPPRemotePlayItem), HEX)); pInputFPPRemotePlayItem->Stop (); while (!pInputFPPRemotePlayItem->IsIdle ()) @@ -549,8 +548,10 @@ bool c_InputFPPRemote::PlayingFile () do // once { + // DEBUG_V(String("pInputFPPRemotePlayItem: ") = String(uint32_t(pInputFPPRemotePlayItem), HEX)); if (nullptr == pInputFPPRemotePlayItem) { + // DEBUG_V("Stop processing if the play item pointer is null"); break; } From c309756fd7be8450d4f0e31a930fb8ee7a67e265 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 26 Dec 2024 13:15:30 -0500 Subject: [PATCH 03/10] Added check against running two concurrent uploads at the same time. --- include/EFUpdate.h | 8 +++++--- src/EFUpdate.cpp | 8 +++----- src/WebMgr.cpp | 18 +++++++++++++++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/include/EFUpdate.h b/include/EFUpdate.h index 96faa31ab..509de3645 100644 --- a/include/EFUpdate.h +++ b/include/EFUpdate.h @@ -36,7 +36,8 @@ class EFUpdate { bool hasError(); uint8_t getError(); bool end(); - void GetDriverName(String & name) {name = String(F("EFUPD"));} + void GetDriverName(String & name) {name = String(F("EFUPD"));} + bool UpdateIsInProgress() {return _state != State::IDLE;} private: /* Record types */ @@ -52,7 +53,8 @@ class EFUpdate { HEADER, RECORD, DATA, - FAIL + FAIL, + IDLE }; /* EFU Header */ @@ -75,7 +77,7 @@ class EFUpdate { uint8_t raw[6]; } efurecord_t; - State _state = State::FAIL; + State _state = State::IDLE; uint32_t _loc = 0; efuheader_t _header; efurecord_t _record; diff --git a/src/EFUpdate.cpp b/src/EFUpdate.cpp index b993b3753..4288b5fd8 100644 --- a/src/EFUpdate.cpp +++ b/src/EFUpdate.cpp @@ -23,6 +23,7 @@ #include #include "EFUpdate.h" +#include #ifdef ARDUINO_ARCH_ESP32 # include @@ -91,10 +92,7 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { case State::RECORD: // DEBUG_V ("Process Data RECORD Type"); // DEBUG_V (String (" len: 0x") + String (len, HEX)); - // DEBUG_V (String ("AccumulatedLentgh: 0x") + String (AccumulatedLentgh, HEX)); // DEBUG_V (String (" index: ") + String (index)); - // DEBUG_V (String (" AccumulatedIndex: ") + String (AccumulatedIndex)); - // DEBUG_V (String (" AccumulatedIndex: 0x") + String (AccumulatedIndex, HEX)); // DEBUG_V (String (" Data: 0x") + String (data[index], HEX)); // DEBUG_V (String (" Data: ") + String (data[index])); @@ -116,9 +114,9 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { _state = State::FAIL; _error = Update.getError(); } else { - // DEBUG_V ("PASS"); + /// DEBUG_V ("PASS"); _state = State::DATA; - // esp_image_header_t *esp_image_header = (esp_image_header_t*)&data[index]; + esp_image_header_t *esp_image_header = (esp_image_header_t*)&data[index]; // DEBUG_V(String(" magic: 0x") + String(esp_image_header->magic, HEX)); // DEBUG_V(String(" segment_count: 0x") + String(esp_image_header->segment_count, HEX)); // DEBUG_V(String(" spi_mode: 0x") + String(esp_image_header->spi_mode, HEX)); diff --git a/src/WebMgr.cpp b/src/WebMgr.cpp index 954d8d71b..149b20297 100644 --- a/src/WebMgr.cpp +++ b/src/WebMgr.cpp @@ -2,7 +2,7 @@ * WebMgr.cpp - Output Management class * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -834,12 +834,24 @@ void c_WebMgr::FirmwareUpload (AsyncWebServerRequest* request, // is the first message in the upload? if (0 == index) { + if(efupdate.UpdateIsInProgress()) + { + logcon("An update is already in progress"); + // send back an error response + request->send (429, CN_textSLASHplain, F ("Update Error: Too many requests.")); + break; + } #ifdef ARDUINO_ARCH_ESP8266 WiFiUDP::stopAll (); #else // this is not supported for ESP32 #endif logcon (String(F ("Upload Started: ")) + filename); + // stop all input and output processing of intensity data. + // InputMgr.SetOperationalState(false); + // OutputMgr.PauseOutputs(true); + + // start the update efupdate.begin (); } @@ -852,7 +864,7 @@ void c_WebMgr::FirmwareUpload (AsyncWebServerRequest* request, { logcon (String(CN_stars) + F (" UPDATE ERROR: ") + String (efupdate.getError ())); // DEBUG_V ("efupdate.hasError"); - request->send (200, CN_textSLASHplain, (String (F ("Update Error: ")) + String (efupdate.getError ()).c_str())); + request->send (500, CN_textSLASHplain, (String (F ("Update Error: ")) + String (efupdate.getError ()).c_str())); break; } // DEBUG_V ("No EFUpdate Error"); @@ -862,7 +874,7 @@ void c_WebMgr::FirmwareUpload (AsyncWebServerRequest* request, request->send (200, CN_textSLASHplain, (String ( F ("Update Finished: ")) + String (efupdate.getError ())).c_str()); logcon (F ("Upload Finished. Rebooting")); efupdate.end (); - RequestReboot(100000);; + RequestReboot(100000); } } while (false); From aa68a055c6cc3bcf34bca1203187b8eef704c8b2 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 26 Dec 2024 13:22:54 -0500 Subject: [PATCH 04/10] Fixed an ESP32 specific include file. --- src/EFUpdate.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EFUpdate.cpp b/src/EFUpdate.cpp index 4288b5fd8..834facc1e 100644 --- a/src/EFUpdate.cpp +++ b/src/EFUpdate.cpp @@ -2,7 +2,7 @@ * EFUpdate.cpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2016, 2022 Shelby Merrick +* Copyright (c) 2016, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -23,11 +23,11 @@ #include #include "EFUpdate.h" -#include #ifdef ARDUINO_ARCH_ESP32 # include # include +# include #endif #ifndef U_SPIFFS From b67bd41dddf0c86128f1c47e43122b031cd065b7 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 26 Dec 2024 13:28:09 -0500 Subject: [PATCH 05/10] Added idel state handling --- src/EFUpdate.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/EFUpdate.cpp b/src/EFUpdate.cpp index 834facc1e..f797bd0d7 100644 --- a/src/EFUpdate.cpp +++ b/src/EFUpdate.cpp @@ -193,6 +193,11 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { index = len; ConfigChanged = false; break; + case State::IDLE: + { + // dont do anything + break; + } } } // DEBUG_END; From eeb76f5b7770757ed95264dbfec6b5fbf0985100 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 26 Dec 2024 15:58:58 -0500 Subject: [PATCH 06/10] Fixed ESP8266 build error --- include/EFUpdate.h | 2 +- src/EFUpdate.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/EFUpdate.h b/include/EFUpdate.h index 509de3645..d59b3b71e 100644 --- a/include/EFUpdate.h +++ b/include/EFUpdate.h @@ -78,7 +78,7 @@ class EFUpdate { } efurecord_t; State _state = State::IDLE; - uint32_t _loc = 0; + uint32_t _loc = 0; efuheader_t _header; efurecord_t _record; uint32_t _maxSketchSpace; diff --git a/src/EFUpdate.cpp b/src/EFUpdate.cpp index f797bd0d7..8cdd27ea3 100644 --- a/src/EFUpdate.cpp +++ b/src/EFUpdate.cpp @@ -27,7 +27,7 @@ #ifdef ARDUINO_ARCH_ESP32 # include # include -# include +// # include #endif #ifndef U_SPIFFS @@ -116,7 +116,7 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { } else { /// DEBUG_V ("PASS"); _state = State::DATA; - esp_image_header_t *esp_image_header = (esp_image_header_t*)&data[index]; + // esp_efu_header_t *esp_image_header = (efuheader_t*)&data[index]; // DEBUG_V(String(" magic: 0x") + String(esp_image_header->magic, HEX)); // DEBUG_V(String(" segment_count: 0x") + String(esp_image_header->segment_count, HEX)); // DEBUG_V(String(" spi_mode: 0x") + String(esp_image_header->spi_mode, HEX)); From 843884792f815096e7c4cd295a3745916a4968e8 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 Dec 2024 13:11:23 -0500 Subject: [PATCH 07/10] Added extended FW update error reporting to the user. --- html/script.js | 24 ++++++++-- include/EFUpdate.h | 12 +++-- src/EFUpdate.cpp | 109 +++++++++++++++++++++++++++++++++++++++++---- src/WebMgr.cpp | 42 +++++++++++++++-- 4 files changed, 168 insertions(+), 19 deletions(-) diff --git a/html/script.js b/html/script.js index ad8d636cb..aa4d05ba3 100644 --- a/html/script.js +++ b/html/script.js @@ -230,19 +230,37 @@ $(function () { } function completeHandler(event) { + console.info("Transfer Complete"); + // console.info("event: '" + event + "'"); + // console.info("event.target.response: '" + event.target.response + "'"); + // console.info("event.target.responseText: '" + event.target.responseText + "'"); + // console.info("event.target.status : '" + event.target.status + "'"); + // console.info("event.target.statusText : '" + event.target.statusText + "'"); + // _("status").innerHTML = event.target.responseText; _("EfuProgressBar").value = 0; //will clear progress bar after successful upload - showReboot(); + $("#EfuProgressBar").addClass("hidden"); + + if(event.target.status === '200') + { + showReboot(); + } + else + { + alert("Firmware Upload FAILED!\n" + event.target.response); + } } function errorHandler(event) { console.error("Transfer Error"); - // _("status").innerHTML = "Upload Failed"; + $("#EfuProgressBar").addClass("hidden"); + alert("Firmware Upload FAILED!"); } function abortHandler(event) { console.error("Transfer Abort"); - // _("status").innerHTML = "Upload Aborted"; + $("#EfuProgressBar").addClass("hidden"); + alert("Firmware Upload FAILED!"); } }); })); diff --git a/include/EFUpdate.h b/include/EFUpdate.h index d59b3b71e..5285ef834 100644 --- a/include/EFUpdate.h +++ b/include/EFUpdate.h @@ -2,7 +2,7 @@ * EFUpdate.h * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2016, 2022 Shelby Merrick +* Copyright (c) 2016, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -34,7 +34,7 @@ class EFUpdate { void begin(); bool process(uint8_t *data, uint32_t len); bool hasError(); - uint8_t getError(); + uint8_t getError(String & msg); bool end(); void GetDriverName(String & name) {name = String(F("EFUPD"));} bool UpdateIsInProgress() {return _state != State::IDLE;} @@ -81,8 +81,12 @@ class EFUpdate { uint32_t _loc = 0; efuheader_t _header; efurecord_t _record; - uint32_t _maxSketchSpace; - uint8_t _error; + uint32_t _maxSketchSpace = 0; + uint8_t _error = EFUPDATE_ERROR_OK; + String _errorMsg; + + void ConvertErrorToString(); + }; #endif /* EFUPDATE_H_ */ diff --git a/src/EFUpdate.cpp b/src/EFUpdate.cpp index 8cdd27ea3..c1088e259 100644 --- a/src/EFUpdate.cpp +++ b/src/EFUpdate.cpp @@ -47,6 +47,7 @@ void EFUpdate::begin() { _state = State::HEADER; _loc = 0; _error = EFUPDATE_ERROR_OK; + _errorMsg = ""; Update.onProgress( [this] (size_t progress, size_t total) { @@ -61,12 +62,15 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { uint32_t index = 0; bool ConfigChanged = true; - while (index < len) { + while (!hasError() && (index < len)) + { // DEBUG_V (String (" len: 0x") + String (len, HEX)); // DEBUG_V (String ("index: 0X") + String (index, HEX)); - switch (_state) { + switch (_state) + { case State::HEADER: + { // DEBUG_V (String (" len: 0x") + String (len, HEX)); // DEBUG_V (String ("index: ") + String (index)); // DEBUG_V ("Process HEADER record"); @@ -82,14 +86,17 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { _loc = 0; _state = State::RECORD; } else { - logcon ("FAIL: EFUPDATE_ERROR_SIG"); + logcon (F("FAIL: EFUPDATE_ERROR_SIG")); _state = State::FAIL; _error = EFUPDATE_ERROR_SIG; + _errorMsg = F("Invalid EFU Signature"); } } // DEBUG_V (); break; + } case State::RECORD: + { // DEBUG_V ("Process Data RECORD Type"); // DEBUG_V (String (" len: 0x") + String (len, HEX)); // DEBUG_V (String (" index: ") + String (index)); @@ -110,9 +117,10 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { logcon ("Starting Sketch Image Update\n"); // Begin sketch update if (!Update.begin(_record.size, U_FLASH)) { - logcon ("Update.begin FAIL"); + logcon (F("Update.begin FAIL")); _state = State::FAIL; _error = Update.getError(); + ConvertErrorToString(); } else { /// DEBUG_V ("PASS"); _state = State::DATA; @@ -143,9 +151,10 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { #endif // DEBUG_V (); if (!Update.begin(_record.size, U_SPIFFS)) { - logcon ("begin U_SPIFFS failed"); + logcon (F("begin U_SPIFFS failed")); _state = State::FAIL; _error = Update.getError(); + ConvertErrorToString(); // DEBUG_V (); } else { // DEBUG_V ("begin U_SPIFFS"); @@ -155,14 +164,17 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { Update.runAsync (true); #endif } else { - logcon ("Unknown Record Type"); + logcon (F("Unknown Record Type")); _state = State::FAIL; _error = EFUPDATE_ERROR_REC; + _errorMsg = F("Unknown Record Type"); } } // DEBUG_V (); break; + } case State::DATA: + { // DEBUG_V ("DATA"); uint32_t toWrite; @@ -187,12 +199,14 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { } // DEBUG_V (); break; - + } case State::FAIL: + { // DEBUG_V ("Enter FAIL state"); index = len; ConfigChanged = false; break; + } case State::IDLE: { // dont do anything @@ -210,11 +224,90 @@ bool EFUpdate::hasError() { return _error != EFUPDATE_ERROR_OK; } -uint8_t EFUpdate::getError() { +uint8_t EFUpdate::getError(String & msg) +{ // DEBUG_V (); + msg = _errorMsg; return _error; } +void EFUpdate::ConvertErrorToString() +{ + switch (_error) + { + case UPDATE_ERROR_OK: + { + _errorMsg = F("OK"); + break; + } + case UPDATE_ERROR_WRITE: + { + _errorMsg = F("Error writting to Flash"); + break; + } + case UPDATE_ERROR_ERASE: + { + _errorMsg = F("Error Erasing Flash"); + break; + } + case UPDATE_ERROR_READ: + { + _errorMsg = F("Could not read from FLASH"); + break; + } + case UPDATE_ERROR_SPACE: + { + _errorMsg = F("Not enough space in partition"); + break; + } + case UPDATE_ERROR_SIZE: + { + _errorMsg = F("File Size mismatch"); + break; + } + case UPDATE_ERROR_STREAM: + { + _errorMsg = F("Stream writer failed"); + break; + } + case UPDATE_ERROR_MD5: + { + _errorMsg = F("MD5 checksum failed"); + break; + } + case UPDATE_ERROR_MAGIC_BYTE: + { + _errorMsg = F("Magic Byte Mismatch"); + break; + } + case UPDATE_ERROR_ACTIVATE: + { + _errorMsg = F("Could Not activate the alternate partition"); + break; + } + case UPDATE_ERROR_NO_PARTITION: + { + _errorMsg = F("No partition defined for target"); + break; + } + case UPDATE_ERROR_BAD_ARGUMENT: + { + _errorMsg = F("Invalid argument"); + break; + } + case UPDATE_ERROR_ABORT: + { + _errorMsg = F("Operation Aborted"); + break; + } + default: + { + _errorMsg = F("Unknown Error Code"); + break; + } + } +} // ConvertErrorToString + bool EFUpdate::end() { // DEBUG_V (); if (_state == State::FAIL) diff --git a/src/WebMgr.cpp b/src/WebMgr.cpp index 149b20297..1c2dd644c 100644 --- a/src/WebMgr.cpp +++ b/src/WebMgr.cpp @@ -365,7 +365,20 @@ void c_WebMgr::init () webServer.on ("/updatefw", HTTP_POST, [](AsyncWebServerRequest* request) { - RequestReboot(100000);; + // DEBUG_V("Client requested reboot"); + if (WebMgr.efupdate.hasError ()) + { + // DEBUG_V ("efupdate.hasError, ignoring reboot request"); + String ErrorMsg; + WebMgr.efupdate.getError (ErrorMsg); + request->send (500, CN_textSLASHplain, (String (F ("Update Error: ")) + ErrorMsg.c_str())); + } + else + { + // DEBUG_V ("efupdate.hasError == false"); + request->send (200, CN_textSLASHplain, (String (F ("Update Success")))); + RequestReboot(100000); + } }, [](AsyncWebServerRequest* request, String filename, uint32_t index, uint8_t* data, uint32_t len, bool final) {WebMgr.FirmwareUpload (request, filename, index, data, len, final); }); //.setFilter (ON_STA_FILTER); @@ -830,6 +843,15 @@ void c_WebMgr::FirmwareUpload (AsyncWebServerRequest* request, // DEBUG_V (String (" data: 0x") + String (uint32_t(data), HEX)); // DEBUG_V (String (" len: ") + String (len)); // DEBUG_V (String ("final: ") + String (final)); + if (efupdate.hasError ()) + { + // logcon (String(CN_stars) + F (" UPDATE ERROR: ") + String (efupdate.getError ())); + // DEBUG_V ("efupdate.hasError"); + String ErrorMsg; + WebMgr.efupdate.getError (ErrorMsg); + request->send (500, CN_textSLASHplain, (String (F ("Update Error: ")) + ErrorMsg.c_str())); + break; + } // is the first message in the upload? if (0 == index) @@ -841,6 +863,7 @@ void c_WebMgr::FirmwareUpload (AsyncWebServerRequest* request, request->send (429, CN_textSLASHplain, F ("Update Error: Too many requests.")); break; } + #ifdef ARDUINO_ARCH_ESP8266 WiFiUDP::stopAll (); #else @@ -853,6 +876,15 @@ void c_WebMgr::FirmwareUpload (AsyncWebServerRequest* request, // start the update efupdate.begin (); + if (efupdate.hasError ()) + { + // logcon (String(CN_stars) + F (" UPDATE ERROR: ") + String (efupdate.getError ())); + // DEBUG_V ("efupdate.hasError"); + String ErrorMsg; + WebMgr.efupdate.getError (ErrorMsg); + request->send (500, CN_textSLASHplain, (String (F ("Update Error: ")) + ErrorMsg.c_str())); + break; + } } // DEBUG_V ("Sending data to efupdate"); @@ -862,16 +894,18 @@ void c_WebMgr::FirmwareUpload (AsyncWebServerRequest* request, if (efupdate.hasError ()) { - logcon (String(CN_stars) + F (" UPDATE ERROR: ") + String (efupdate.getError ())); + // logcon (String(CN_stars) + F (" UPDATE ERROR: ") + String (efupdate.getError ())); // DEBUG_V ("efupdate.hasError"); - request->send (500, CN_textSLASHplain, (String (F ("Update Error: ")) + String (efupdate.getError ()).c_str())); + String ErrorMsg; + WebMgr.efupdate.getError (ErrorMsg); + request->send (500, CN_textSLASHplain, (String (F ("Update Error: ")) + ErrorMsg.c_str())); break; } // DEBUG_V ("No EFUpdate Error"); if (final) { - request->send (200, CN_textSLASHplain, (String ( F ("Update Finished: ")) + String (efupdate.getError ())).c_str()); + request->send (200, CN_textSLASHplain, (String ( F ("Update Finished")))); logcon (F ("Upload Finished. Rebooting")); efupdate.end (); RequestReboot(100000); From f066ea3c58b485b8d3c1c96512382ae2845af096 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 Dec 2024 15:21:31 -0500 Subject: [PATCH 08/10] Fixed http status check. --- html/script.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/html/script.js b/html/script.js index aa4d05ba3..dfff51ba1 100644 --- a/html/script.js +++ b/html/script.js @@ -241,13 +241,15 @@ $(function () { _("EfuProgressBar").value = 0; //will clear progress bar after successful upload $("#EfuProgressBar").addClass("hidden"); - if(event.target.status === '200') + if(event.target.status === 200) { + alert("Firmware Upload SUCCESS!"); showReboot(); } else { alert("Firmware Upload FAILED!\n" + event.target.response); + showReboot(); } } From b927e4179cc5d8bbe35071188245703ea329d68a Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 Dec 2024 15:47:03 -0500 Subject: [PATCH 09/10] Removed error cases not supported by 8266 --- src/EFUpdate.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/EFUpdate.cpp b/src/EFUpdate.cpp index c1088e259..bbc24dbbe 100644 --- a/src/EFUpdate.cpp +++ b/src/EFUpdate.cpp @@ -280,6 +280,7 @@ void EFUpdate::ConvertErrorToString() _errorMsg = F("Magic Byte Mismatch"); break; } +#ifdef ARDUINO_ARCH_ESP32 case UPDATE_ERROR_ACTIVATE: { _errorMsg = F("Could Not activate the alternate partition"); @@ -300,6 +301,7 @@ void EFUpdate::ConvertErrorToString() _errorMsg = F("Operation Aborted"); break; } +#endif // def ARDUINO_ARCH_ESP32 default: { _errorMsg = F("Unknown Error Code"); From acf1ea21e61820c0829cb82225b245a032656b72 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 28 Dec 2024 11:29:22 -0500 Subject: [PATCH 10/10] Fixed issue caused by tasks running async in the input space and not stopping when the primary input was active. --- include/input/InputAlexa.h | 4 ++-- include/input/InputArtnet.hpp | 2 +- include/input/InputCommon.hpp | 2 +- include/input/InputDDP.h | 4 ++-- include/input/InputDisabled.hpp | 4 ++-- include/input/InputE131.hpp | 4 ++-- include/input/InputEffectEngine.hpp | 5 ++-- include/input/InputFPPRemote.h | 5 ++-- include/input/InputFPPRemotePlayEffect.hpp | 6 ++--- include/input/InputFPPRemotePlayEffectFsm.hpp | 8 +++---- include/input/InputFPPRemotePlayFile.hpp | 14 +++++------ include/input/InputFPPRemotePlayFileFsm.hpp | 14 +++++------ include/input/InputFPPRemotePlayItem.hpp | 4 ++-- include/input/InputFPPRemotePlayList.hpp | 4 ++-- include/input/InputFPPRemotePlayListFsm.hpp | 14 +++++------ include/input/InputMQTT.h | 4 ++-- include/input/externalInput.h | 20 ++++++++++++++-- src/input/InputAlexa.cpp | 6 ++--- src/input/InputDDP.cpp | 9 +++++-- src/input/InputDisabled.cpp | 4 ++-- src/input/InputE131.cpp | 4 ++-- src/input/InputEffectEngine.cpp | 6 ++--- src/input/InputFPPRemote.cpp | 9 +++---- src/input/InputFPPRemotePlayEffect.cpp | 6 ++--- src/input/InputFPPRemotePlayEffectFsm.cpp | 10 ++++---- src/input/InputFPPRemotePlayFile.cpp | 8 +++---- src/input/InputFPPRemotePlayFileFsm.cpp | 23 +++++++++++------- src/input/InputFPPRemotePlayList.cpp | 6 ++--- src/input/InputFPPRemotePlayListFsm.cpp | 20 ++++++++-------- src/input/InputMQTT.cpp | 8 +++---- src/input/InputMgr.cpp | 6 ++--- src/input/externalInput.cpp | 24 +++++++++++++++---- 32 files changed, 157 insertions(+), 110 deletions(-) diff --git a/include/input/InputAlexa.h b/include/input/InputAlexa.h index a2ff4e210..fa24cae88 100644 --- a/include/input/InputAlexa.h +++ b/include/input/InputAlexa.h @@ -3,7 +3,7 @@ * InputAlexa.h * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -37,7 +37,7 @@ class c_InputAlexa : public c_InputCommon bool SetConfig (JsonObject& jsonConfig); ///< Set a new config in the driver void GetConfig (JsonObject& jsonConfig); ///< Get the current config used by the driver void GetStatus (JsonObject& jsonStatus); - void Process (); ///< Call from loop(), renders Input data + void Process (bool StayDark); void GetDriverName (String& sDriverName) { sDriverName = "Alexa"; } ///< get the name for the instantiated driver void SetBufferInfo (uint32_t BufferSize); diff --git a/include/input/InputArtnet.hpp b/include/input/InputArtnet.hpp index d444390d8..c58545188 100644 --- a/include/input/InputArtnet.hpp +++ b/include/input/InputArtnet.hpp @@ -79,6 +79,6 @@ class c_InputArtnet : public c_InputCommon void SetBufferInfo (uint32_t BufferSize); void NetworkStateChanged (bool IsConnected); // used by poorly designed rx functions bool isShutDownRebootNeeded () { return HasBeenInitialized; } - virtual void Process () {} ///< Call from loop(), renders Input data + virtual void Process (bool StayDark) {} ///< Call from loop(), renders Input data }; diff --git a/include/input/InputCommon.hpp b/include/input/InputCommon.hpp index 8fdf51c70..0d980ec06 100644 --- a/include/input/InputCommon.hpp +++ b/include/input/InputCommon.hpp @@ -36,7 +36,7 @@ class c_InputCommon virtual bool SetConfig (ArduinoJson::JsonObject & jsonConfig) = 0; ///< Set a new config in the driver virtual void GetConfig (ArduinoJson::JsonObject & jsonConfig) = 0; ///< Get the current config used by the driver virtual void GetStatus (JsonObject & jsonStatus) = 0; - virtual void Process () = 0; ///< Call from loop(), renders Input data + virtual void Process (bool StayDark) = 0; ///< Call from loop(), renders Input data virtual void GetDriverName (String & sDriverName) = 0; ///< get the name for the instantiated driver virtual void SetBufferInfo (uint32_t BufferSize) = 0; virtual void SetOperationalState (bool ActiveFlag) { IsInputChannelActive = ActiveFlag; } diff --git a/include/input/InputDDP.h b/include/input/InputDDP.h index c1ca50f8a..480a5f4d0 100644 --- a/include/input/InputDDP.h +++ b/include/input/InputDDP.h @@ -3,7 +3,7 @@ * InputDDP.h * * Project: InputDDP - Asynchronous DDP library for Arduino ESP8266 and ESP32 -* Copyright (c) 2019, 2022 Daniel Kulp, Shelby Merrick +* Copyright (c) 2019, 2025 Daniel Kulp, Shelby Merrick * * This program is provided free for you to use in any way that you wish, * subject to the laws and regulations where you are using it. Due diligence @@ -137,7 +137,7 @@ class c_InputDDP : public c_InputCommon bool SetConfig (JsonObject& jsonConfig); ///< Set a new config in the driver void GetConfig (JsonObject& jsonConfig); ///< Get the current config used by the driver void GetStatus (JsonObject& jsonStatus); - void Process (); ///< Call from loop(), renders Input data + void Process (bool StayDark); ///< Call from loop(), renders Input data void GetDriverName (String& sDriverName) { sDriverName = "DDP"; } ///< get the name for the instantiated driver void SetBufferInfo (uint32_t BufferSize); bool isShutDownRebootNeeded () { return HasBeenInitialized; } diff --git a/include/input/InputDisabled.hpp b/include/input/InputDisabled.hpp index d71e0a35f..85ee765d1 100644 --- a/include/input/InputDisabled.hpp +++ b/include/input/InputDisabled.hpp @@ -3,7 +3,7 @@ * InputDisabled.h - Do Nothing input driver * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -38,7 +38,7 @@ class c_InputDisabled : public c_InputCommon bool SetConfig (JsonObject & jsonConfig); ///< Set a new config in the driver void GetConfig (JsonObject & jsonConfig); ///< Get the current config used by the driver void GetStatus (JsonObject & jsonStatus); - void Process (); ///< Call from loop(), Process Input data + void Process (bool StayDark); void GetDriverName (String& sDriverName) { sDriverName = "Disabled"; } ///< get the name for the instantiated driver void SetBufferInfo (uint32_t BufferSize) {} diff --git a/include/input/InputE131.hpp b/include/input/InputE131.hpp index 34d339d73..a9312ffea 100644 --- a/include/input/InputE131.hpp +++ b/include/input/InputE131.hpp @@ -3,7 +3,7 @@ * E131Input.h - Code to wrap ESPAsyncE131 for input * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -69,7 +69,7 @@ class c_InputE131 : public c_InputCommon bool SetConfig (JsonObject & jsonConfig); ///< Set a new config in the driver void GetConfig (JsonObject & jsonConfig); ///< Get the current config used by the driver void GetStatus (JsonObject & jsonStatus); - void Process (); ///< Call from loop(), renders Input data + void Process (bool StayDark); void GetDriverName (String & sDriverName) { sDriverName = "E1.31"; } ///< get the name for the instantiated driver void SetBufferInfo (uint32_t BufferSize); void NetworkStateChanged (bool IsConnected); // used by poorly designed rx functions diff --git a/include/input/InputEffectEngine.hpp b/include/input/InputEffectEngine.hpp index 5383eeced..e5742b37c 100644 --- a/include/input/InputEffectEngine.hpp +++ b/include/input/InputEffectEngine.hpp @@ -3,7 +3,7 @@ * InputEffectEngine.cpp - Input Management class * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -102,7 +102,7 @@ class c_InputEffectEngine : public c_InputCommon void GetMqttConfig (MQTTConfiguration_s& mqttConfig); ///< Get the current config used by the driver void GetMqttEffectList (JsonObject& jsonConfig); ///< Get the current config used by the driver void GetStatus (JsonObject& jsonStatus); - void Process (); ///< Call from loop(), renders Input data + void Process (bool StayDark); void Poll (); ///< Call from loop(), renders Input data void GetDriverName (String & sDriverName) { sDriverName = "Effects"; } ///< get the name for the instantiated driver void SetBufferInfo (uint32_t BufferSize); @@ -145,6 +145,7 @@ class c_InputEffectEngine : public c_InputCommon float EffectBrightness = 1.0; /* Externally controlled effect brightness [0, 255] */ CRGB EffectColor = { 183, 0, 255 }; /* Externally controlled effect color */ bool StayDark = false; + bool Disabled = false; uint32_t effectMarqueePixelAdvanceCount = 1; uint32_t effectMarqueePixelLocation = 0; diff --git a/include/input/InputFPPRemote.h b/include/input/InputFPPRemote.h index eac29e209..dbfb2fab9 100644 --- a/include/input/InputFPPRemote.h +++ b/include/input/InputFPPRemote.h @@ -3,7 +3,7 @@ * InputFPPRemote.h * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -38,7 +38,7 @@ class c_InputFPPRemote : public c_InputCommon bool SetConfig (JsonObject& jsonConfig); ///< Set a new config in the driver void GetConfig (JsonObject& jsonConfig); ///< Get the current config used by the driver void GetStatus (JsonObject& jsonStatus); - void Process (); ///< Call from loop(), renders Input data + void Process (bool StayDark); void TaskProcess (); ///< Call from loop(), renders Input data void GetDriverName (String& sDriverName) { sDriverName = "FPP Remote"; } ///< get the name for the instantiated driver void SetBufferInfo (uint32_t BufferSize); @@ -54,6 +54,7 @@ class c_InputFPPRemote : public c_InputCommon String StatusType; bool StayDark = false; + bool Disabled = false; private: diff --git a/include/input/InputFPPRemotePlayEffect.hpp b/include/input/InputFPPRemotePlayEffect.hpp index e626e9d5a..d669ae93e 100644 --- a/include/input/InputFPPRemotePlayEffect.hpp +++ b/include/input/InputFPPRemotePlayEffect.hpp @@ -3,7 +3,7 @@ * InputFPPRemotePlayEffect.hpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -33,7 +33,7 @@ class c_InputFPPRemotePlayEffect : public c_InputFPPRemotePlayItem virtual void Start (String & FileName, float duration, uint32_t PlayCount); virtual void Stop (); virtual void Sync (String & FileName, float SecondsElapsed); - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void GetStatus (JsonObject & jsonStatus); virtual bool IsIdle () { return (pCurrentFsmState == &fsm_PlayEffect_state_Idle_imp); } @@ -48,7 +48,7 @@ class c_InputFPPRemotePlayEffect : public c_InputFPPRemotePlayItem fsm_PlayEffect_state* pCurrentFsmState = nullptr; FastTimer PlayEffectTimer; - + c_InputEffectEngine EffectsEngine; }; // c_InputFPPRemotePlayEffect diff --git a/include/input/InputFPPRemotePlayEffectFsm.hpp b/include/input/InputFPPRemotePlayEffectFsm.hpp index de5335d63..2ae6ca18d 100644 --- a/include/input/InputFPPRemotePlayEffectFsm.hpp +++ b/include/input/InputFPPRemotePlayEffectFsm.hpp @@ -3,7 +3,7 @@ * InputFPPRemotePlayEffectFsm.hpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -35,7 +35,7 @@ class fsm_PlayEffect_state fsm_PlayEffect_state() {} virtual ~fsm_PlayEffect_state() {} - virtual bool Poll () = 0; + virtual bool Poll (bool StayDark) = 0; virtual void Init (c_InputFPPRemotePlayEffect * Parent) = 0; virtual void GetStateName (String & sName) = 0; virtual void Start (String & FileName, float SecondsElapsed) = 0; @@ -56,7 +56,7 @@ class fsm_PlayEffect_state_Idle : public fsm_PlayEffect_state fsm_PlayEffect_state_Idle() {} virtual ~fsm_PlayEffect_state_Idle() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayEffect* Parent); virtual void GetStateName (String & sName) { sName = CN_Idle; } virtual void Start (String & FileName, float SecondsElapsed); @@ -73,7 +73,7 @@ class fsm_PlayEffect_state_PlayingEffect : public fsm_PlayEffect_state fsm_PlayEffect_state_PlayingEffect() {} virtual ~fsm_PlayEffect_state_PlayingEffect() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayEffect* Parent); virtual void GetStateName (String & sName) { sName = CN_Effect; } virtual void Start (String & FileName, float SecondsElapsed); diff --git a/include/input/InputFPPRemotePlayFile.hpp b/include/input/InputFPPRemotePlayFile.hpp index 3348fc82e..19006ef8c 100644 --- a/include/input/InputFPPRemotePlayFile.hpp +++ b/include/input/InputFPPRemotePlayFile.hpp @@ -3,7 +3,7 @@ * InputFPPRemotePlayFile.hpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -39,7 +39,7 @@ class c_InputFPPRemotePlayFile : public c_InputFPPRemotePlayItem virtual void Start (String & FileName, float SecondsElapsed, uint32_t RemainingPlayCount); virtual void Stop (); virtual void Sync (String& FileName, float SecondsElapsed); - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void GetStatus (JsonObject & jsonStatus); virtual bool IsIdle () { return (pCurrentFsmState == &fsm_PlayFile_state_Idle_imp); } @@ -73,11 +73,11 @@ class c_InputFPPRemotePlayFile : public c_InputFPPRemotePlayItem struct FrameControl_t { - uint32_t DataOffset = 0; - uint32_t ChannelsPerFrame = 0; - uint32_t FrameStepTimeMS = 1; - uint32_t TotalNumberOfFramesInSequence = 0; - uint32_t ElapsedPlayTimeMS = 0; + uint32_t DataOffset = 0; + uint32_t ChannelsPerFrame = 0; + uint32_t FrameStepTimeMS = 1; + uint32_t TotalNumberOfFramesInSequence = 0; + uint32_t ElapsedPlayTimeMS = 0; } FrameControl; diff --git a/include/input/InputFPPRemotePlayFileFsm.hpp b/include/input/InputFPPRemotePlayFileFsm.hpp index 673a6e531..e601a3e20 100644 --- a/include/input/InputFPPRemotePlayFileFsm.hpp +++ b/include/input/InputFPPRemotePlayFileFsm.hpp @@ -3,7 +3,7 @@ * InputFPPRemotePlayFileFsm.hpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -36,7 +36,7 @@ class fsm_PlayFile_state fsm_PlayFile_state() {} virtual ~fsm_PlayFile_state() {} - virtual bool Poll () = 0; + virtual bool Poll (bool StayDark) = 0; virtual void Init (c_InputFPPRemotePlayFile * Parent) = 0; virtual void GetStateName (String & sName) = 0; virtual void Start (String & FileName, float SecondsElapsed, uint32_t RemainingPlayCount) = 0; @@ -57,7 +57,7 @@ class fsm_PlayFile_state_Idle : public fsm_PlayFile_state fsm_PlayFile_state_Idle() {} virtual ~fsm_PlayFile_state_Idle() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayFile* Parent); virtual void GetStateName (String & sName) { sName = CN_Idle; } virtual void Start (String & FileName, float SecondsElapsed, uint32_t RemainingPlayCount); @@ -74,7 +74,7 @@ class fsm_PlayFile_state_Starting : public fsm_PlayFile_state fsm_PlayFile_state_Starting() {} virtual ~fsm_PlayFile_state_Starting() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayFile* Parent); virtual void GetStateName (String& sName) { sName = F ("Starting"); } virtual void Start (String& FileName, float SecondsElapsed, uint32_t RemainingPlayCount); @@ -91,7 +91,7 @@ class fsm_PlayFile_state_PlayingFile : public fsm_PlayFile_state fsm_PlayFile_state_PlayingFile() {} virtual ~fsm_PlayFile_state_PlayingFile() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayFile* Parent); virtual void GetStateName (String & sName) { sName = CN_File; } virtual void Start (String & FileName, float SecondsElapsed, uint32_t RemainingPlayCount); @@ -116,7 +116,7 @@ class fsm_PlayFile_state_Stopping : public fsm_PlayFile_state fsm_PlayFile_state_Stopping() {} virtual ~fsm_PlayFile_state_Stopping() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayFile* Parent); virtual void GetStateName (String& sName) { sName = F("Stopping"); } virtual void Start (String& FileName, float SecondsElapsed, uint32_t RemainingPlayCount); @@ -138,7 +138,7 @@ class fsm_PlayFile_state_Error : public fsm_PlayFile_state fsm_PlayFile_state_Error() {} virtual ~fsm_PlayFile_state_Error() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayFile* Parent); virtual void GetStateName (String& sName) { sName = F ("Error"); } virtual void Start (String& FileName, float SecondsElapsed, uint32_t RemainingPlayCount); diff --git a/include/input/InputFPPRemotePlayItem.hpp b/include/input/InputFPPRemotePlayItem.hpp index ac0b7b446..05a3b1e12 100644 --- a/include/input/InputFPPRemotePlayItem.hpp +++ b/include/input/InputFPPRemotePlayItem.hpp @@ -3,7 +3,7 @@ * InputFPPRemotePlayItem.hpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -28,7 +28,7 @@ class c_InputFPPRemotePlayItem c_InputFPPRemotePlayItem (c_InputMgr::e_InputChannelIds InputChannelId); virtual ~c_InputFPPRemotePlayItem (); - virtual bool Poll () = 0; + virtual bool Poll (bool StayDark) = 0; virtual void Start (String & FileName, float SecondsElapsed, uint32_t RemainingPlayCount) = 0; virtual void Stop () = 0; virtual void Sync (String & FileName, float SecondsElapsed) = 0; diff --git a/include/input/InputFPPRemotePlayList.hpp b/include/input/InputFPPRemotePlayList.hpp index a5e2078f2..bda8a63e9 100644 --- a/include/input/InputFPPRemotePlayList.hpp +++ b/include/input/InputFPPRemotePlayList.hpp @@ -3,7 +3,7 @@ * InputFPPRemotePlayList.hpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -34,7 +34,7 @@ class c_InputFPPRemotePlayList : public c_InputFPPRemotePlayItem virtual void Start (String & FileName, float SecondsElapsed, uint32_t PlayCount); virtual void Stop (); virtual void Sync (String & FileName, float SecondsElapsed); - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void GetStatus (JsonObject & jsonStatus); virtual bool IsIdle () { return (pCurrentFsmState == &fsm_PlayList_state_Idle_imp); } diff --git a/include/input/InputFPPRemotePlayListFsm.hpp b/include/input/InputFPPRemotePlayListFsm.hpp index 215143fc5..89d455bce 100644 --- a/include/input/InputFPPRemotePlayListFsm.hpp +++ b/include/input/InputFPPRemotePlayListFsm.hpp @@ -3,7 +3,7 @@ * InputFPPRemotePlayListFsm.hpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -35,7 +35,7 @@ class fsm_PlayList_state fsm_PlayList_state() {} virtual ~fsm_PlayList_state() {} - virtual bool Poll () = 0; + virtual bool Poll (bool StayDark) = 0; virtual void Init (c_InputFPPRemotePlayList * Parent) = 0; virtual void GetStateName (String & sName) = 0; virtual void Start (String & FileName, float SecondsElapsed, uint32_t PlayCount) = 0; @@ -56,7 +56,7 @@ class fsm_PlayList_state_WaitForStart : public fsm_PlayList_state fsm_PlayList_state_WaitForStart() {} virtual ~fsm_PlayList_state_WaitForStart() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayList* Parent); virtual void GetStateName (String & sName) { sName = CN_Idle; } virtual void Start (String & FileName, float SecondsElapsed, uint32_t PlayCount); @@ -72,7 +72,7 @@ class fsm_PlayList_state_Idle : public fsm_PlayList_state fsm_PlayList_state_Idle() {} virtual ~fsm_PlayList_state_Idle() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayList* Parent); virtual void GetStateName (String & sName) { sName = CN_Idle; } virtual void Start (String & FileName, float SecondsElapsed, uint32_t PlayCount); @@ -88,7 +88,7 @@ class fsm_PlayList_state_PlayingFile : public fsm_PlayList_state fsm_PlayList_state_PlayingFile() {} virtual ~fsm_PlayList_state_PlayingFile() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayList* Parent); virtual void GetStateName (String & sName) { sName = CN_File; } virtual void Start (String & FileName, float SecondsElapsed, uint32_t PlayCount); @@ -104,7 +104,7 @@ class fsm_PlayList_state_PlayingEffect : public fsm_PlayList_state fsm_PlayList_state_PlayingEffect() {} virtual ~fsm_PlayList_state_PlayingEffect() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayList* Parent); virtual void GetStateName (String & sName) { sName = CN_Effect; } virtual void Start (String & FileName, float SecondsElapsed, uint32_t PlayCount); @@ -120,7 +120,7 @@ class fsm_PlayList_state_Paused : public fsm_PlayList_state fsm_PlayList_state_Paused() {} virtual ~fsm_PlayList_state_Paused() {} - virtual bool Poll (); + virtual bool Poll (bool StayDark); virtual void Init (c_InputFPPRemotePlayList* Parent); virtual void GetStateName (String & sName) { sName = CN_Paused; } virtual void Start (String & FileName, float SecondsElapsed, uint32_t PlayCount); diff --git a/include/input/InputMQTT.h b/include/input/InputMQTT.h index d9ed24440..46c77f665 100644 --- a/include/input/InputMQTT.h +++ b/include/input/InputMQTT.h @@ -3,7 +3,7 @@ * InputMQTT.h * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -41,7 +41,7 @@ class c_InputMQTT : public c_InputCommon bool SetConfig (JsonObject& jsonConfig); ///< Set a new config in the driver void GetConfig (JsonObject& jsonConfig); ///< Get the current config used by the driver void GetStatus (JsonObject& jsonStatus); - void Process (); ///< Call from loop(), renders Input data + void Process (bool StayDark); void GetDriverName (String& sDriverName) { sDriverName = "MQTT"; } ///< get the name for the instantiated driver void SetBufferInfo (uint32_t BufferSize); void NetworkStateChanged (bool IsConnected); // used by poorly designed rx functions diff --git a/include/input/externalInput.h b/include/input/externalInput.h index eef7a6e7e..cb848b772 100644 --- a/include/input/externalInput.h +++ b/include/input/externalInput.h @@ -1,6 +1,22 @@ -// only allow the file to be included once. #pragma once +/* externalInput.h +* +* Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver +* Copyright (c) 2021, 2025 Shelby Merrick +* http://www.forkineye.com +* +* This program is provided free for you to use in any way that you wish, +* subject to the laws and regulations where you are using it. Due diligence +* is strongly suggested before using this code. Please give credit where due. +* +* The Author makes no warranty of any kind, express or implied, with regard +* to this program or the documentation contained in this document. The +* Author shall not be liable in any event for incidental or consequential +* damages in connection with, or arising out of, the furnishing, performance +* or use of these programs. +* +*/ #include "ESPixelStick.h" @@ -26,7 +42,7 @@ class c_ExternalInput final }; void Init (uint32_t iInputId, uint32_t iPinId, Polarity_t Poliarity, String & sName); - void Poll (void); + void Poll (bool StayDark); void GetConfig (JsonObject JsonData); void GetStatistics (JsonObject JsonData); void ProcessConfig (JsonObject JsonData); diff --git a/src/input/InputAlexa.cpp b/src/input/InputAlexa.cpp index 136dba838..c86623d17 100644 --- a/src/input/InputAlexa.cpp +++ b/src/input/InputAlexa.cpp @@ -2,7 +2,7 @@ * InputAlexa.cpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -100,12 +100,12 @@ void c_InputAlexa::GetStatus (JsonObject& /* jsonStatus */) } // GetStatus //----------------------------------------------------------------------------- -void c_InputAlexa::Process () +void c_InputAlexa::Process (bool StayDark) { // DEBUG_START; if (IsInputChannelActive) { - pEffectsEngine->Process (); + pEffectsEngine->Process (StayDark); } // DEBUG_END; diff --git a/src/input/InputDDP.cpp b/src/input/InputDDP.cpp index 000f138bb..a0790a690 100644 --- a/src/input/InputDDP.cpp +++ b/src/input/InputDDP.cpp @@ -2,7 +2,7 @@ * c_InputDDP.cpp * * Project: c_InputDDP - Asynchronous DDP library for Arduino ESP8266 and ESP32 -* Copyright (c) 2019, 2022 Daniel Kulp, Shelby Merrick +* Copyright (c) 2019, 2025 Daniel Kulp, Shelby Merrick * * This program is provided free for you to use in any way that you wish, * subject to the laws and regulations where you are using it. Due diligence @@ -192,12 +192,17 @@ void c_InputDDP::ProcessReceivedUdpPacket(AsyncUDPPacket ReceivedPacket) } // ProcessReceivedUdpPacket //----------------------------------------------------------------------------- -void c_InputDDP::Process () +void c_InputDDP::Process (bool StayDark) { // DEBUG_START; do // once { + if(!IsInputChannelActive || StayDark) + { + break; + } + if (PacketBuffer.PacketBufferStatus != PacketBufferStatus_t::BufferIsFilled) { // DEBUG_V ("There is nothing in the buffer for us to porcess"); diff --git a/src/input/InputDisabled.cpp b/src/input/InputDisabled.cpp index 2944f4fff..80d7c0c13 100644 --- a/src/input/InputDisabled.cpp +++ b/src/input/InputDisabled.cpp @@ -2,7 +2,7 @@ * InputDisabled.cpp - InputDisabled NULL driver code for ESPixelStick * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -92,7 +92,7 @@ void c_InputDisabled::GetConfig(ArduinoJson::JsonObject & jsonConfig) } // GetConfig //---------------------------------------------------------------------------- -void c_InputDisabled::Process() +void c_InputDisabled::Process(bool /* StayDark */) { // DEBUG_START; diff --git a/src/input/InputE131.cpp b/src/input/InputE131.cpp index a687f8e28..d4d22abfb 100644 --- a/src/input/InputE131.cpp +++ b/src/input/InputE131.cpp @@ -2,7 +2,7 @@ * E131Input.cpp - Code to wrap ESPAsyncE131 for input * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -119,7 +119,7 @@ void c_InputE131::GetStatus (JsonObject & jsonStatus) } // GetStatus //----------------------------------------------------------------------------- -void c_InputE131::Process () +void c_InputE131::Process (bool /* StayDark */) { // DEBUG_START; diff --git a/src/input/InputEffectEngine.cpp b/src/input/InputEffectEngine.cpp index d3fa1d8e7..7d12b7873 100644 --- a/src/input/InputEffectEngine.cpp +++ b/src/input/InputEffectEngine.cpp @@ -373,10 +373,10 @@ void c_InputEffectEngine::PollFlash () } // PollFlash //----------------------------------------------------------------------------- -void c_InputEffectEngine::Process () +void c_InputEffectEngine::Process (bool _StayDark) { // DEBUG_START; - + Disabled = _StayDark; // DEBUG_V (String ("HasBeenInitialized: ") + HasBeenInitialized); // DEBUG_V (String ("PixelCount: ") + PixelCount); #ifndef ARDUINO_ARCH_ESP32 @@ -440,7 +440,7 @@ void c_InputEffectEngine::Poll () #ifdef ARDUINO_ARCH_ESP32 do // once { - if (!HasBeenInitialized) + if (!HasBeenInitialized || Disabled) { break; } diff --git a/src/input/InputFPPRemote.cpp b/src/input/InputFPPRemote.cpp index 59e85bdcb..2ae889ca4 100644 --- a/src/input/InputFPPRemote.cpp +++ b/src/input/InputFPPRemote.cpp @@ -234,9 +234,10 @@ void c_InputFPPRemote::PlayNextFile () } // PlayNextFile //----------------------------------------------------------------------------- -void c_InputFPPRemote::Process () +void c_InputFPPRemote::Process (bool StayDark) { // DEBUG_START; + Disabled = StayDark; #ifndef ARDUINO_ARCH_ESP32 TaskProcess(); #else @@ -257,7 +258,7 @@ void c_InputFPPRemote::Process () void c_InputFPPRemote::TaskProcess () { // DEBUG_START; - if (!IsInputChannelActive || StayDark) + if (!IsInputChannelActive || StayDark || Disabled) { // DEBUG_V ("dont do anything if the channel is not active"); StopPlaying (); @@ -289,7 +290,7 @@ bool c_InputFPPRemote::Poll () bool Response = false; if(pInputFPPRemotePlayItem) { - Response = pInputFPPRemotePlayItem->Poll (); + Response = pInputFPPRemotePlayItem->Poll (Disabled); } // DEBUG_END; @@ -387,7 +388,7 @@ void c_InputFPPRemote::StopPlaying () while (!pInputFPPRemotePlayItem->IsIdle ()) { - pInputFPPRemotePlayItem->Poll (); + pInputFPPRemotePlayItem->Poll (Disabled); // DEBUG_V(); pInputFPPRemotePlayItem->Stop (); } diff --git a/src/input/InputFPPRemotePlayEffect.cpp b/src/input/InputFPPRemotePlayEffect.cpp index 0e8e29ff3..47e199bd1 100644 --- a/src/input/InputFPPRemotePlayEffect.cpp +++ b/src/input/InputFPPRemotePlayEffect.cpp @@ -2,7 +2,7 @@ * InputFPPRemotePlayEffect.cpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -82,11 +82,11 @@ void c_InputFPPRemotePlayEffect::Sync (String& FileName, float SecondsElapsed) } // Sync //----------------------------------------------------------------------------- -bool c_InputFPPRemotePlayEffect::Poll () +bool c_InputFPPRemotePlayEffect::Poll (bool StayDark) { // DEBUG_START; - return pCurrentFsmState->Poll (); + return pCurrentFsmState->Poll (StayDark); // DEBUG_END; diff --git a/src/input/InputFPPRemotePlayEffectFsm.cpp b/src/input/InputFPPRemotePlayEffectFsm.cpp index 5c9135d4c..a0ede7350 100644 --- a/src/input/InputFPPRemotePlayEffectFsm.cpp +++ b/src/input/InputFPPRemotePlayEffectFsm.cpp @@ -2,7 +2,7 @@ * InputFPPRemoteFsm.cpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -23,7 +23,7 @@ #include "utility/SaferStringConversion.hpp" //----------------------------------------------------------------------------- -bool fsm_PlayEffect_state_Idle::Poll () +bool fsm_PlayEffect_state_Idle::Poll (bool /* StayDark */) { // DEBUG_START; @@ -31,7 +31,7 @@ bool fsm_PlayEffect_state_Idle::Poll () // DEBUG_END; return false; - + } // fsm_PlayEffect_state_Idle::Poll //----------------------------------------------------------------------------- @@ -118,12 +118,12 @@ void fsm_PlayEffect_state_Idle::GetStatus (JsonObject& jsonStatus) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool fsm_PlayEffect_state_PlayingEffect::Poll () +bool fsm_PlayEffect_state_PlayingEffect::Poll (bool StayDark) { // DEBUG_START; p_InputFPPRemotePlayEffect->EffectsEngine.SetBufferInfo (OutputMgr.GetBufferUsedSize()); - p_InputFPPRemotePlayEffect->EffectsEngine.Process (); + p_InputFPPRemotePlayEffect->EffectsEngine.Process (StayDark); if (p_InputFPPRemotePlayEffect->PlayEffectTimer.IsExpired()) { diff --git a/src/input/InputFPPRemotePlayFile.cpp b/src/input/InputFPPRemotePlayFile.cpp index 41f39b0e5..834563f0a 100644 --- a/src/input/InputFPPRemotePlayFile.cpp +++ b/src/input/InputFPPRemotePlayFile.cpp @@ -2,7 +2,7 @@ * InputFPPRemotePlayFile.cpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -98,7 +98,7 @@ c_InputFPPRemotePlayFile::~c_InputFPPRemotePlayFile () for (uint32_t LoopCount = 10000; (LoopCount != 0) && (!IsIdle ()); LoopCount--) { Stop (); - Poll (); + Poll (false); } // DEBUG_END; @@ -148,7 +148,7 @@ void c_InputFPPRemotePlayFile::Sync (String & FileName, float SecondsElapsed) } // Sync //----------------------------------------------------------------------------- -bool c_InputFPPRemotePlayFile::Poll () +bool c_InputFPPRemotePlayFile::Poll (bool StayDark) { // xDEBUG_START; @@ -156,7 +156,7 @@ bool c_InputFPPRemotePlayFile::Poll () PollDetectionCounter = 0; // TimerPoll (); - return pCurrentFsmState->Poll (); + return pCurrentFsmState->Poll (StayDark); // xDEBUG_END; diff --git a/src/input/InputFPPRemotePlayFileFsm.cpp b/src/input/InputFPPRemotePlayFileFsm.cpp index 9b5f9a03f..133634b14 100644 --- a/src/input/InputFPPRemotePlayFileFsm.cpp +++ b/src/input/InputFPPRemotePlayFileFsm.cpp @@ -2,7 +2,7 @@ * InputFPPRemotePlayFileFsm.cpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -23,7 +23,7 @@ #include "service/FPPDiscovery.h" //----------------------------------------------------------------------------- -bool fsm_PlayFile_state_Idle::Poll () +bool fsm_PlayFile_state_Idle::Poll (bool /* StayDark */) { // DEBUG_START; @@ -110,11 +110,18 @@ bool fsm_PlayFile_state_Idle::Sync (String& FileName, float ElapsedSeconds) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool fsm_PlayFile_state_Starting::Poll () +bool fsm_PlayFile_state_Starting::Poll (bool StayDark) { // DEBUG_START; - p_Parent->fsm_PlayFile_state_PlayingFile_imp.Init (p_Parent); + if(StayDark) + { + p_Parent->fsm_PlayFile_state_Stopping_imp.Init (p_Parent); + } + else + { + p_Parent->fsm_PlayFile_state_PlayingFile_imp.Init (p_Parent); + } // DEBUG_V (String (" RemainingPlayCount: ") + p_Parent->RemainingPlayCount); // DEBUG_V (String ("TotalNumberOfFramesInSequence: ") + String (p_Parent->FrameControl.TotalNumberOfFramesInSequence)); @@ -195,7 +202,7 @@ bool fsm_PlayFile_state_Starting::Sync (String& FileName, float ElapsedSeconds) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool fsm_PlayFile_state_PlayingFile::Poll () +bool fsm_PlayFile_state_PlayingFile::Poll (bool StayDark) { // xDEBUG_START; @@ -203,7 +210,7 @@ bool fsm_PlayFile_state_PlayingFile::Poll () do // once { - if(c_FileMgr::INVALID_FILE_HANDLE == p_Parent->FileHandleForFileBeingPlayed) + if(!StayDark || (c_FileMgr::INVALID_FILE_HANDLE == p_Parent->FileHandleForFileBeingPlayed)) { // DEBUG_V("Bad FileHandleForFileBeingPlayed"); Stop(); @@ -497,7 +504,7 @@ bool fsm_PlayFile_state_PlayingFile::Sync (String& FileName, float ElapsedSecond //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool fsm_PlayFile_state_Stopping::Poll () +bool fsm_PlayFile_state_Stopping::Poll (bool /* StayDark */) { // DEBUG_START; @@ -587,7 +594,7 @@ bool fsm_PlayFile_state_Stopping::Sync (String&, float) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool fsm_PlayFile_state_Error::Poll () +bool fsm_PlayFile_state_Error::Poll (bool /* StayDark */) { // xDEBUG_START; diff --git a/src/input/InputFPPRemotePlayList.cpp b/src/input/InputFPPRemotePlayList.cpp index 02fbb0796..9289b6a32 100644 --- a/src/input/InputFPPRemotePlayList.cpp +++ b/src/input/InputFPPRemotePlayList.cpp @@ -2,7 +2,7 @@ * InputFPPRemotePlayList.cpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -77,11 +77,11 @@ void c_InputFPPRemotePlayList::Sync (String & FileName, float ElapsedSeconds) } // Sync //----------------------------------------------------------------------------- -bool c_InputFPPRemotePlayList::Poll () +bool c_InputFPPRemotePlayList::Poll (bool StayDark) { // DEBUG_START; - return pCurrentFsmState->Poll (); + return pCurrentFsmState->Poll (StayDark); // DEBUG_END; diff --git a/src/input/InputFPPRemotePlayListFsm.cpp b/src/input/InputFPPRemotePlayListFsm.cpp index 4b251c0d1..d16a5f70c 100644 --- a/src/input/InputFPPRemotePlayListFsm.cpp +++ b/src/input/InputFPPRemotePlayListFsm.cpp @@ -2,7 +2,7 @@ * InputFPPRemotePlayListFsm.cpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -25,7 +25,7 @@ #include "input/InputFPPRemotePlayEffect.hpp" //----------------------------------------------------------------------------- -bool fsm_PlayList_state_WaitForStart::Poll () +bool fsm_PlayList_state_WaitForStart::Poll (bool /* StayDark */) { // DEBUG_START; @@ -33,7 +33,7 @@ bool fsm_PlayList_state_WaitForStart::Poll () // DEBUG_END; return false; - + } // fsm_PlayList_state_Idle::Poll //----------------------------------------------------------------------------- @@ -94,7 +94,7 @@ void fsm_PlayList_state_WaitForStart::GetStatus (JsonObject& jsonStatus) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool fsm_PlayList_state_Idle::Poll () +bool fsm_PlayList_state_Idle::Poll (bool /* StayDark */) { // DEBUG_START; @@ -153,12 +153,12 @@ void fsm_PlayList_state_Idle::GetStatus (JsonObject& jsonStatus) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool fsm_PlayList_state_PlayingFile::Poll () +bool fsm_PlayList_state_PlayingFile::Poll (bool StayDark) { // xDEBUG_START; - bool Response = pInputFPPRemotePlayList->pInputFPPRemotePlayItem->Poll (); - + bool Response = pInputFPPRemotePlayList->pInputFPPRemotePlayItem->Poll (StayDark); + if (pInputFPPRemotePlayList->pInputFPPRemotePlayItem->IsIdle ()) { // DEBUG_V ("Done with all entries"); @@ -230,11 +230,11 @@ void fsm_PlayList_state_PlayingFile::GetStatus (JsonObject& jsonStatus) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool fsm_PlayList_state_PlayingEffect::Poll () +bool fsm_PlayList_state_PlayingEffect::Poll (bool StayDark) { // DEBUG_START; - pInputFPPRemotePlayList->pInputFPPRemotePlayItem->Poll (); + pInputFPPRemotePlayList->pInputFPPRemotePlayItem->Poll (StayDark); if (pInputFPPRemotePlayList->pInputFPPRemotePlayItem->IsIdle ()) { @@ -309,7 +309,7 @@ void fsm_PlayList_state_PlayingEffect::GetStatus (JsonObject& jsonStatus) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool fsm_PlayList_state_Paused::Poll () +bool fsm_PlayList_state_Paused::Poll (bool /* StayDark */) { // DEBUG_START; diff --git a/src/input/InputMQTT.cpp b/src/input/InputMQTT.cpp index ffa1c5cf9..1e14dbc8f 100644 --- a/src/input/InputMQTT.cpp +++ b/src/input/InputMQTT.cpp @@ -2,7 +2,7 @@ * InputMQTT.cpp * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -154,7 +154,7 @@ void c_InputMQTT::GetStatus (JsonObject & jsonStatus) } // GetStatus //----------------------------------------------------------------------------- -void c_InputMQTT::Process () +void c_InputMQTT::Process (bool StayDark) { // DEBUG_START; @@ -163,12 +163,12 @@ void c_InputMQTT::Process () if (nullptr != pEffectsEngine) { // DEBUG_V (""); - pEffectsEngine->Process (); + pEffectsEngine->Process (StayDark); } else if (nullptr != pPlayFileEngine) { - pPlayFileEngine->Poll (); + pPlayFileEngine->Poll (StayDark); } else { diff --git a/src/input/InputMgr.cpp b/src/input/InputMgr.cpp index 6eed931db..312f6732c 100644 --- a/src/input/InputMgr.cpp +++ b/src/input/InputMgr.cpp @@ -637,7 +637,7 @@ void c_InputMgr::Process () break; } - ExternalInput.Poll (); + ExternalInput.Poll (false); if (NO_CONFIG_NEEDED != ConfigLoadNeeded) { @@ -662,13 +662,13 @@ void c_InputMgr::Process () continue; } // DEBUG_V(String("pInputChannelDriver: 0x") + String(uint32_t(CurrentInput.pInputChannelDriver), HEX)); - CurrentInput.pInputChannelDriver->Process (); + CurrentInput.pInputChannelDriver->Process (aBlankTimerIsRunning); if (!BlankTimerHasExpired (CurrentInput.pInputChannelDriver->GetInputChannelId())) { // DEBUG_V (String ("Blank Timer is running: ") + String (CurrentInput.pInputChannelDriver->GetInputChannelId ())); aBlankTimerIsRunning = true; - break; + // break; } } diff --git a/src/input/externalInput.cpp b/src/input/externalInput.cpp index b6d578ba0..d23644fe4 100644 --- a/src/input/externalInput.cpp +++ b/src/input/externalInput.cpp @@ -1,6 +1,22 @@ /* - * Manage a single input line - */ +* externalInput.cpp +* +* Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver +* Copyright (c) 2021, 2025 Shelby Merrick +* http://www.forkineye.com +* +* This program is provided free for you to use in any way that you wish, +* subject to the laws and regulations where you are using it. Due diligence +* is strongly suggested before using this code. Please give credit where due. +* +* The Author makes no warranty of any kind, express or implied, with regard +* to this program or the documentation contained in this document. The +* Author shall not be liable in any event for incidental or consequential +* damages in connection with, or arising out of, the furnishing, performance +* or use of these programs. +* +* PlayFile object used to parse and play an effect +*/ #include "input/externalInput.h" #include "input/InputMgr.hpp" #include "FileMgr.hpp" @@ -109,10 +125,10 @@ void c_ExternalInput::ProcessConfig (JsonObject JsonData) } // ProcessConfig /*****************************************************************************/ -void c_ExternalInput::Poll (void) +void c_ExternalInput::Poll (bool StayDark) { // DEBUG_START; - + CurrentFsmState->Poll (*this); // DEBUG_END;