Commit Graph

136 Commits

Author SHA1 Message Date
Jakub
dd2c09174f Extract bot logic from MyMesh into MyMeshBot.h
Move tryBotReplyDM() and tryBotReplyChannel() implementations to
MyMeshBot.h (included at end of MyMesh.cpp). onMessageRecv and
onChannelMessageRecv now contain only a single-line call each,
minimising the diff against upstream in those methods.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
dcccc9733b Bot: global keyboard in BotScreen, placeholder expansion via MsgExpand.h
- Replace BotScreen's custom embedded keyboard with the shared global
  keyboard layout (KB_* constants): char rows at KB_CHARS_Y, special row
  at KB_SPECIAL_Y=48 with 5 buttons ([^][Sp][Del][{}][OK]), fixing the
  previous layout that rendered below the 64 px display boundary.
  Proportional column scaling between char rows (10 cols) and special row
  (5 cols). [{}] opens the placeholder picker overlay.

- Add MsgExpand.h: standalone inline expandMsg() with no framework
  dependencies, expanding {loc} and {time} placeholders. Used by both
  MyMesh (bot channel/DM replies) and QuickMsgScreen, replacing the
  duplicate expandBotMsg() static and the inline expandMsg() method.

- Bump FIRMWARE_VERSION to v1.15.3.

- ToolsScreen: remove key-hint footer line.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
e638955898 Bot: add DM contact target alongside channel
The bot can now reply to a specific DM contact instead of a channel.

UI (BotScreen): item 1 cycles through all channels followed by all DM
contacts (ADV_TYPE_CHAT). The label switches between "Channel" / "Contact"
and the value shows the channel or contact name. Left/right/enter navigate
the combined list.

Logic (MyMesh::onMessageRecv): when bot_target_type==1, match the trigger
against incoming DM text and reply via sendMessage(). A 4-byte pubkey
prefix identifies the target; all-zero prefix matches any DM sender.

Persistence: bot_target_type and bot_dm_pubkey[4] appended to prefs with
backward-compat read guard (old firmware defaults to channel mode).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
9756bb062c Fix 4 bugs found in code review
- BotScreen keyboard: add explicit null-terminator after strncpy when
  trigger/reply text reaches max length (strncpy skips it in that case)
- BotScreen keyboard: clamp _kb_col to 3 when moving DOWN to special row,
  so the cursor doesn't become invisible (col > 3 has no special-row item)
- MyMesh: initialise _bot_last_reply_ms = 0 in constructor (was relying on
  BSS zero-init, which is technically UB for a non-trivial class member)
- RingtoneEditor: exit via CANCEL/Save/Discard goes to ToolsScreen instead
  of HomeScreen — consistent with BotScreen and expected navigation flow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
58afc23df3 Add Auto-Reply Bot and Tools screen to home carousel
- New 'Tools' page on the home screen carousel with Ringtone Editor and Auto-Reply Bot items
- Bot settings: enable/disable toggle, channel picker, trigger phrase, reply text (keyboard with pre-fill)
- Bot logic in MyMesh: case-insensitive substring match, 10 s cooldown to prevent reply loops
- Settings: Home Pages visibility control (which carousel pages are shown; Settings and Messages always visible)
- DataStore: persist home_pages_mask and bot fields with backward-compat guards on read

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
2fc9e094e7 Settings: add Home Pages visibility control
New "Home Pages" section in Settings lets the user toggle which pages
appear in the home screen carousel. Settings and Messages are always
shown; Clock, Recent, Radio, Bluetooth, Advert, GPS, Sensors, Tools
and Shutdown can each be hidden individually.

- NodePrefs: home_pages_mask uint16_t (bit per page, 0=all visible)
- HomeScreen: isPageVisible/navPage skip hidden pages; dots indicator
  counts only visible pages; enforces visible page on re-entry
- SettingsScreen: SECTION_HOME_PAGES with per-page ON/OFF toggles
- DataStore: persisted at offset 1598
- Default: all pages visible (0x01FF)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
4891a36c72 Add ringtone editor, buzzer volume, unread fixes and buzzer notification fixes
- RingtoneEditorScreen: 32-note step sequencer accessible via new Tools page on home screen. U/D=pitch, ENTER=octave cycle, L/R=cursor, MENU=options (play, duration, BPM, insert/delete, save). Notes stored packed in NodePrefs and persisted via DataStore.
- ToolsScreen: new "Tools" home page entry launching the editor
- Buzzer volume: 0-4 bar control in Settings > Sound, persisted to prefs
- Buzzer notifications: fixed notify() firing inside wrong serial-guard branch and before addChannelMsg set the channel index
- Unread counter: fixed newest-first index direction; watermark formula now correct
- OLED brightness: wider range via pre-charge register 0xD9 combined with contrast

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
ffa568938f Settings: add buzzer volume control (5 levels, like brightness)
- NodePrefs: add buzzer_volume field (0=min..4=max, default 4)
- DataStore: persist buzzer_volume at end of prefs file (backward-compat)
- buzzer: setVolume()/getVolume(); applyVolume() sets PWM duty cycle via
  analogWrite() after each rtttl::play() call to control output amplitude
