feat(companion): quiet hours -- muted on a schedule, the alarm still rings

Settings > Sound > Quiet hours (L2: its own group; L1: Quiet hrs / from /
until): from quiet_from to quiet_to (local hours, wrapping past midnight)
the buzzer is muted and a message doesn't wake the screen; the clock alarm
still rings. A manual mute or unmute inside the window stands until the
window ends. Off with the clock unset.

NodePrefs gains quiet_hours / quiet_from / quiet_to (appended to the file,
sentinel 0xC0DE0030; sizeof 2832 on nRF52 and ESP32), off by default,
22:00-07:00. hourInWindow() / localHour() are shared with the bot's quiet
hours. soundctl::tick() replaces autoTick() (Auto and quiet hours).

Also fixes the L2 side-button mute: it went by the mode, not by whether
the buzzer was muted, so with Auto + an app connected (and now quiet hours)
the first press muted instead of unmuting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-09-28 21:59:40 +02:00
co-authored by Claude Opus 5.5
parent 2e9654fd1c
commit 1def29335c
10 changed files with 121 additions and 32 deletions
+3 -3
View File
@@ -1593,7 +1593,7 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
}
#ifdef PIN_BUZZER
soundctl::applyMode(_node_prefs, buzzer, false);
soundctl::applyMode(_node_prefs, buzzer, false, rtc_clock.getCurrentTime());
buzzer.setVolume(_node_prefs->buzzer_volume);
buzzer.begin();
#endif
@@ -1952,7 +1952,7 @@ void UITask::onMessageArrived(const UiEvent& ev) {
showAlert(alert_buf, 3000);
if (_display != NULL && !_locked) {
bool wake_disabled = _node_prefs && _node_prefs->msg_wake_screen_off;
bool wake_disabled = _node_prefs && (_node_prefs->msg_wake_screen_off || inQuietHours(*_node_prefs, rtc_clock.getCurrentTime()));
if (!wake_disabled && !_display->isOn() && !isClientConnected()) { // wake for the msg unless an app (BLE/USB) is already showing it, or the user disabled msg-wake
_display->turnOn();
}
@@ -2686,7 +2686,7 @@ void UITask::loop() {
userLedHandler();
#ifdef PIN_BUZZER
if (soundctl::autoTick(_node_prefs, buzzer, isClientConnected())) // BLE bonded or an open USB port
if (soundctl::tick(_node_prefs, buzzer, isClientConnected(), rtc_clock.getCurrentTime())) // BLE bonded or an open USB port
_next_refresh = 0;
if (buzzer.isPlaying()) buzzer.loop();
#endif