diff --git a/404.html b/404.html index 299a4df2e..bd4a2dfea 100644 --- a/404.html +++ b/404.html @@ -44,7 +44,7 @@ - + @@ -2131,7 +2131,7 @@ - + diff --git a/WiFi/index.html b/WiFi/index.html index 2cbf34cd9..446558c6b 100644 --- a/WiFi/index.html +++ b/WiFi/index.html @@ -50,7 +50,7 @@ - + @@ -3154,7 +3154,7 @@ and NTP diagnostics remain infrastructure features.
- + diff --git a/_javascript/notification_builder.js b/_javascript/notification_builder.js index 5673de894..91fcbcf62 100644 --- a/_javascript/notification_builder.js +++ b/_javascript/notification_builder.js @@ -5,7 +5,8 @@ const EXAMPLES = { find: { label: "Find my node", kind: "all", id: "", when: "disconnected", vibration: "200,200,200", led: "100,100,100,700", sound: "find:d=8,o=6,b=180:c,e,g,p", screen: "on", gpio: "off", repeat: "forever", gap: "1000", stop: "connected" }, food: { label: "Your food truck order is ready", kind: "channel", id: "3", when: "any", vibration: "50,300,40,20,500", led: "100,100,100,500", sound: "order:d=8,o=5,b=180:c,e,g,4c6", screen: "on", gpio: "off", repeat: "forever", gap: "2000", stop: "button" }, - vip: { label: "VIP chat", kind: "contact", id: "", when: "disconnected", vibration: "100,100,300", led: "50,300,40,20,500", sound: "vip:d=8,o=5,b=180:c,e,g,4g", screen: "on", gpio: "off", repeat: "2", gap: "500", stop: "button" } + vip: { label: "VIP chat", kind: "contact", id: "", when: "disconnected", vibration: "100,100,300", led: "50,300,40,20,500", sound: "vip:d=8,o=5,b=180:c,e,g,4g", screen: "on", gpio: "off", repeat: "2", gap: "500", stop: "button" }, + channel9: { label: "Only channel 9", kind: "channel", id: "9", when: "any", vibration: "off", led: "off", sound: "ch9:d=8,o=5,b=180:c,e,g", screen: "off", gpio: "off", repeat: "1", gap: "500", stop: "button", quietOthers: "on" } }; function pulse(text) { if (text === "off" || text === "inherit") return []; @@ -91,6 +92,14 @@ if (config.repeat !== "forever" && (!/^\d+$/.test(config.repeat) || Number(config.repeat) < 1 || Number(config.repeat) > 65535)) throw new Error("Repeat must be 1-65535 or forever."); if (!/^\d+$/.test(config.gap) || Number(config.gap) < 1 || Number(config.gap) > 60000) throw new Error("Repeat gap must be 1-60000 ms."); if (!["button", "connected", "never"].includes(config.stop)) throw new Error("Unknown stop condition."); + if (config.quietOthers === "on") { + if (config.kind !== "channel") throw new Error("Silencing other message alerts needs a channel exception."); + // This is a shared RULE, not master off: the selected channel can still + // override it. Copy and USB Save must apply the same two-rule recipe. + result.push("set notify.enabled on"); + for (const name of Object.keys(OUTPUTS)) result.push("set notify." + name + " all off"); + result.push("set notify.repeat all 1", "set notify.gap all 500", "set notify.stop all button"); + } for (const name of Object.keys(OUTPUTS)) { if (!["off", "inherit"].includes(config[name])) result.push("set notify." + name + " on"); result.push("set notify." + name + " " + target + " " + config[name]); @@ -104,6 +113,7 @@ return result; } function notificationText(config) { + if (config.quietOthers === "on") throw new Error("Use CLI commands or USB Save for the silent default and channel exception; a notification DM cannot configure these rules."); const parts = []; for (const name of ["vibration", "sound", "led", "screen"]) if (config[name] !== "inherit") parts.push(name + "=" + config[name]); for (const name of ["repeat", "gap"]) parts.push(name + "=" + config[name]); @@ -185,6 +195,10 @@ let client = null, supported = null, previewTimer = null, previewUrl = null, previewVersion = 0; const config = () => Object.fromEntries(new FormData(form)); function render() { + const quiet = form.elements.quietOthers; + quiet.disabled = form.elements.kind.value !== "channel"; + if (quiet.disabled) quiet.checked = false; + find("quiet-warning").hidden = !quiet.checked; try { output.textContent = commands(config()).join("\n"); error.textContent = ""; try { find("dm").textContent = notificationText(config()); } @@ -193,8 +207,11 @@ catch (e) { output.textContent = ""; find("dm").textContent = ""; error.textContent = e.message; } } function preset(name) { - const values = { remote: "inherit", ...EXAMPLES[name] }; - for (const [key, value] of Object.entries(values)) if (form.elements[key]) form.elements[key].value = value; + const values = { remote: "inherit", quietOthers: "off", ...EXAMPLES[name] }; + for (const [key, value] of Object.entries(values)) if (form.elements[key]) { + if (key === "quietOthers") form.elements[key].checked = value === "on"; + else form.elements[key].value = value; + } render(); } function stopPreview(status = "Stopped") { @@ -296,6 +313,9 @@ const c = config(), list = commands(c); if (!client || supported === null) throw new Error("Connect updated Companion firmware first."); for (const name of Object.keys(OUTPUTS)) if (!["off", "inherit"].includes(c[name]) && !(supported & OUTPUTS[name])) throw new Error(name + " is unavailable on this device. Choose off or inherit."); + // Resolve/check numeric channel slots before changing the shared + // default: a missing exception channel must not leave all alerts mute. + if (c.quietOthers === "on") await run("get notify.sound " + selector(c)); for (const text of list) await run(text); if (action === "apply-test") await run("notify.test " + selector(c)); } diff --git a/_stylesheets/notification_builder.css b/_stylesheets/notification_builder.css index a6d5ab11d..74d2861ba 100644 --- a/_stylesheets/notification_builder.css +++ b/_stylesheets/notification_builder.css @@ -7,6 +7,8 @@ .notification-builder small { font-size: .7rem; font-weight: 400; color: var(--md-default-fg-color--light); } .notification-builder input, .notification-builder select { width: 100%; min-width: 0; border: 1px solid var(--md-default-fg-color--lighter); border-radius: 6px; padding: .6rem; background: var(--md-default-bg-color); color: var(--md-default-fg-color); font: inherit; font-weight: 400; } .notification-builder input:focus, .notification-builder select:focus { outline: 2px solid var(--md-primary-fg-color); outline-offset: 2px; } +.notification-builder .notification-checkbox { flex-direction: row; align-items: center; margin-top: 1rem; } +.notification-builder .notification-checkbox input { width: auto; flex: 0 0 auto; padding: 0; } .notification-builder button { border: 1px solid var(--md-primary-fg-color); border-radius: 6px; padding: .5rem .75rem; margin: .2rem; cursor: pointer; color: var(--md-primary-fg-color); font: inherit; } .notification-builder button:hover { background: var(--md-primary-fg-color); color: var(--md-primary-bg-color); } .notification-builder button:disabled { opacity: .5; cursor: wait; } diff --git a/bootloader_version_stock_audit/index.html b/bootloader_version_stock_audit/index.html index 08a0bd20b..c99b5942a 100644 --- a/bootloader_version_stock_audit/index.html +++ b/bootloader_version_stock_audit/index.html @@ -46,7 +46,7 @@ - + @@ -2167,7 +2167,7 @@ - + diff --git a/cad_scan_validation/index.html b/cad_scan_validation/index.html index 0a127e699..6369f1d02 100644 --- a/cad_scan_validation/index.html +++ b/cad_scan_validation/index.html @@ -46,7 +46,7 @@ - + @@ -2167,7 +2167,7 @@ - + diff --git a/carrier_wave/index.html b/carrier_wave/index.html index 0802391dd..230c816c9 100644 --- a/carrier_wave/index.html +++ b/carrier_wave/index.html @@ -50,7 +50,7 @@ - + @@ -2255,7 +2255,7 @@ reproduction steps, and the tested preamble settings. - + diff --git a/carrier_wave_validation/index.html b/carrier_wave_validation/index.html index 4d5500f0d..36022b124 100644 --- a/carrier_wave_validation/index.html +++ b/carrier_wave_validation/index.html @@ -46,7 +46,7 @@ - + @@ -2167,7 +2167,7 @@ - + diff --git a/cli_build_matrix/index.html b/cli_build_matrix/index.html index 75b2a3847..1b256a134 100644 --- a/cli_build_matrix/index.html +++ b/cli_build_matrix/index.html @@ -50,7 +50,7 @@ - + @@ -2761,7 +2761,7 @@ does not contain its linked marker is rejected during the build. - + diff --git a/cli_command_availability/index.html b/cli_command_availability/index.html index 4d0fea534..826230dcc 100644 --- a/cli_command_availability/index.html +++ b/cli_command_availability/index.html @@ -50,7 +50,7 @@ - + @@ -5847,7 +5847,7 @@ selected by that manifest. - + diff --git a/cli_commands/index.html b/cli_commands/index.html index 09e4cf293..5c3dc80fc 100644 --- a/cli_commands/index.html +++ b/cli_commands/index.html @@ -50,7 +50,7 @@ - + @@ -11184,7 +11184,7 @@ to charge above it or have USB power restored before it wakes. - + diff --git a/cli_settings_audit/index.html b/cli_settings_audit/index.html index cf7eb521d..d5983d41e 100644 --- a/cli_settings_audit/index.html +++ b/cli_settings_audit/index.html @@ -46,7 +46,7 @@ - + @@ -2167,7 +2167,7 @@ - + diff --git a/companion_contact_cache/index.html b/companion_contact_cache/index.html index 6261150a1..f3183e7bf 100644 --- a/companion_contact_cache/index.html +++ b/companion_contact_cache/index.html @@ -46,7 +46,7 @@ - + @@ -2167,7 +2167,7 @@ - + diff --git a/companion_contact_cache_results/index.html b/companion_contact_cache_results/index.html index 06c24c37a..28c774e89 100644 --- a/companion_contact_cache_results/index.html +++ b/companion_contact_cache_results/index.html @@ -46,7 +46,7 @@ - + @@ -2167,7 +2167,7 @@ - + diff --git a/companion_offline_queue/index.html b/companion_offline_queue/index.html index ae0c0cdeb..c8d190bfe 100644 --- a/companion_offline_queue/index.html +++ b/companion_offline_queue/index.html @@ -50,7 +50,7 @@ - + @@ -2382,7 +2382,7 @@ protocol setting to resize it at runtime. - + diff --git a/companion_protocol/index.html b/companion_protocol/index.html index ebec1d91a..3957faaf9 100644 --- a/companion_protocol/index.html +++ b/companion_protocol/index.html @@ -50,7 +50,7 @@ - + @@ -5212,7 +5212,7 @@ response = wait_for_response(PACKET_MSG_SENT) - + diff --git a/companion_radio_full/index.html b/companion_radio_full/index.html index 1678ee00b..990529277 100644 --- a/companion_radio_full/index.html +++ b/companion_radio_full/index.html @@ -50,7 +50,7 @@ - + @@ -3593,7 +3593,7 @@ selection, nRF52 in-place deltas, relays, trust checks, and recovery behavior. - + diff --git a/companion_usb_ascii_validation/index.html b/companion_usb_ascii_validation/index.html index ea2cb9d19..e6a89aa49 100644 --- a/companion_usb_ascii_validation/index.html +++ b/companion_usb_ascii_validation/index.html @@ -46,7 +46,7 @@ - + @@ -2167,7 +2167,7 @@ - + diff --git a/companion_usb_client_validation/index.html b/companion_usb_client_validation/index.html index 3f74c539f..a47421743 100644 --- a/companion_usb_client_validation/index.html +++ b/companion_usb_client_validation/index.html @@ -46,7 +46,7 @@ - + @@ -2167,7 +2167,7 @@ - + diff --git a/docs/index.html b/docs/index.html index 514331c6f..13753b89a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -50,7 +50,7 @@ - + @@ -2256,7 +2256,7 @@ pip install mkdocs-material - + diff --git a/double_frequency_v4_validation/index.html b/double_frequency_v4_validation/index.html index a0e054591..2b7451a1d 100644 --- a/double_frequency_v4_validation/index.html +++ b/double_frequency_v4_validation/index.html @@ -46,7 +46,7 @@ - + @@ -2167,7 +2167,7 @@ - + diff --git a/esp32_memory_budget/index.html b/esp32_memory_budget/index.html index 368c5a59a..2e7d8eb3e 100644 --- a/esp32_memory_budget/index.html +++ b/esp32_memory_budget/index.html @@ -46,7 +46,7 @@ - + @@ -2167,7 +2167,7 @@ - + diff --git a/esp32_partition_catalog/index.html b/esp32_partition_catalog/index.html index 5db9758bd..4b509580b 100644 --- a/esp32_partition_catalog/index.html +++ b/esp32_partition_catalog/index.html @@ -50,7 +50,7 @@ - + @@ -2471,7 +2471,7 @@ LUT. No scheduled refresh job or release upload is installed by this script. - + diff --git a/esp32_wifi_partition_migration/index.html b/esp32_wifi_partition_migration/index.html index 3d72c5507..b28c5696a 100644 --- a/esp32_wifi_partition_migration/index.html +++ b/esp32_wifi_partition_migration/index.html @@ -50,7 +50,7 @@ - + @@ -2533,7 +2533,7 @@ The 16 MiB target table creates two 6.25 MiB OTA slots. See the - + diff --git a/espnow_bridge_setup/index.html b/espnow_bridge_setup/index.html index 749aa463c..ad26c0b06 100644 --- a/espnow_bridge_setup/index.html +++ b/espnow_bridge_setup/index.html @@ -50,7 +50,7 @@ - + @@ -2548,7 +2548,7 @@ a crossover-only block. See the - + diff --git a/faq/index.html b/faq/index.html index d57f1476f..704c78a8c 100644 --- a/faq/index.html +++ b/faq/index.html @@ -50,7 +50,7 @@ - + @@ -5111,7 +5111,7 @@ Flash one of the Ethernet-enabled firmware variants: - + diff --git a/filter_tool/index.html b/filter_tool/index.html index 310b0233f..0de87a102 100644 --- a/filter_tool/index.html +++ b/filter_tool/index.html @@ -50,7 +50,7 @@ - + @@ -3110,7 +3110,7 @@ sized structure for every possible condition and action. - + diff --git a/firmware_memory_budget/index.html b/firmware_memory_budget/index.html index 93a53c6e3..962e31cd7 100644 --- a/firmware_memory_budget/index.html +++ b/firmware_memory_budget/index.html @@ -46,7 +46,7 @@ - + @@ -2167,7 +2167,7 @@ - + diff --git a/firmware_picker/index.html b/firmware_picker/index.html index 7fd09fa16..19ebfe059 100644 --- a/firmware_picker/index.html +++ b/firmware_picker/index.html @@ -50,7 +50,7 @@ - + @@ -3029,7 +3029,7 @@ and each replacement's.memory.json report before updating.
-
+
diff --git a/flood_filtering/index.html b/flood_filtering/index.html
index 2211f544b..89b1e1fdf 100644
--- a/flood_filtering/index.html
+++ b/flood_filtering/index.html
@@ -50,7 +50,7 @@
-
+
@@ -4022,7 +4022,7 @@ inspect or reset those separately when troubleshooting.
-
+
diff --git a/four_fixed_tx_dwell_validation/index.html b/four_fixed_tx_dwell_validation/index.html
index 52135cd9a..df91d0b91 100644
--- a/four_fixed_tx_dwell_validation/index.html
+++ b/four_fixed_tx_dwell_validation/index.html
@@ -46,7 +46,7 @@
-
+
@@ -2167,7 +2167,7 @@
-
+
diff --git a/four_fixed_tx_single_pass_validation/index.html b/four_fixed_tx_single_pass_validation/index.html
index 8d626422a..f8c450090 100644
--- a/four_fixed_tx_single_pass_validation/index.html
+++ b/four_fixed_tx_single_pass_validation/index.html
@@ -46,7 +46,7 @@
-
+
@@ -2167,7 +2167,7 @@
-
+
diff --git a/full_companion_features/index.html b/full_companion_features/index.html
index 066dee859..91029fef2 100644
--- a/full_companion_features/index.html
+++ b/full_companion_features/index.html
@@ -50,7 +50,7 @@
-
+
@@ -2569,7 +2569,7 @@ serve host-supplied packages without needing that receiver storage layout.
-
+
diff --git a/full_companion_usb_switcher/index.html b/full_companion_usb_switcher/index.html
index fd40346a1..21e1c95f5 100644
--- a/full_companion_usb_switcher/index.html
+++ b/full_companion_usb_switcher/index.html
@@ -50,7 +50,7 @@
-
+
@@ -2817,7 +2817,7 @@ ownership in
-
+
diff --git a/full_usb_logging_validation/index.html b/full_usb_logging_validation/index.html
index 3d9b4d587..8741424eb 100644
--- a/full_usb_logging_validation/index.html
+++ b/full_usb_logging_validation/index.html
@@ -46,7 +46,7 @@
-
+
@@ -2167,7 +2167,7 @@
-
+
diff --git a/gps_tracking/index.html b/gps_tracking/index.html
index b3356e056..042a696e9 100644
--- a/gps_tracking/index.html
+++ b/gps_tracking/index.html
@@ -50,7 +50,7 @@
-
+
@@ -2503,7 +2503,7 @@ fresh data is available.
-
+
diff --git a/halo_keymind_settings/index.html b/halo_keymind_settings/index.html
index db034bf33..06218e193 100644
--- a/halo_keymind_settings/index.html
+++ b/halo_keymind_settings/index.html
@@ -50,7 +50,7 @@
-
+
@@ -3132,7 +3132,7 @@ set flood.retry.path 2
-
+
diff --git a/hardware_validation_bluetooth_stealth_2026-09-07/index.html b/hardware_validation_bluetooth_stealth_2026-09-07/index.html
index 32fca026c..07f619763 100644
--- a/hardware_validation_bluetooth_stealth_2026-09-07/index.html
+++ b/hardware_validation_bluetooth_stealth_2026-09-07/index.html
@@ -46,7 +46,7 @@
-
+
@@ -2167,7 +2167,7 @@
-
+
diff --git a/hardware_validation_checklist/index.html b/hardware_validation_checklist/index.html
index f15538e1e..185f27ecb 100644
--- a/hardware_validation_checklist/index.html
+++ b/hardware_validation_checklist/index.html
@@ -46,7 +46,7 @@
-
+
@@ -2167,7 +2167,7 @@
-
+
diff --git a/heltec_v4_wifi_partition_migration/index.html b/heltec_v4_wifi_partition_migration/index.html
index d2f4d7378..6907bd59d 100644
--- a/heltec_v4_wifi_partition_migration/index.html
+++ b/heltec_v4_wifi_partition_migration/index.html
@@ -50,7 +50,7 @@
-
+
@@ -2204,7 +2204,7 @@ installed over LoRa without reaching the board's Wi-Fi network.
-
+
diff --git a/home_text_spacing/index.html b/home_text_spacing/index.html
index d393c4e46..be2b34ab2 100644
--- a/home_text_spacing/index.html
+++ b/home_text_spacing/index.html
@@ -46,7 +46,7 @@
-
+
@@ -2167,7 +2167,7 @@
-
+
diff --git a/host_cli_service/index.html b/host_cli_service/index.html
index ba967e13c..9cdf3d18b 100644
--- a/host_cli_service/index.html
+++ b/host_cli_service/index.html
@@ -50,7 +50,7 @@
-
+
@@ -2627,7 +2627,7 @@ sign serial requests.
-
+
diff --git a/index.html b/index.html
index 12c2caa0f..2403e45b0 100644
--- a/index.html
+++ b/index.html
@@ -48,7 +48,7 @@
-
+
@@ -2335,7 +2335,7 @@
-
+
diff --git a/kiss_modem_protocol/index.html b/kiss_modem_protocol/index.html
index ce477c22b..8605da2dd 100644
--- a/kiss_modem_protocol/index.html
+++ b/kiss_modem_protocol/index.html
@@ -50,7 +50,7 @@
-
+
@@ -3869,7 +3869,7 @@ never falls back to the other profile.
-
+
diff --git a/lora_ota_automation/index.html b/lora_ota_automation/index.html
index cfd8c0149..6e8933d87 100644
--- a/lora_ota_automation/index.html
+++ b/lora_ota_automation/index.html
@@ -50,7 +50,7 @@
-
+
@@ -3603,7 +3603,7 @@ image: the default active-download guard preserves it until you explicitly use
-
+
diff --git a/management_decoder/index.html b/management_decoder/index.html
index 7a3439e65..7992b3184 100644
--- a/management_decoder/index.html
+++ b/management_decoder/index.html
@@ -50,7 +50,7 @@
-
+
@@ -2371,7 +2371,7 @@ offline Python capture tool, see Management rep
-
+
diff --git a/management_reports/index.html b/management_reports/index.html
index 6978b394f..1f7931298 100644
--- a/management_reports/index.html
+++ b/management_reports/index.html
@@ -50,7 +50,7 @@
-
+
@@ -2743,7 +2743,7 @@ public metadata and entry/page counts remain visible.
-
+
diff --git a/mbedtls-tls-footprint/index.html b/mbedtls-tls-footprint/index.html
index 45418abea..c4fc96083 100644
--- a/mbedtls-tls-footprint/index.html
+++ b/mbedtls-tls-footprint/index.html
@@ -46,7 +46,7 @@
-
+
@@ -2167,7 +2167,7 @@
-
+
diff --git a/mixed_scan_validation/index.html b/mixed_scan_validation/index.html
index 8491311c5..253d10d02 100644
--- a/mixed_scan_validation/index.html
+++ b/mixed_scan_validation/index.html
@@ -46,7 +46,7 @@
-
+
@@ -2167,7 +2167,7 @@
-
+
diff --git a/mixed_sf_bw_validation/index.html b/mixed_sf_bw_validation/index.html
index b34134f7b..02c83ebaa 100644
--- a/mixed_sf_bw_validation/index.html
+++ b/mixed_sf_bw_validation/index.html
@@ -46,7 +46,7 @@
-
+
@@ -2167,7 +2167,7 @@
-
+
diff --git a/nimble_companion_trial/index.html b/nimble_companion_trial/index.html
index 912b578c2..f0347c37c 100644
--- a/nimble_companion_trial/index.html
+++ b/nimble_companion_trial/index.html
@@ -46,7 +46,7 @@
-
+
@@ -2167,7 +2167,7 @@
-
+
diff --git a/nimble_companion_trial_results/index.html b/nimble_companion_trial_results/index.html
index 3a569cf86..89f737bb8 100644
--- a/nimble_companion_trial_results/index.html
+++ b/nimble_companion_trial_results/index.html
@@ -46,7 +46,7 @@
-
+
@@ -2167,7 +2167,7 @@
-
+
diff --git a/notifications/index.html b/notifications/index.html
index a12e97568..384f626e9 100644
--- a/notifications/index.html
+++ b/notifications/index.html
@@ -50,7 +50,7 @@
-
+
@@ -2339,6 +2339,7 @@ stop policy. USB testing uses Binary Companion mode at 115200 baud.
+