- Settings UI: new BzrVol bar item in Sound section (left/right to adjust)
- UITask: apply saved volume on startup alongside brightness

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
861a65d4b1 Fix buzzer notifications, unread tracking, OLED dimming; remove dead code
- MyMesh: notify() now always fires for channel/contact messages regardless
  of serial connection; called after addChannelMsg so channel index is set
- ChannelHist: fix unread watermark direction (histEntry is newest-first,
  index 0=newest); counter now decrements correctly as user reads messages
- ChannelHist: reset unread to 0 after sending (user is active in channel)
- SH1106Display: add pre-charge register (0xD9) to setBrightness for wider
  dimming range; re-apply contrast+precharge in turnOn(); tune curve
- UITask: remove MsgPreviewScreen dead code (~180 lines, never shown)
- UITask: fix strcpy→snprintf in showAlert()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
158bbf74c8 Unread badges per category + context menu stays open on action
- newMsg() now takes contact_type; room server messages (ADV_TYPE_ROOM)
  tracked separately in _room_unread; DM badge = msgCount - roomUnread
- MODE_SELECT shows unread badges for all 3 rows: DM, Channels, Rooms
- Room unread cleared when user opens Room Servers list or msgRead(0)
- Channel context menu: ENTER performs action but stays open; only
  CANCEL (Back button) closes it so user can see the updated state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
6779b3489b WioTrackerL1: redesign companion UI (channels, keyboard, msg preview)
- QuickMsg → Message screen: channel history, on-screen keyboard, custom message first
- Channel history: RAM ring buffer (32 entries, 80 chars), fullscreen view with word-wrap scroll
- After channel send: stay in history, own message shown as "Me: ..."
- MsgPreview: one message per screen with up/down nav, ENTER opens fullscreen scroll
- Monochromatic display: all color usage corrected to DARK/LIGHT only
- Top bar: battery icon, BT muted indicator, splash "Plus for Wio"
- KB_MAX_LEN: 64 → 100 chars; channel text buffer: 52 → 80 chars

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
c3846ba9f5 feat(wio-tracker-l1): add settings screen and companion radio improvements
Settings screen (UI_HAS_JOYSTICK_UPDOWN build variant):
- Display brightness (5 levels, contrast curve tuned for SH1106 non-linearity)
- Buzzer on/off (respected at startup, no more forced unmute)
- TX power (2–22 dBm)
- Auto-off delay (5s / 15s / 30s / 60s / never)
- GPS update interval (off / 30s / 1min / 5min / 15min / 30min)
- Timezone offset (UTC-12..+14) for clock screen
- Low battery auto-shutdown threshold (off / 3.0–3.5V, default 3.4V)
- Battery display mode (icon / % / voltage)

Battery:
- EMA filter (alpha=0.2) on ADC readings to smooth voltage spikes from uneven load
- Battery % calculated using low_batt_mv as 0% anchor
- Mute icon repositions dynamically based on battery display width

Clock screen on HomeScreen showing time/date with timezone support.

Build:
- _settings variants added for USB and BLE companion radio builds
- Automatic UF2 generation on every build via create-uf2.py post-script
- UI_HAS_JOYSTICK_UPDOWN flag guards joystick_up/down to avoid breaking other boards

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:46 +02:00
Scott Powell
efdd2b6a6c * companion: simplified the CMD_GET / CMD_SET _DEFAULT_FLOOD_SCOPE 2026-04-13 23:11:21 +10:00
Scott Powell
d131e8ae35 * companion: RegionMap now used in Datastore
* companion: new CMD_SET_DEFAULT_FLOOD_SCOPE
* support for regional builds with DEFAULT_REGION_SCOPE
2026-04-13 21:06:53 +10:00
Scott Powell
3b32f35288 * Companion: default scope 2026-04-10 17:01:41 +10:00
liamcottle
1d61df72c3 add define for reserved group data type 2026-03-23 23:09:35 +13:00
liamcottle
c78f7133c9 reorder command args 2026-03-23 23:02:24 +13:00
liamcottle
ed326255d5 add support for direct paths when sending group data 2026-03-23 21:46:21 +13:00
Liam Cottle
91aed048e9 Merge pull request #1928 from dz0ny/feat/grp-data-upstream
feat: Add support for PAYLOAD_TYPE_GRP_DATA
2026-03-23 21:41:51 +13:00
Rastislav Vysoky
285fc685c5 allow to set lower LoRa frequency 2026-03-22 13:54:42 +01:00
Janez T
2f68769185 fix: Widen grp data type
ref: #1928
2026-03-19 09:25:42 +01:00
Janez T
1fb26e7623 fix: Drop grp data timestamp
ref: #1928
2026-03-19 09:22:12 +01:00
Janez T
f25d7a882a fix: Align channel data framing
ref: #1928
2026-03-18 20:14:22 +01:00
Janez T
a21b83b127 fix: address comments
ref:
2026-03-18 20:09:11 +01:00
Janez T
9b84278607 feat: Add support for PAYLOAD_TYPE_GRP_DATA
Docs changes are to reflect how it is currently in fw

