mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-10-09 03:06:39 +00:00
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:
@@ -627,6 +627,15 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
|
||||
rd(&_prefs.display_brightness_pct, sizeof(_prefs.display_brightness_pct));
|
||||
if (_prefs.display_brightness_pct > 100) _prefs.display_brightness_pct = 0;
|
||||
|
||||
// quiet_hours / quiet_from / quiet_to. Out of range -> off, 22-7; an older
|
||||
// file's sentinel bytes landing here are reset below on the mismatch.
|
||||
rd(&_prefs.quiet_hours, sizeof(_prefs.quiet_hours));
|
||||
rd(&_prefs.quiet_from, sizeof(_prefs.quiet_from));
|
||||
rd(&_prefs.quiet_to, sizeof(_prefs.quiet_to));
|
||||
if (_prefs.quiet_hours > 1) _prefs.quiet_hours = 0;
|
||||
if (_prefs.quiet_from > 23) _prefs.quiet_from = 22;
|
||||
if (_prefs.quiet_to > 23) _prefs.quiet_to = 7;
|
||||
|
||||
// Schema sentinel: bumped on layout changes. Mismatch means an older file
|
||||
// (or a different schema); rd() and the clamps above already keep every
|
||||
// field within its valid range regardless, so we just log it here —
|
||||
@@ -636,6 +645,9 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
|
||||
if (sentinel != NodePrefs::SCHEMA_SENTINEL) {
|
||||
MESH_DEBUG_PRINTLN("prefs schema sentinel mismatch: got 0x%08X, expected 0x%08X — re-saving on next change",
|
||||
(unsigned)sentinel, (unsigned)NodePrefs::SCHEMA_SENTINEL);
|
||||
// 0xC0DE002F → 0xC0DE0030: quiet hours appended; from an older file they
|
||||
// hold its sentinel's bytes, so start off, 22:00-07:00.
|
||||
if (sentinel < 0xC0DE0030) { _prefs.quiet_hours = 0; _prefs.quiet_from = 22; _prefs.quiet_to = 7; }
|
||||
// 0xC0DE002E → 0xC0DE002F: display_brightness_pct appended; from an older
|
||||
// file it holds a stray sentinel byte (0x2E = "46 %"), so start from the level.
|
||||
_prefs.display_brightness_pct = 0;
|
||||
@@ -828,6 +840,9 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_
|
||||
file.write((uint8_t *)&_prefs.loc_share_scope, sizeof(_prefs.loc_share_scope));
|
||||
file.write((uint8_t *)&_prefs.loc_share_duration_idx, sizeof(_prefs.loc_share_duration_idx));
|
||||
file.write((uint8_t *)&_prefs.display_brightness_pct, sizeof(_prefs.display_brightness_pct));
|
||||
file.write((uint8_t *)&_prefs.quiet_hours, sizeof(_prefs.quiet_hours));
|
||||
file.write((uint8_t *)&_prefs.quiet_from, sizeof(_prefs.quiet_from));
|
||||
file.write((uint8_t *)&_prefs.quiet_to, sizeof(_prefs.quiet_to));
|
||||
|
||||
// Tail sentinel — must be last. See NodePrefs::SCHEMA_SENTINEL. Its write is
|
||||
// the one we check: once the flash fills, writes return 0, so a good
|
||||
|
||||
@@ -1846,6 +1846,8 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
|
||||
_prefs.radio_fem_txgain = 0;
|
||||
_prefs.display_brightness = 2; // medium brightness by default
|
||||
_prefs.buzzer_volume = 4; // max volume by default
|
||||
_prefs.quiet_from = 22; // quiet hours (off by default) 22:00-07:00
|
||||
_prefs.quiet_to = 7;
|
||||
_prefs.ringtone_bpm_idx = 2; // 120 bpm default
|
||||
_prefs.ringtone_len = 0; // no custom ringtone by default
|
||||
_prefs.ringtone2_bpm_idx = 2; // 120 bpm default
|
||||
|
||||
@@ -123,14 +123,9 @@ void MyMesh::botDmRecord(const uint8_t* pubkey) {
|
||||
// width window (start == end) disables the feature; a window where start > end
|
||||
// wraps past midnight.
|
||||
bool MyMesh::botInQuietHours() const {
|
||||
if (_prefs.bot_quiet_start == _prefs.bot_quiet_end) return false; // disabled
|
||||
uint32_t utc = getRTCClock()->getCurrentTime();
|
||||
if (utc < 1000000000UL) return false; // clock not set — don't suppress
|
||||
uint32_t local = utc + (int32_t)_prefs.tz_offset_hours * 3600;
|
||||
int h = (int)((local / 3600) % 24);
|
||||
int s = _prefs.bot_quiet_start, e = _prefs.bot_quiet_end;
|
||||
return (s < e) ? (h >= s && h < e) // same-day window
|
||||
: (h >= s || h < e); // overnight window
|
||||
int h;
|
||||
if (!localHour(getRTCClock()->getCurrentTime(), _prefs.tz_offset_hours, h)) return false; // clock not set -- don't suppress
|
||||
return hourInWindow(h, _prefs.bot_quiet_start, _prefs.bot_quiet_end);
|
||||
}
|
||||
|
||||
void MyMesh::tryBotReplyDM(const ContactInfo& from, const char* text, uint8_t hops) {
|
||||
|
||||
@@ -317,6 +317,13 @@ struct NodePrefs { // persisted to file
|
||||
uint8_t buzzer_quiet;
|
||||
uint8_t buzzer_volume; // 0=min..4=max, default 4
|
||||
uint8_t buzzer_auto; // 0=manual (default), 1=auto-mute when BT connected
|
||||
// Quiet hours: muted from quiet_from to quiet_to (local hours 0-23, wrapping
|
||||
// past midnight) while quiet_hours is on; the clock alarm still rings and a
|
||||
// message doesn't wake the screen (inQuietHours() below). A manual mute /
|
||||
// unmute during the window stands until it ends (soundctl::tick()).
|
||||
uint8_t quiet_hours; // 0=off (default), 1=on
|
||||
uint8_t quiet_from; // default 22
|
||||
uint8_t quiet_to; // default 7
|
||||
// Settings > Display > "Msg wake". Stored inverted (same reason as
|
||||
// fav_sort_off below) so both a fresh memset and an older prefs file (no
|
||||
// bytes here at all) mean "on" -- today's behaviour, where an incoming
|
||||
@@ -627,7 +634,7 @@ struct NodePrefs { // persisted to file
|
||||
// repeat_* fields) instead of at the tail, which shifted every field after
|
||||
// them by 25 bytes when loading an older file. Never released, but a dev
|
||||
// build wrote it, so the number must not be reused for anything else.
|
||||
static const uint32_t SCHEMA_SENTINEL = 0xC0DE002F;
|
||||
static const uint32_t SCHEMA_SENTINEL = 0xC0DE0030;
|
||||
|
||||
// Bit-index for each home page. Used by page_order (entries store bit+1) and
|
||||
// by home_pages_mask. Single source of truth — both HomeScreen::pageBit/bitToPage
|
||||
@@ -704,6 +711,25 @@ struct NodePrefs { // persisted to file
|
||||
}
|
||||
};
|
||||
|
||||
// Local hour `h` inside [start, end): a window with start > end wraps past
|
||||
// midnight; start == end is no window. Shared by the bot's quiet hours and the
|
||||
// sound's.
|
||||
static inline bool hourInWindow(int h, int start, int end) {
|
||||
if (start == end) return false;
|
||||
return start < end ? (h >= start && h < end) : (h >= start || h < end);
|
||||
}
|
||||
// The local hour from a UTC time; false while the clock isn't set.
|
||||
static inline bool localHour(uint32_t utc, int8_t tz_hours, int& h) {
|
||||
if (utc < 1000000000UL) return false;
|
||||
h = (int)(((int64_t)utc + (int64_t)tz_hours * 3600) / 3600 % 24);
|
||||
return true;
|
||||
}
|
||||
// Settings > Sound > Quiet hours in force at `utc` (never with the clock unset).
|
||||
static inline bool inQuietHours(const NodePrefs& p, uint32_t utc) {
|
||||
int h;
|
||||
return p.quiet_hours && localHour(utc, p.tz_offset_hours, h) && hourInWindow(h, p.quiet_from, p.quiet_to);
|
||||
}
|
||||
|
||||
// ── Serialization tripwire ───────────────────────────────────────────────────
|
||||
// NodePrefs is written/read field-by-field, in order, by DataStore::savePrefs()
|
||||
// and loadPrefsInt(); the on-disk format IS the struct's field layout. There is
|
||||
@@ -782,7 +808,10 @@ struct NodePrefs { // persisted to file
|
||||
// (ESP32) builds, sizeof unchanged at 2824. loc_share_duration_idx (0xC0DE002E)
|
||||
// likewise (sim build; see the check below). display_brightness_pct (0xC0DE002F)
|
||||
// likewise (L2 ESP32 + L1 nRF52 builds).
|
||||
static_assert(sizeof(NodePrefs) == 2824,
|
||||
// quiet_hours / quiet_from / quiet_to (0xC0DE0030) added 8 bytes, not 3 (next
|
||||
// to buzzer_auto, rounded up to the alignment) -- sizeof 2832, confirmed via real
|
||||
// WioTrackerL1_companion_solo_dual (nRF52/ARM) and L2 (ESP32) builds.
|
||||
static_assert(sizeof(NodePrefs) == 2832,
|
||||
"NodePrefs layout changed — sync DataStore save/load + clamp, bump "
|
||||
"SCHEMA_SENTINEL, then update this size (see steps above).");
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ enum Page : uint8_t { PG_NAV, PG_ADVERT, PG_DEVICE, PG_MESSAGES, PG_SOUND, PG_CO
|
||||
enum Section : uint8_t { SEC_TRAIL, SEC_LIVE_SHARE, SEC_LOCATOR, SEC_ADVERT,
|
||||
SEC_DISPLAY, SEC_POWER, SEC_TIME, SEC_UNITS,
|
||||
SEC_MESSAGES, SEC_CONTACTS,
|
||||
SEC_SOUND, SEC_SOUND_FOR, SEC_COUNT };
|
||||
SEC_SOUND, SEC_SOUND_FOR, SEC_QUIET, SEC_COUNT };
|
||||
|
||||
static const char* pageTitle(uint8_t p) {
|
||||
static const char* T[PG_COUNT] = { "Map options", "Advert", "Display & power", "Messages & contacts", "Sound" };
|
||||
@@ -35,14 +35,14 @@ static const char* sectionTitle(uint8_t s) {
|
||||
static const char* T[SEC_COUNT] = { "TRAIL", "LIVE SHARE", "ARRIVAL ALERT", "AUTOMATIC",
|
||||
"DISPLAY", "POWER", "TIME", "UNITS",
|
||||
"MESSAGES", "CONTACTS",
|
||||
"SOUND", "PLAYS FOR" };
|
||||
"SOUND", "PLAYS FOR", "QUIET HOURS" };
|
||||
return s < SEC_COUNT ? T[s] : "";
|
||||
}
|
||||
static uint8_t sectionPage(uint8_t s) {
|
||||
static const uint8_t P[SEC_COUNT] = { PG_NAV, PG_NAV, PG_NAV, PG_ADVERT,
|
||||
PG_DEVICE, PG_DEVICE, PG_DEVICE, PG_DEVICE,
|
||||
PG_MESSAGES, PG_MESSAGES,
|
||||
PG_SOUND, PG_SOUND };
|
||||
PG_SOUND, PG_SOUND, PG_SOUND };
|
||||
return s < SEC_COUNT ? P[s] : PG_DEVICE;
|
||||
}
|
||||
|
||||
@@ -136,6 +136,10 @@ static void optVolume(uint8_t v, char* b, int n, const NodePrefs&) {
|
||||
static const char* L[5] = { "Quietest", "Quiet", "Medium", "Loud", "Loudest" };
|
||||
snprintf(b, n, "%s", L[v < 5 ? v : 4]);
|
||||
}
|
||||
static void optHour(uint8_t v, char* b, int n, const NodePrefs& p) { // "22:00", or "10 PM" with the 12-hour clock
|
||||
if (!p.clock_12h) snprintf(b, n, "%02u:00", (unsigned)v);
|
||||
else snprintf(b, n, "%u %s", (unsigned)(v % 12 ? v % 12 : 12), v < 12 ? "AM" : "PM");
|
||||
}
|
||||
static void optSound(uint8_t v, char* b, int n, const NodePrefs&) { snprintf(b, n, "%s", soundctl::soundLabel(v)); }
|
||||
static void optAdvertScope(uint8_t v, char* b, int n, const NodePrefs&) {
|
||||
snprintf(b, n, "%s", v == ADVERT_SOUND_SCOPE_ZERO_HOP ? "Direct only" : "All");
|
||||
@@ -209,6 +213,9 @@ static const Setting ALL[] = {
|
||||
|
||||
// On / Off / Auto spans two fields (soundctl::setMode): the frontend's own row.
|
||||
IDX("Volume", nullptr, SEC_SOUND, buzzer_volume, 5, optVolume, applySound),
|
||||
SW("Quiet hours", "Muted, screen dark; alarms ring", SEC_QUIET, quiet_hours, nullptr),
|
||||
IDX("From", nullptr, SEC_QUIET, quiet_from, 24, optHour, nullptr),
|
||||
IDX("Until", nullptr, SEC_QUIET, quiet_to, 24, optHour, nullptr),
|
||||
|
||||
IDX("Direct messages", nullptr, SEC_SOUND_FOR, notif_melody_dm, soundctl::SOUND_COUNT, optSound, nullptr),
|
||||
IDX("Channels", nullptr, SEC_SOUND_FOR, notif_melody_ch, soundctl::SOUND_COUNT, optSound, nullptr),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// Ringtone) and ui-lvgl (Settings > Sound, Melodies): the On / Off / Auto mode
|
||||
// (buzzer_quiet + buzzer_auto), the volume, the built-in sounds, the labels of
|
||||
// the notification sound choices, and the two user melodies (ringtone_* /
|
||||
// ringtone2_*) as an editable note list. Which sound a message plays is
|
||||
// ringtone2_*) as an editable note list. Quiet hours mute on a schedule. Which sound a message plays is
|
||||
// SoundNotifier.h.
|
||||
|
||||
#include "../NodePrefs.h"
|
||||
@@ -44,10 +44,21 @@ static const char* soundLabel(uint8_t v) {
|
||||
static const uint8_t OVERRIDE_COUNT = 3;
|
||||
|
||||
#ifdef PIN_BUZZER
|
||||
// The mute that goes with the mode; `connected`: an app is connected.
|
||||
static void applyMode(const NodePrefs* p, genericBuzzer& b, bool connected) {
|
||||
// Quiet hours (NodePrefs::inQuietHours) mute like the mode does. A mute or
|
||||
// unmute by hand inside the window stands until the window ends.
|
||||
static bool s_quiet_now = false; // inside the window, as of the last tick
|
||||
static bool s_quiet_override = false; // set by hand since the window began
|
||||
|
||||
// The mute that goes with the mode and quiet hours; `connected`: an app is
|
||||
// connected.
|
||||
static bool wantQuiet(const NodePrefs* p, bool connected) {
|
||||
uint8_t m = mode(p);
|
||||
b.quiet(m == MODE_OFF || (m == MODE_AUTO && connected));
|
||||
if (m == MODE_OFF || (m == MODE_AUTO && connected)) return true;
|
||||
return s_quiet_now && !s_quiet_override;
|
||||
}
|
||||
static void applyMode(const NodePrefs* p, genericBuzzer& b, bool connected, uint32_t utc) {
|
||||
s_quiet_now = p && inQuietHours(*p, utc);
|
||||
b.quiet(wantQuiet(p, connected));
|
||||
}
|
||||
|
||||
// Auto keeps buzzer_quiet (the manual choice it goes back to). The caller
|
||||
@@ -56,16 +67,21 @@ static void setMode(NodePrefs* p, genericBuzzer& b, uint8_t m, bool connected) {
|
||||
if (!p || m >= MODE_COUNT) return;
|
||||
p->buzzer_auto = m == MODE_AUTO;
|
||||
if (m != MODE_AUTO) p->buzzer_quiet = m == MODE_OFF;
|
||||
applyMode(p, b, connected);
|
||||
s_quiet_override = s_quiet_now; // a choice made during quiet hours wins until they end
|
||||
b.quiet(wantQuiet(p, connected));
|
||||
}
|
||||
|
||||
// From the loop: Auto follows the app connection. True when the mute changed.
|
||||
static bool autoTick(const NodePrefs* p, genericBuzzer& b, bool connected) {
|
||||
if (!p || !p->buzzer_auto || b.isQuiet() == connected) return false;
|
||||
b.quiet(connected);
|
||||
// From the loop: Auto follows the app connection, quiet hours the clock.
|
||||
// True when the mute changed.
|
||||
static bool tick(const NodePrefs* p, genericBuzzer& b, bool connected, uint32_t utc) {
|
||||
if (!p) return false;
|
||||
bool q = inQuietHours(*p, utc);
|
||||
if (q != s_quiet_now) { s_quiet_now = q; s_quiet_override = false; }
|
||||
bool want = wantQuiet(p, connected);
|
||||
if (b.isQuiet() == want) return false;
|
||||
b.quiet(want);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Level 0..4, with a preview beep (through mute: it answers the user's own
|
||||
// change). The caller saves the prefs.
|
||||
static void setVolume(NodePrefs* p, genericBuzzer& b, uint8_t level) {
|
||||
|
||||
@@ -823,7 +823,7 @@ void UITask::begin(DisplayDriver* display_drv, SensorManager* sensors, NodePrefs
|
||||
user_btn.begin();
|
||||
#endif
|
||||
#ifdef PIN_BUZZER
|
||||
soundctl::applyMode(_prefs, _buzzer, isClientConnected());
|
||||
soundctl::applyMode(_prefs, _buzzer, isClientConnected(), rtc_clock.getCurrentTime());
|
||||
_buzzer.setVolume(_prefs ? _prefs->buzzer_volume : 4);
|
||||
_buzzer.begin(); // plays the startup sound unless muted
|
||||
#endif
|
||||
@@ -852,7 +852,7 @@ MyMesh::Listener* UITask::meshListener() { return _core; }
|
||||
void UITask::toggleMute() {
|
||||
#ifdef PIN_BUZZER
|
||||
if (!_prefs) return;
|
||||
bool on = soundctl::mode(_prefs) != soundctl::MODE_ON;
|
||||
bool on = _buzzer.isQuiet(); // muted now, however (mode, Auto, quiet hours): sound on
|
||||
soundctl::setMode(_prefs, _buzzer, on ? soundctl::MODE_ON : soundctl::MODE_OFF, isClientConnected());
|
||||
prefsSave();
|
||||
if (on) _buzzer.playForced(soundctl::MEL_VOLUME);
|
||||
@@ -988,7 +988,7 @@ void UITask::loop() {
|
||||
#endif
|
||||
#ifdef PIN_BUZZER
|
||||
_buzzer.loop();
|
||||
if (soundctl::autoTick(_prefs, _buzzer, isClientConnected()) && !_asleep) refreshStatusBar();
|
||||
if (soundctl::tick(_prefs, _buzzer, isClientConnected(), rtc_clock.getCurrentTime()) && !_asleep) refreshStatusBar();
|
||||
// The alarm melody repeats until dismissed or the ring window ends.
|
||||
if (_core->clock.isRinging() && !_buzzer.isPlaying()) playMelody(soundctl::MEL_ALARM);
|
||||
#endif
|
||||
@@ -1289,7 +1289,7 @@ void UITask::onMessageArrived(const UiEvent& ev) {
|
||||
}
|
||||
// Wake for the message unless an app is already showing it, or the user
|
||||
// turned message-wake off.
|
||||
bool wake_disabled = _prefs && _prefs->msg_wake_screen_off;
|
||||
bool wake_disabled = _prefs && (_prefs->msg_wake_screen_off || inQuietHours(*_prefs, rtc_clock.getCurrentTime())); // quiet hours: dark too
|
||||
if (_asleep && !wake_disabled && !isClientConnected()) wake();
|
||||
else if (!_asleep) lv_display_trigger_activity(NULL);
|
||||
bool open_here = _screen == SCR_THREAD &&
|
||||
|
||||
@@ -41,6 +41,7 @@ class SettingsScreen : public UIScreen {
|
||||
SECTION_SOUND,
|
||||
BUZZER,
|
||||
BUZZER_VOLUME,
|
||||
QUIET_HOURS, QUIET_FROM, QUIET_TO,
|
||||
DM_MELODY,
|
||||
CH_MELODY,
|
||||
AD_SOUND,
|
||||
@@ -480,6 +481,17 @@ class SettingsScreen : public UIScreen {
|
||||
display.setCursor(valCol(display), y);
|
||||
display.print("N/A");
|
||||
#endif
|
||||
} else if (item == QUIET_HOURS) {
|
||||
display.print("Quiet hrs");
|
||||
display.setCursor(valCol(display), y);
|
||||
display.print((p && p->quiet_hours) ? "ON" : "OFF");
|
||||
} else if (item == QUIET_FROM || item == QUIET_TO) {
|
||||
display.print(item == QUIET_FROM ? " from" : " until");
|
||||
display.setCursor(valCol(display), y);
|
||||
{ char hb[8]; uint8_t h = p ? (item == QUIET_FROM ? p->quiet_from : p->quiet_to) : 0;
|
||||
if (p && p->clock_12h) snprintf(hb, sizeof(hb), "%u%s", (unsigned)(h % 12 ? h % 12 : 12), h < 12 ? "AM" : "PM");
|
||||
else snprintf(hb, sizeof(hb), "%02u:00", (unsigned)h);
|
||||
display.print(hb); }
|
||||
} else if (item == DM_MELODY) {
|
||||
display.print("DM sound");
|
||||
display.setCursor(valCol(display), y);
|
||||
@@ -1027,6 +1039,15 @@ public:
|
||||
#endif
|
||||
return right || left;
|
||||
}
|
||||
if (_selected == QUIET_HOURS && p && (left || right || enter)) {
|
||||
p->quiet_hours ^= 1;
|
||||
_dirty = true; return true;
|
||||
}
|
||||
if ((_selected == QUIET_FROM || _selected == QUIET_TO) && p && (left || right || enter)) {
|
||||
uint8_t& h = _selected == QUIET_FROM ? p->quiet_from : p->quiet_to;
|
||||
h = (h + (left ? 23 : 1)) % 24;
|
||||
_dirty = true; return true;
|
||||
}
|
||||
if (_selected == DM_MELODY && p && (left || right || enter)) {
|
||||
p->notif_melody_dm = (p->notif_melody_dm + (left ? SOUND_COUNT - 1 : 1)) % SOUND_COUNT;
|
||||
_dirty = true; return true;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user