From 54d708401e765a691674bd8342708b0eff36b4e3 Mon Sep 17 00:00:00 2001 From: liquidraver <504870+liquidraver@users.noreply.github.com> Date: Thu, 22 Oct 2026 15:06:58 +0200 Subject: [PATCH] fix led bug --- docs/CLI_commands.md | 6 ++++-- releasenotes/RELEASE_NOTES_1.18.1-zephcore.md | 4 ++++ zephcore/helpers/ui/ui_common.c | 8 ++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/CLI_commands.md b/docs/CLI_commands.md index 98f0333..6ee5f27 100644 --- a/docs/CLI_commands.md +++ b/docs/CLI_commands.md @@ -448,7 +448,7 @@ four radio parameters together, since they are one interop-critical set. | `set buzzer <0\|1\|2\|3>` | or `off` / `on` / `vibrate` / `sound` | *(ZephCore only; room server only)* `0`/`off` silent, `1`/`on` sound + vibration, `2`/`vibrate` vibration only, `3`/`sound` sound only. Modes 2 and 3 need a vibration motor; without one the node replies `Error: no vibration motor on this board - use 0 or 1`. Applied live and persisted. Compiled out on repeater builds. | | `set leds ` | default **on** | *(ZephCore only)* Master switch for every LED on the node, applied live and persisted: heartbeat, unread-message and LoRa TX-activity LEDs, plus the message and shutdown flashes. Works on every role, including headless repeaters where the TX LED is the only one that ever lights. Does **not** cover the display backlight, which is a separate UI brightness setting. | | `set leds.radio ` | default **tx** | *(ZephCore only)* What the LoRa activity LED reacts to, applied live and persisted. `tx` lights it for the duration of each transmit (the behaviour before this setting existed), `rx` gives a 30 ms blink per valid packet received, `all` does both, `off` keeps it dark. Sits **below** `set leds`: the master switch off keeps it dark whatever this says. Only boards defining a `lora-tx-led` or `lora-tx-pwm-led` alias have this LED; elsewhere the value is stored but does nothing, and the reply says so. | -| `set leds.hb ` | default **all** | *(ZephCore only)* What the heartbeat LED reacts to, applied live and persisted. `all` is the 4 s liveness tick that widens from 20 ms to 200 ms while messages are unread (the behaviour before this setting existed), `hb` never widens, `unread` stays dark until there are unread messages, `off` keeps it dark. Also sits below `set leds`. See the LED-topology notes below for what this does on single-LED boards. | +| `set leds.hb ` | default **all** | *(ZephCore only)* What the heartbeat LED reacts to, applied live and persisted. `all` is the 4 s liveness tick that widens from 20 ms to 200 ms while messages are unread (the behaviour before this setting existed), `hb` never widens, `unread` stays dark until there are unread messages, `off` keeps it dark. The immediate flash on a received message (button-UI companions, while no app is connected) follows the same setting: it fires in `all` and `unread` only, so `hb` and `off` stay silent on messages. The shutdown flash is not affected by this setting. Also sits below `set leds`. See the LED-topology notes below for what this does on single-LED boards. | | `set leds.brightness <0-100>` | default **100** | *(ZephCore only)* Brightness of a PWM-capable heartbeat/activity LED, applied live and persisted, `%` suffix accepted. Only boards defining a `heartbeat-pwm-led` or `lora-tx-pwm-led` alias have a dimmable LED; elsewhere the value is stored but has no effect. Also sits below `set leds`. | | `set agc.reset.interval ` | Accepted, ignored | Removed — replies `Removed - Automatic AGC reset is on`. The prefs byte is still read and written so the on-flash layout stays byte-exact, but nothing acts on it. | | `set multi.acks <0\|1>` | | Enable extra ACK transmits | @@ -515,7 +515,9 @@ four radio parameters together, since they are one interop-critical set. **button UI only** — the joystick UI and every repeater/observer report 0 permanently. On those, `leds.hb all` behaves identically to `hb`, and `leds.hb unread` leaves the LED **dark forever**. - **`set leds off` still wins.** Both `leds.radio` and `leds.hb` sit below the master switch; with `leds off` - the node stays dark whatever they say. All three are applied live and persisted. + the node stays dark whatever they say, shutdown flash included. All three are applied live and persisted. + For a node that is dark in use but still blinks three times at power-off (buzzer muted), use + `set leds on` with `set leds.hb off` (and `set leds.radio off` where the board has a radio LED). - **USB-only commands** — `get acl`, `get prv.key`, `set freq`, `log` (dump), `stats-packets`, `stats-radio`, `stats-core`, `erase` — are blocked when the command arrives over the mesh (remote admin). These are the only ones gated on `sender_timestamp == 0`; `get public.key` and `set prv.key` are **not** among them. - **Adaptive contention window** — `txdelay`, `rxdelay`, and `direct.txdelay` are accepted and stored for Arduino prefs compatibility but have no effect. Use `get txdelay` to inspect the current adaptive state and `set backoff.multiplier` to tune reactive backoff. - **Region load mode** — after `region load`, every line received is parsed as a region entry until a blank line is sent. The loaded map is only committed to the live region tree at that point; use `region save` to persist it. Region rows must be indented by at least one space, so an **unindented line that starts with a name character aborts the mode and is executed as a normal command** — the escape hatch if a `region load` is started by accident or a client dies mid-transfer. An abort discards the partial map, leaving the live region tree untouched. The exported wildcard header line `*` stays unindented and is ignored as before, so pasting the output of `region` still loads cleanly. diff --git a/releasenotes/RELEASE_NOTES_1.18.1-zephcore.md b/releasenotes/RELEASE_NOTES_1.18.1-zephcore.md index 9664167..32a7816 100644 --- a/releasenotes/RELEASE_NOTES_1.18.1-zephcore.md +++ b/releasenotes/RELEASE_NOTES_1.18.1-zephcore.md @@ -24,6 +24,10 @@ becomes 5). ## Other changes +- **`set leds.hb off` and `hb` now also stop the message blink.** Before, a node with the heartbeat + LED off still flashed on every DM and channel message. `set leds on` with `set leds.hb off` now keeps + a T1000-E dark in use while it still blinks three times when you switch it off with the buzzer muted; + `set leds off` keeps it dark at power-off too. - **Zephyr** updated to `b70dbaf045e`. A GPS receiver that fails to start on the first try is now really tried again (the two retries did nothing before), and on boards with external flash a failed start of that flash is retried at the next mount instead of staying failed until reboot. diff --git a/zephcore/helpers/ui/ui_common.c b/zephcore/helpers/ui/ui_common.c index a54f906..5ce31ad 100644 --- a/zephcore/helpers/ui/ui_common.c +++ b/zephcore/helpers/ui/ui_common.c @@ -303,11 +303,15 @@ void ui_set_leds_disabled(bool disabled) /* Flash the heartbeat LED immediately on message receipt. * Cancels the current cycle, pulses at LED_ON_MSG_MS width, then the * work chain resumes the normal heartbeat automatically. - * No-op when LEDs are disabled or hardware is absent. */ + * No-op when LEDs are disabled, when leds.hb is "hb" or "off" (the modes + * that never show message activity), or when hardware is absent. */ void ui_led_flash_msg(void) { #if HAS_ANY_HEARTBEAT_LED - if (!zephcore_leds_disabled() && heartbeat_led_is_ready()) { + uint8_t hb = zephcore_leds_hb_mode(); + + if (!zephcore_leds_disabled() && heartbeat_led_is_ready() && + (hb == LEDS_HB_ALL || hb == LEDS_HB_UNREAD)) { k_work_cancel_delayable(&s_led_on_work); k_work_cancel_delayable(&s_led_off_work); heartbeat_led_write(true);