From dc12ccd367946e231d1005a7ec02fa740bf2258c Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 10 Sep 2026 21:52:56 -0300 Subject: [PATCH 1/8] fix(HDMI): Prevent HDMI CEC from powering on display at boot --- src/boot/FPPINIT.cpp | 12 ++++-- src/boot/FPPINIT.h | 1 + src/boot/FPPINIT_Config.cpp | 85 +++++++++++++++++++++++++++++++++++++ upgrade/144/upgrade.sh | 24 +++++++++++ www/common/settings.php | 5 +++ www/settings.json | 14 ++++++ 6 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 upgrade/144/upgrade.sh diff --git a/src/boot/FPPINIT.cpp b/src/boot/FPPINIT.cpp index 5b5cc5591..088e41072 100644 --- a/src/boot/FPPINIT.cpp +++ b/src/boot/FPPINIT.cpp @@ -241,7 +241,7 @@ int main(int argc, char* argv[]) { // dup2 replaces that fd before we print anything, so this capture // still works even though the parent shell redirected us away. teeOutput(logFile, "fppinit", "Audio", getpid()); - } else if (action == "configureBBB" || action == "applyThermal" || action == "resetThermal" || action == "installKiosk" || action == "setupPiRTC") { + } else if (action == "configureBBB" || action == "applyThermal" || action == "resetThermal" || action == "installKiosk" || action == "setupPiRTC" || action == "setupHDMICEC") { // Same gap as setupNetwork: invoked directly via PHP exec(), output // otherwise lives only in that request's $output/HTTP response. teeOutput(logFile, "fppinit", "Config", getpid()); @@ -283,6 +283,7 @@ int main(int argc, char* argv[]) { // After DetectCape() above, so a cape shipping DisablePiRTC in its // defaultSettings is honoured on the boot it is first detected on. setupPiRTCConfig(); + setupHDMICECConfig(); int reboot = getRawSettingInt("rebootFlag", 0); if (reboot && !needReboot) { printf("FPP - Clearing reboot flags\n"); @@ -472,9 +473,12 @@ int main(int argc, char* argv[]) { resetThermalSettings(); } else if (action == "installKiosk") { installKiosk(); - } else if (action == "setupPiRTC") { - // The UI's "reboot": 1 on DisablePiRTC prompts the user; don't reboot here. - setupPiRTCConfig(false); + } else if (action == "setupPiRTC") { + // The UI's "reboot": 1 on DisablePiRTC prompts the user; don't reboot here. + setupPiRTCConfig(false); + } else if (action == "setupHDMICEC") { + // The UI's "reboot": 1 on DisableHDMICECInit prompts the user; don't reboot here. + setupHDMICECConfig(false); } else if (action == "setupNetwork") { PutFileContents(networkSetupMut, "1"); setupNetwork(true); diff --git a/src/boot/FPPINIT.h b/src/boot/FPPINIT.h index 9ee2e6f48..346e1f0d8 100644 --- a/src/boot/FPPINIT.h +++ b/src/boot/FPPINIT.h @@ -94,6 +94,7 @@ void startZRAMSwap(); void startDiskSwap(); void setupChannelOutputs(); void setupPiRTCConfig(bool rebootIfChanged = true); +void setupHDMICECConfig(bool rebootIfChanged = true); void handleRebootActions(); // --------------------------------------------------------------------------- diff --git a/src/boot/FPPINIT_Config.cpp b/src/boot/FPPINIT_Config.cpp index 9deac6ffb..8df5afcb5 100644 --- a/src/boot/FPPINIT_Config.cpp +++ b/src/boot/FPPINIT_Config.cpp @@ -991,6 +991,17 @@ static void migrateMultiSyncDefaultToMulticast() { } } +// Migrate DisableHDMICECInit to its new default (1) for existing +// installs that have never saved the setting. Explicit 0 stays 0. +// Idempotent; safe to re-run. Used by both upgrade/144 (normal +// in-place upgrades) and checkConfigMigrations (FPPOS reflash). +static void migrateHDMICECDefault() { + std::string existing; + if (!getRawSetting("DisableHDMICECInit", existing)) { + setRawSetting("DisableHDMICECInit", "1"); + } +} + // Config-state migrations that must survive an FPPOS reflash, gated on the // same /fppos_upgraded marker as checkInstallPackages() (touched by // upgradeOS-part2.sh, which is always sourced from the target image being @@ -1003,6 +1014,7 @@ static void migrateMultiSyncDefaultToMulticast() { void checkConfigMigrations() { if (FileExists("/fppos_upgraded")) { migrateMultiSyncDefaultToMulticast(); + migrateHDMICECDefault(); } } @@ -1256,6 +1268,79 @@ void setupPiRTCConfig(bool rebootIfChanged) { #endif } +#ifdef PLATFORM_PI +// Suppress the initial CEC Active Source at boot that wakes projectors/TVs +// (e.g. Epson L210SF, issue #2938). When enabled, adds hdmi_ignore_cec_init=1 +// to config.txt. Unlike hdmi_ignore_cec=1 this only suppresses the boot +// broadcast — the CEC plugin can still power the display on/off on demand. +// +// Managed block pattern mirrors applyDisablePiRTCBlock above: strip every +// prior copy (including truncated), remember first insertion point, and +// re-insert ahead of the cape variant block to avoid leapfrog reboot loops. +static const std::string HDMI_CEC_BLOCK_BEGIN = "# FPP HDMI CEC - BEGIN (managed by fppinit, do not edit)"; +static const std::string HDMI_CEC_BLOCK_END = "# FPP HDMI CEC - END"; + +// --- BEGIN applyDisableHDMICECBlock --- +static bool applyDisableHDMICECBlock(std::string& content, bool disable) { + const std::string orig = content; + std::string desired; + if (disable) { + desired = HDMI_CEC_BLOCK_BEGIN + "\n[all]\nhdmi_ignore_cec_init=1\n[all]\n" + HDMI_CEC_BLOCK_END + "\n"; + } + + size_t at = std::string::npos; + size_t begin = content.find(HDMI_CEC_BLOCK_BEGIN); + while (begin != std::string::npos) { + if (at == std::string::npos) { + at = begin; + } + size_t end = content.find(HDMI_CEC_BLOCK_END, begin); + end = (end == std::string::npos) ? content.length() + : end + HDMI_CEC_BLOCK_END.length(); + if (end < content.length() && content[end] == '\n') { + ++end; + } + content.erase(begin, end - begin); + begin = content.find(HDMI_CEC_BLOCK_BEGIN); + } + + if (!desired.empty()) { + if (at == std::string::npos) { + at = content.find(CAPE_VARIANT_BLOCK_BEGIN); + if (at == std::string::npos) { + while (!content.empty() && content.back() == '\n') { + content.pop_back(); + } + content += "\n\n"; + at = content.length(); + } else { + desired += "\n"; + } + } + content.insert(at, desired); + } + return content != orig; +} +// --- END applyDisableHDMICECBlock --- +#endif + +void setupHDMICECConfig(bool rebootIfChanged) { +#ifdef PLATFORM_PI + std::string content = GetFileContents("/boot/firmware/config.txt"); + if (content.empty()) { + return; + } + if (applyDisableHDMICECBlock(content, getRawSettingInt("DisableHDMICECInit", 1) != 0)) { + PutFileContents("/boot/firmware/config.txt", content); + printf("FPP - HDMI CEC configuration changed in config.txt\n"); + if (rebootIfChanged) { + printf("\n\nRebooting to load new settings.\n\n"); + exec("/usr/sbin/reboot"); + } + } +#endif +} + void setupChannelOutputs() { #ifdef PLATFORM_PI bool hasDPI = false; diff --git a/upgrade/144/upgrade.sh b/upgrade/144/upgrade.sh new file mode 100644 index 000000000..7bf5f1c31 --- /dev/null +++ b/upgrade/144/upgrade.sh @@ -0,0 +1,24 @@ +#!/bin/bash +##################################### +# Upgrade 144: Prevent HDMI CEC At Boot by default +# +# Issue #2938: FPP 10 (Trixie, 6.18 vc4-kms-v3d) wakes CEC projectors/TVs +# at boot via vc4-hdmi-cec Active Source. The new DisableHDMICECInit +# toggle adds hdmi_ignore_cec_init=1 to config.txt when enabled. +# +# For fresh installs the new default in www/settings.json (1) already +# applies. For existing installs that have never saved the setting +# (no line in /home/fpp/media/settings), pin it to 1 now so the +# projector stays in standby after an upgrade. Explicit 0 stays 0. +# +# Handles normal in-place upgrades via scripts/upgrade_config. +# FPPOS-reflash / restore path is handled separately in +# src/boot/FPPINIT_Config.cpp:checkConfigMigrations(). +##################################### + +BINDIR=$(cd $(dirname $0) && pwd) +. ${BINDIR}/../../scripts/common + +if [ -z "$(getSetting DisableHDMICECInit)" ]; then + setSetting DisableHDMICECInit 1 +fi diff --git a/www/common/settings.php b/www/common/settings.php index de893caeb..b673c40c3 100644 --- a/www/common/settings.php +++ b/www/common/settings.php @@ -434,6 +434,11 @@ function ApplySetting($setting, $value) // "reboot": 1, so the UI is already prompting for that. exec("sudo " . $settings['fppDir'] . "/src/fppinit setupPiRTC", $output); break; + case 'DisableHDMICECInit': + // fppinit owns the config.txt block. The setting is declared + // "reboot": 1, so the UI already prompts for reboot. + exec("sudo " . $settings['fppDir'] . "/src/fppinit setupHDMICEC", $output); + break; case 'screensaver': SetupScreenBlanking($value); break; diff --git a/www/settings.json b/www/settings.json index b1c533d8d..76d25ecd6 100644 --- a/www/settings.json +++ b/www/settings.json @@ -183,6 +183,7 @@ "settings": [ "VideoOutput", "ForceHDMI", + "DisableHDMICECInit", "EnableBBBHDMI", "ForceHDMIResolution", "ForceHDMIResolutionPort2", @@ -1616,6 +1617,19 @@ ], "type": "checkbox" }, + "DisableHDMICECInit": { + "name": "DisableHDMICECInit", + "description": "Prevent HDMI CEC At Boot", + "gatherStats": true, + "tip": "When enabled, adds hdmi_ignore_cec_init=1 to config.txt to suppress the initial CEC Active Source that wakes projectors/TVs at boot (e.g. after a power outage). CEC control via the CEC plugin still works.", + "reboot": 1, + "level": 1, + "platforms": [ + "Raspberry Pi" + ], + "type": "checkbox", + "default": "1" + }, "GPIOFan": { "name": "GPIOFan", "description": "GPIO 14 Fan Control", From bdf238f2b714d4f1a2bbee2a218297614b0bf3c4 Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 10 Sep 2026 22:21:45 -0300 Subject: [PATCH 2/8] fix(HDMI): Prevent HDMI CEC from powering on display at boot - Fix Indentation --- src/boot/FPPINIT.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/boot/FPPINIT.cpp b/src/boot/FPPINIT.cpp index 088e41072..9f6b962b9 100644 --- a/src/boot/FPPINIT.cpp +++ b/src/boot/FPPINIT.cpp @@ -473,12 +473,12 @@ int main(int argc, char* argv[]) { resetThermalSettings(); } else if (action == "installKiosk") { installKiosk(); - } else if (action == "setupPiRTC") { - // The UI's "reboot": 1 on DisablePiRTC prompts the user; don't reboot here. - setupPiRTCConfig(false); - } else if (action == "setupHDMICEC") { - // The UI's "reboot": 1 on DisableHDMICECInit prompts the user; don't reboot here. - setupHDMICECConfig(false); + } else if (action == "setupPiRTC") { + // The UI's "reboot": 1 on DisablePiRTC prompts the user; don't reboot here. + setupPiRTCConfig(false); + } else if (action == "setupHDMICEC") { + // The UI's "reboot": 1 on DisableHDMICECInit prompts the user; don't reboot here. + setupHDMICECConfig(false); } else if (action == "setupNetwork") { PutFileContents(networkSetupMut, "1"); setupNetwork(true); From 04ca9a789a47f4ec4d6b913aebcf9b375c3b9e6d Mon Sep 17 00:00:00 2001 From: Ryan Date: Fri, 11 Sep 2026 04:52:22 -0300 Subject: [PATCH 3/8] fix(HDMI): Prevent HDMI CEC from powering on display at boot --- src/boot/FPPINIT_Config.cpp | 11 +++++++---- upgrade/144/upgrade.sh | 17 +++++++++++++++++ www/settings.json | 3 +-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/boot/FPPINIT_Config.cpp b/src/boot/FPPINIT_Config.cpp index 8df5afcb5..9f0acb3fe 100644 --- a/src/boot/FPPINIT_Config.cpp +++ b/src/boot/FPPINIT_Config.cpp @@ -991,10 +991,13 @@ static void migrateMultiSyncDefaultToMulticast() { } } -// Migrate DisableHDMICECInit to its new default (1) for existing -// installs that have never saved the setting. Explicit 0 stays 0. -// Idempotent; safe to re-run. Used by both upgrade/144 (normal -// in-place upgrades) and checkConfigMigrations (FPPOS reflash). +// Materialize DisableHDMICECInit=1 for installs that have never saved +// the setting. Behavior is already controlled by the fallback in +// setupHDMICECConfig (getRawSettingInt(...,1)) and the default in +// www/settings.json (1), so this only persists the implicit default +// to the settings file for tooling that reads raw. Explicit 0 stays 0. +// Idempotent; safe to re-run. Paired with upgrade/144 for normal +// in-place upgrades; this covers FPPOS reflash. static void migrateHDMICECDefault() { std::string existing; if (!getRawSetting("DisableHDMICECInit", existing)) { diff --git a/upgrade/144/upgrade.sh b/upgrade/144/upgrade.sh index 7bf5f1c31..894a947f0 100644 --- a/upgrade/144/upgrade.sh +++ b/upgrade/144/upgrade.sh @@ -21,4 +21,21 @@ BINDIR=$(cd $(dirname $0) && pwd) if [ -z "$(getSetting DisableHDMICECInit)" ]; then setSetting DisableHDMICECInit 1 + # Pre-seed the config.txt block so the next boot does not trigger + # the extra reboot that setupHDMICECConfig(rebootIfChanged=true) would + # otherwise do for every Pi. Idempotent and Pi-only. + BOOTCONF="" + if [ -f /boot/firmware/config.txt ]; then + BOOTCONF="/boot/firmware/config.txt" + elif [ -f /boot/config.txt ]; then + BOOTCONF="/boot/config.txt" + fi + if [ -n "$BOOTCONF" ] && ! grep -q "FPP HDMI CEC - BEGIN" "$BOOTCONF" 2>/dev/null; then + # Insert ahead of cape variant block if present, else append + if grep -q "FPP Cape Overlay Variants - BEGIN" "$BOOTCONF" 2>/dev/null; then + awk 'BEGIN{p=0} /FPP Cape Overlay Variants - BEGIN/ && p==0 {print "# FPP HDMI CEC - BEGIN (managed by fppinit, do not edit)"; print "[all]"; print "hdmi_ignore_cec_init=1"; print "[all]"; print "# FPP HDMI CEC - END"; print ""; p=1} {print}' "$BOOTCONF" > "${BOOTCONF}.tmp" && mv "${BOOTCONF}.tmp" "$BOOTCONF" + else + printf "\n# FPP HDMI CEC - BEGIN (managed by fppinit, do not edit)\n[all]\nhdmi_ignore_cec_init=1\n[all]\n# FPP HDMI CEC - END\n" >> "$BOOTCONF" + fi + fi fi diff --git a/www/settings.json b/www/settings.json index 76d25ecd6..f05927498 100644 --- a/www/settings.json +++ b/www/settings.json @@ -183,7 +183,6 @@ "settings": [ "VideoOutput", "ForceHDMI", - "DisableHDMICECInit", "EnableBBBHDMI", "ForceHDMIResolution", "ForceHDMIResolutionPort2", @@ -322,6 +321,7 @@ "settings": [ "GPIOFan", "GPIOFanTemperature", + "DisableHDMICECInit", "LEDDisplayType", "bootDelay", "FPP_UUID" @@ -1623,7 +1623,6 @@ "gatherStats": true, "tip": "When enabled, adds hdmi_ignore_cec_init=1 to config.txt to suppress the initial CEC Active Source that wakes projectors/TVs at boot (e.g. after a power outage). CEC control via the CEC plugin still works.", "reboot": 1, - "level": 1, "platforms": [ "Raspberry Pi" ], From 0ad1c1f95d0aa5962b9b698e5d52e3c4c1cc462d Mon Sep 17 00:00:00 2001 From: jessica12ryan Date: Fri, 11 Sep 2026 04:58:22 -0300 Subject: [PATCH 4/8] fix: make upgrade/144 executable (755) --- upgrade/144/upgrade.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 upgrade/144/upgrade.sh diff --git a/upgrade/144/upgrade.sh b/upgrade/144/upgrade.sh old mode 100644 new mode 100755 From 3cb823d8caaf4c3114424c89179af15ddd3424b4 Mon Sep 17 00:00:00 2001 From: jessica12ryan Date: Fri, 11 Sep 2026 18:31:06 -0300 Subject: [PATCH 5/8] fix: exclude DisableHDMICECInit on Pi 5 (firmware hdmi_ignore_cec_init is no-op on KMS/RP1) --- www/settings.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/www/settings.json b/www/settings.json index f05927498..99723c5c0 100644 --- a/www/settings.json +++ b/www/settings.json @@ -1621,11 +1621,16 @@ "name": "DisableHDMICECInit", "description": "Prevent HDMI CEC At Boot", "gatherStats": true, - "tip": "When enabled, adds hdmi_ignore_cec_init=1 to config.txt to suppress the initial CEC Active Source that wakes projectors/TVs at boot (e.g. after a power outage). CEC control via the CEC plugin still works.", + "tip": "When enabled, adds hdmi_ignore_cec_init=1 to config.txt to suppress the initial CEC Active Source that wakes projectors/TVs at boot (e.g. after a power outage). CEC control via the CEC plugin still works. Not applicable on Pi 5 (kernel KMS, no firmware HDMI).", "reboot": 1, "platforms": [ "Raspberry Pi" ], + "variants": { + "Raspberry Pi": [ + "!Pi 5" + ] + }, "type": "checkbox", "default": "1" }, From 89838a3e50678f9354f5a2b2a20ddeea5ae5f5cf Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 15 Sep 2026 22:12:15 -0300 Subject: [PATCH 6/8] fix(HDMI): Prevent HDMI CEC from powering on display at boot - not enabled by default --- src/boot/FPPINIT_Config.cpp | 17 +-------------- upgrade/144/upgrade.sh | 41 ------------------------------------- www/settings.json | 4 ++-- 3 files changed, 3 insertions(+), 59 deletions(-) delete mode 100755 upgrade/144/upgrade.sh diff --git a/src/boot/FPPINIT_Config.cpp b/src/boot/FPPINIT_Config.cpp index 9f0acb3fe..4ee6e65da 100644 --- a/src/boot/FPPINIT_Config.cpp +++ b/src/boot/FPPINIT_Config.cpp @@ -991,20 +991,6 @@ static void migrateMultiSyncDefaultToMulticast() { } } -// Materialize DisableHDMICECInit=1 for installs that have never saved -// the setting. Behavior is already controlled by the fallback in -// setupHDMICECConfig (getRawSettingInt(...,1)) and the default in -// www/settings.json (1), so this only persists the implicit default -// to the settings file for tooling that reads raw. Explicit 0 stays 0. -// Idempotent; safe to re-run. Paired with upgrade/144 for normal -// in-place upgrades; this covers FPPOS reflash. -static void migrateHDMICECDefault() { - std::string existing; - if (!getRawSetting("DisableHDMICECInit", existing)) { - setRawSetting("DisableHDMICECInit", "1"); - } -} - // Config-state migrations that must survive an FPPOS reflash, gated on the // same /fppos_upgraded marker as checkInstallPackages() (touched by // upgradeOS-part2.sh, which is always sourced from the target image being @@ -1017,7 +1003,6 @@ static void migrateHDMICECDefault() { void checkConfigMigrations() { if (FileExists("/fppos_upgraded")) { migrateMultiSyncDefaultToMulticast(); - migrateHDMICECDefault(); } } @@ -1333,7 +1318,7 @@ void setupHDMICECConfig(bool rebootIfChanged) { if (content.empty()) { return; } - if (applyDisableHDMICECBlock(content, getRawSettingInt("DisableHDMICECInit", 1) != 0)) { + if (applyDisableHDMICECBlock(content, getRawSettingInt("DisableHDMICECInit", 0) != 0)) { PutFileContents("/boot/firmware/config.txt", content); printf("FPP - HDMI CEC configuration changed in config.txt\n"); if (rebootIfChanged) { diff --git a/upgrade/144/upgrade.sh b/upgrade/144/upgrade.sh deleted file mode 100755 index 894a947f0..000000000 --- a/upgrade/144/upgrade.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash -##################################### -# Upgrade 144: Prevent HDMI CEC At Boot by default -# -# Issue #2938: FPP 10 (Trixie, 6.18 vc4-kms-v3d) wakes CEC projectors/TVs -# at boot via vc4-hdmi-cec Active Source. The new DisableHDMICECInit -# toggle adds hdmi_ignore_cec_init=1 to config.txt when enabled. -# -# For fresh installs the new default in www/settings.json (1) already -# applies. For existing installs that have never saved the setting -# (no line in /home/fpp/media/settings), pin it to 1 now so the -# projector stays in standby after an upgrade. Explicit 0 stays 0. -# -# Handles normal in-place upgrades via scripts/upgrade_config. -# FPPOS-reflash / restore path is handled separately in -# src/boot/FPPINIT_Config.cpp:checkConfigMigrations(). -##################################### - -BINDIR=$(cd $(dirname $0) && pwd) -. ${BINDIR}/../../scripts/common - -if [ -z "$(getSetting DisableHDMICECInit)" ]; then - setSetting DisableHDMICECInit 1 - # Pre-seed the config.txt block so the next boot does not trigger - # the extra reboot that setupHDMICECConfig(rebootIfChanged=true) would - # otherwise do for every Pi. Idempotent and Pi-only. - BOOTCONF="" - if [ -f /boot/firmware/config.txt ]; then - BOOTCONF="/boot/firmware/config.txt" - elif [ -f /boot/config.txt ]; then - BOOTCONF="/boot/config.txt" - fi - if [ -n "$BOOTCONF" ] && ! grep -q "FPP HDMI CEC - BEGIN" "$BOOTCONF" 2>/dev/null; then - # Insert ahead of cape variant block if present, else append - if grep -q "FPP Cape Overlay Variants - BEGIN" "$BOOTCONF" 2>/dev/null; then - awk 'BEGIN{p=0} /FPP Cape Overlay Variants - BEGIN/ && p==0 {print "# FPP HDMI CEC - BEGIN (managed by fppinit, do not edit)"; print "[all]"; print "hdmi_ignore_cec_init=1"; print "[all]"; print "# FPP HDMI CEC - END"; print ""; p=1} {print}' "$BOOTCONF" > "${BOOTCONF}.tmp" && mv "${BOOTCONF}.tmp" "$BOOTCONF" - else - printf "\n# FPP HDMI CEC - BEGIN (managed by fppinit, do not edit)\n[all]\nhdmi_ignore_cec_init=1\n[all]\n# FPP HDMI CEC - END\n" >> "$BOOTCONF" - fi - fi -fi diff --git a/www/settings.json b/www/settings.json index 99723c5c0..8318b3d29 100644 --- a/www/settings.json +++ b/www/settings.json @@ -1619,7 +1619,7 @@ }, "DisableHDMICECInit": { "name": "DisableHDMICECInit", - "description": "Prevent HDMI CEC At Boot", + "description": "Prevent HDMI CEC at Boot", "gatherStats": true, "tip": "When enabled, adds hdmi_ignore_cec_init=1 to config.txt to suppress the initial CEC Active Source that wakes projectors/TVs at boot (e.g. after a power outage). CEC control via the CEC plugin still works. Not applicable on Pi 5 (kernel KMS, no firmware HDMI).", "reboot": 1, @@ -1632,7 +1632,7 @@ ] }, "type": "checkbox", - "default": "1" + "default": "0" }, "GPIOFan": { "name": "GPIOFan", From 1023ce220463c5e2bb53e6ebdc120c3b0a5a81fe Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 15 Sep 2026 22:18:03 -0300 Subject: [PATCH 7/8] fix(system): HDMI CEC at boot gated for Pi 5 --- src/boot/FPPINIT_Config.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/boot/FPPINIT_Config.cpp b/src/boot/FPPINIT_Config.cpp index 4ee6e65da..b5f5b46c6 100644 --- a/src/boot/FPPINIT_Config.cpp +++ b/src/boot/FPPINIT_Config.cpp @@ -1318,7 +1318,11 @@ void setupHDMICECConfig(bool rebootIfChanged) { if (content.empty()) { return; } - if (applyDisableHDMICECBlock(content, getRawSettingInt("DisableHDMICECInit", 0) != 0)) { + // Pi 5 has no firmware HDMI path (RP1/KMS), so hdmi_ignore_cec_init is + // ignored. Never write the block on Pi 5; this also cleans up a stale + // block left from when the setting previously defaulted to on. + bool want = !isPi5() && getRawSettingInt("DisableHDMICECInit", 0) != 0; + if (applyDisableHDMICECBlock(content, want)) { PutFileContents("/boot/firmware/config.txt", content); printf("FPP - HDMI CEC configuration changed in config.txt\n"); if (rebootIfChanged) { From ea8bd720ab4391645da1a13e8b51fb4d2e034d86 Mon Sep 17 00:00:00 2001 From: Ryan Date: Wed, 16 Sep 2026 21:01:48 -0300 Subject: [PATCH 8/8] fix(help): Add info for Prevent HDMI CEC at Boot --- www/help/settings-system.php | 1 + 1 file changed, 1 insertion(+) diff --git a/www/help/settings-system.php b/www/help/settings-system.php index 3fb3ee02c..1b085623c 100644 --- a/www/help/settings-system.php +++ b/www/help/settings-system.php @@ -11,6 +11,7 @@
  • GPIO 14 Fan Control (checkbox, Raspberry Pi, Advanced) — Uses GPIO 14 PWM to control a cooling fan. Takes effect on reboot; the fan’s temperatures are then set under Fan Temperatures below. A cape that declares its own fan in its device tree does not use this setting and removes it.
  • Fan Temperatures (dynamic section, shown only when a fan thermal zone is present) — Every thermal zone with a fan cooling device bound to it — from the setting above, a cape’s own device tree, or the Pi 5 active cooler — is rendered by PrintFanThermalSettings() as FanTrip_<zone sanitized>_<index> inputs, per zone (e.g. CPU, K16-Pro) with trip points sorted low→high (“Fan On Temperature”, “Fan Speed 2/3…”). Changes are written to sysfs immediately and re-applied at every boot by FPPINIT_Config, since trip points revert to their device tree values on boot. Reset to Defaults POSTs api/settings/fanThermal/reset to restore the hardware values. Stored in °C, displayed in °F when Temperature display units = Fahrenheit.
  • Status Display (dropdown via /dev/i2c-* check) — OLED/LCD on the Pi/BeagleBone I²C bus. Options: Disabled, 128×64 SSD1306 (normal/flipped/h-flipped), 128×64 2-color variants, 128×32 variants, SH1106/SH1107, SSD1327, PCF8574/PCF8574A 16×2/20×4 I²C LCDs, etc. Reboot required.
  • +
  • Prevent HDMI CEC at Boot (checkbox, Raspberry Pi except Pi 5) — Suppresses the initial CEC Active Source broadcast at boot that can wake connected TVs/projectors (e.g. Epson L210SF after a power outage, issue #2938). When enabled, fppinit adds hdmi_ignore_cec_init=1 inside a managed block in /boot/firmware/config.txt. Unlike hdmi_ignore_cec=1 it only suppresses the boot broadcast — the CEC plugin can still power the display on/off on demand. Hidden on Pi 5 (KMS/RP1, no firmware HDMI path) and any stale block is removed there. Reboot required.
  • FPPD Boot Delay (dropdown) — Wait after boot before starting fppd so slow switches/routers can come up and E1.31 multicast works. Options: 0–10s, 15/20/25/30s, 1/2/3/5 min, Auto (−1, wait until NTP/RTC time is valid or 5 min max). Not shown inside containers.
  • Override UUID (text, Advanced, pii) — Replacement UUID for FPP Connect dedup / stats / services instead of the CPU/serial-derived one. Reboot required.