Document channel-nine-only notification example

This commit is contained in:
mikecarper committed 2026-10-05 18:33:56 -07:00
1 parent 8af0511f54
commit 46e6bb7b71
2 files changed
+93

No files matched your search

+52
View File
@@ -240,3 +240,55 @@ notification strings. Receiver master switches apply even while connected.
and vibration. Add a connected profile with sound/vibration off if the phone
should handle notifications while attached. Permission to send notification
strings is separate from a VIP's ordinary message rule.
### Only channel 9 alerts; all other channels silent
This example makes message alerts silent by default, then plays one short
melody for channel 9. It works both with and without a connected companion
client and requires a device with a buzzer. Messages still arrive normally;
this changes the node's alerts, not the phone app's notification settings.
`channel:9` means the firmware's **zero-based slot 9** (the tenth slot), not
a channel named `ch9`. Configure that slot before running these commands.
The rule follows its saved channel key; recreate it if you replace the channel
in that slot.
Start with no conflicting custom rules. Use `get notify.rules`, then
`get notify.rules <rule-slot>` to inspect existing selectors. Remove only
unwanted rules with `notify.delete <selector>`: existing state-specific and
contact/channel rules can override the silent default below.
```text
set notify.enabled on
set notify.vibration all off
set notify.sound all off
set notify.led all off
set notify.screen all off
set notify.gpio all off
set notify.repeat all 1
set notify.gap all 500
set notify.stop all button
set notify.sound on
set notify.sound channel:9 ch9:d=8,o=5,b=180:c,e,g
```
Keep the sound **master** on: `set notify.sound all off` silences the default
rule, while `set notify.sound off` would also block the channel 9 exception.
The other outputs remain silent, including screen wake-ups for messages.
To add vibration for channel 9 on a device with a vibration motor:
```text
set notify.vibration on
set notify.vibration channel:9 100,100,300
```
Test the saved exception with `notify.test channel:9`; stop it with
`notify.stop`. Send a message on another configured channel to verify that
it stays quiet.
**Scope:** there is no channels-only wildcard: `all` also silences ordinary
DM and room-message alerts unless a more specific rule enables them.
Previously authorized contact/room `!notify` strings can still request alerts.
If those should stay quiet too, revoke their permission with
`set notify.remote contact:PUBLIC_KEY off` or
`set notify.remote room:ROOM_PUBLIC_KEY off`, using the full sender/server key.
@@ -67,6 +67,47 @@ TEST_F(Notifications, ContactAndChannelOverrideEachOutputAndConditionIndependent
uint8_t channel[16];memset(channel,2,sizeof(channel));
c.message(nullptr,channel,false,0);EXPECT_TRUE(sink.led);EXPECT_TRUE(sink.vibration);
}
TEST_F(Notifications, DocumentedChannelNineExceptionKeepsOtherMessagesQuiet) {
// notifications.md: numeric slots are resolved to channel keys by MyMesh.
// Exercise the same recipe with slot 9's already-resolved key.
for (const char* command : {
"set notify.enabled on",
"set notify.vibration all off",
"set notify.sound all off",
"set notify.led all off",
"set notify.screen all off",
"set notify.gpio all off",
"set notify.repeat all 1",
"set notify.gap all 500",
"set notify.stop all button",
"set notify.sound on",
"set notify.sound channel:09090909090909090909090909090909 ch9:d=8,o=5,b=180:c,e,g"}) {
EXPECT_EQ("OK", cmd(command)) << command;
}
unsigned rules = 0;
for (const auto& rule : c.settings().rules) if (rule.used) ++rules;
EXPECT_EQ(2U, rules);
for (bool connected : {false, true}) {
for (unsigned slot = 0; slot < 40; ++slot) {
uint8_t channel[16];memset(channel, slot, sizeof(channel));
ASSERT_TRUE(c.message(nullptr, channel, connected, 0));
EXPECT_EQ(slot == 9 ? "ch9:d=8,o=5,b=180:c,e,g" : "", sink.tune);
EXPECT_FALSE(sink.vibration);EXPECT_FALSE(sink.led);EXPECT_FALSE(sink.gpio);
EXPECT_EQ(0, sink.screen_state);
EXPECT_TRUE(c.overridesScreen());
c.loop(1000, connected);EXPECT_FALSE(c.active());
}
uint8_t contact[32];memset(contact, 1, sizeof(contact));
ASSERT_TRUE(c.message(contact, nullptr, connected, 0));
EXPECT_TRUE(sink.tune.empty());EXPECT_FALSE(sink.vibration);EXPECT_FALSE(sink.led);
EXPECT_EQ(0, sink.screen_state);
c.stop();
}
EXPECT_EQ("OK", cmd("set notify.sound off"));
uint8_t channel[16];memset(channel, 9, sizeof(channel));
ASSERT_TRUE(c.message(nullptr, channel, false, 0));
EXPECT_TRUE(sink.tune.empty()); // A rule cannot bypass its master switch.
}
TEST_F(Notifications, ButtonConnectedAndNeverStopPolicies) {
cmd("set notify.led all 50");cmd("set notify.repeat all forever");
c.loop(0,false);c.message(nullptr,nullptr,false,0);EXPECT_TRUE(c.button());EXPECT_FALSE(c.active());