This adds ability to send datagram data to everyone in channel
2026-03-18 20:08:52 +01:00
João Brázio
92bef49c55 Merge branch 'dev' into 2026/remote-lna 2026-03-16 09:40:10 +00:00
João Brázio
274e00df50 Merge remote-tracking branch 'upstream/dev' into 2026/remote-lna 2026-03-16 09:37:55 +00:00
ripplebiz
cf0cc851d4 Merge pull request #1297 from ViezeVingertjes/feature/duty-cycle-token-bucket
Implement token bucket duty cycle enforcement
2026-03-08 23:54:32 +11:00
ripplebiz
29be7e293c Merge pull request #1877 from DanielNovak/fix-countbefore-sentinel-regression
Fix countBefore regression: replace sentinel with getOutboundTotal()
2026-03-07 18:48:02 +11:00
João Brázio
9a95e25ef2 Remove unused RX boosted gain mode functions and related preprocessor directives across multiple variants 2026-03-05 18:38:57 +00:00
João Brázio
f858f2e4bb Rename sx126x_rx_boosted_gain to rx_boosted_gain 2026-03-05 18:14:47 +00:00
João Brázio
8df87d5609 Merge remote-tracking branch 'upstream/dev' into 2026/remote-lna 2026-03-05 17:21:38 +00:00
Wouter Bijen
1d190ad944 Clamp max_hops to 64 to cover full protocol hop range (0-63) 2026-03-03 09:05:53 +01:00
Wouter Bijen
c016db86d5 Address PR review: subtract-1 encoding and clamp max_hops
- Change > to >= so stored value 1 means direct/0-hop only (liamcottle)
- Clamp max_hops to 63 on write since getPathHashCount() caps at 63 (robekl)
- Update comments to reflect encoding: 0=no limit, 1=direct only, N=up to N-1 hops

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 08:37:22 +01:00
Wouter Bijen
00566741f6 Add configurable max hops filter for auto-add contacts
Filter auto-add of new contacts by hop count (issues #1533, #1546).
Setting is configurable from the companion app via extended
CMD_SET/GET_AUTOADD_CONFIG protocol (0 = no limit, 1-63 = max hops).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:41:41 +01:00
Daniel Novak
c7568a8db0 Replace 0xFFFFFFFF sentinel with explicit getOutboundTotal()
Instead of overloading getOutboundCount() with a magic sentinel value,
add a dedicated getOutboundTotal() method to the PacketManager interface
that returns the total queue size without time filtering.

This eliminates the fragile convention that caused the regression and
makes the two operations — time-filtered count vs total count —
explicitly separate in the API.
2026-02-28 17:19:04 +01:00
João Brázio
64a16d7ad2 Merge branch 'dev' into 2026/remote-lna 2026-02-27 10:32:14 +00:00
Wessel Nieboer
8bf63256b6 Fix remote LNA toggle bugs: correct register comparison, add missing implementations, wire up companion radio
getRxBoostedGain was returned true because both 0x94 (power saving) and
0x96 (boosted gain = 1) return true
2026-02-24 23:49:06 +01:00
Scott Powell
b14879ce2d * CMD_GET_ADVERT_PATH bug fix 2026-02-24 14:23:59 +11:00
Scott Powell
213d085012 * revert CMD_SEND_SELF_ADVERT, use _prefs.path_hash_mode 2026-02-24 00:08:13 +11:00
Scott Powell
5b0884ad2d * added CMD_SET_PATH_HASH_MODE 2026-02-23 21:08:22 +11:00
Scott Powell
e52d57c065 * companion: new pref: path_hash_mode (0..2)
* companion: new field in CMD_SET_OTHER_PARAMS, path_hash_mode
* companion: CMD_SEND_SELF_ADVERT, cmd_frame[1] now holds the path hash size (0 = zero hop, 1..3 = flood path hash size)
2026-02-23 18:26:56 +11:00
Scott Powell
a66773bac0 * CommonCLI: added "get/set path.hash.mode " 2026-02-23 14:25:19 +11:00
Scott Powell
3e76161e9c * refactor of Contact/Client out_path_len (stored in files), from signed to unsigned byte (+2 squashed commits)
Squashed commits:
[f326e25] * misc
[fa5152e] * new 'path mode' parsing in Dispatcher
2026-02-21 19:35:51 +11:00
Scott Powell
2e00298128 * companion: retransmit delays now hard-coded (only for client repeat mode) 2026-02-17 20:25:56 +11:00
Scott Powell
0abac35744 * client_repeat state now in _DEVICE_INFO response 2026-02-14 16:45:41 +11:00
Scott Powell
564a19d125 * companion client repeat mode support 2026-02-14 15:50:06 +11:00
liamcottle
bafa2ccd22 fix estimated timeout for multi byte path traces 2026-02-10 17:01:30 +13:00
Wessel Nieboer
e8646f5ede Parse as signed int 2026-02-07 16:58:06 +01:00
Wessel Nieboer
d0720c63c2 Allow negative tx power
Like SX1262 allows -9 dBm lowest, some allow lower but that probably
isn't useful
2026-02-06 02:24:51 +01:00