The audit found three keys the Store work added or renamed since v7 -- Store,
the out-of-memory message and the Languages hint -- untranslated in all 13
languages. Filled, using each language's own word for the Use button so the
hint matches the control it points at, and bumped the files to v8. Every
language is back to full coverage at 856 keys.
New deploy/site/sdk.html: the wada.* reference. The beta ships a public API and
had no user-facing documentation for it, so nobody outside the repo could write
an app. Covers the lifecycle, all seven tables, the app format, side-loading and
how to publish, plus the two constraints that surprise people -- the mesh is
read-only in v1 and http_get is plain HTTP because TLS does not fit in the heap
left after Wi-Fi associates.
Site device list: the Attaky Core and the T-Display P4 are fully supported now
(Kaj's call), so their not-hardware-verified caveats are gone. Dropped the "one
of the two primary development boards" wording, which stopped being true once
the P4 joined the test loop. The terms section named only the T-Deck and Heltec
V4 as flashable when the flasher offers ten boards; it now points at the list on
the page instead of going stale again.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
P4-focused beta. Non-P4 boards only pick up minor shared exit-trap code, nothing user-facing.
- Snake + full-screen apps (Monitor/Spectrum/Discover/Web mirror/Advert) exit on status-bar tap
- Screen timeout / standby / burn-in dimming wired for the AMOLED (setBrightness path)
- UI scale pinned to 100% on the P4 (text overflow above 100%)
- No hard-lock on screen-off (P4 has no lock screen yet)
- GPS: L76K detect at 9600 baud, skip boot-detect race, 4096 RX buffer
- Control center dropdown taller on tall screens so the GPS line clears the toggle buttons
- P4 LCD SKU: HI8561 backlight PWM on GPIO51 (fixes the black screen)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- New Discover app: active NODE_DISCOVER sweep -> signal-ranked nearby list, tap-to-add-contact, GPS wardriving log (SD CSV) + signal-coloured coverage overlay on the map. Board-agnostic.
- T-Display P4 TFT-LCD (HI8561) variant support (WADA_P4_LCD build; AMOLED bin untouched).
- Wire the Attaky Core board (#158, @attakygit) into the release matrix + web flasher.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rewrites the beta_45 notes as the full delta since the last stable (beta_40)
for the stable promotion: browser remote control (VNC/REMOTE + web app), the
on-device Web browser + tappable chat links, three new boards (T-LoRa Pager,
T-Display P4, V4-R8), and fixes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Contact-loss fix (microSD devices): atomic temp+swap saveContacts, unified robust
boot SD-mount ladder, and a storage-truth line in the Store-on-SD setting.
- Heltec V4-R8: route MISO for the shared FSPI bus so the microSD mounts; wake-from-sleep
freeze fixed (panel sleep goes through LovyanGFX's own bus, not the HSPI shim).
- Do Not Disturb (originally PR #156 by Tesso Codemonkey / @codemonkeybr): scheduled
sound-silencing window in Settings > Sound + a status-bar bell.
- Control-center redesign: round icon-only chips that spread to fill each row (T-Deck 2x4,
V4 portrait 2 rows), frosted-glass panel, real lock glyph + dynamic bell/bell-slash DND
chip + keyboard icon+word chip (new cc_icons_16 FontAwesome font), per-chip confirmation
toasts, press-grow clip fix, and a V4-portrait status-bar BLE/clock overlap fix.
- LilyGo T-Pager: map tile cache falls back to the microSD under the launcher (fixes the
"storage error / reflash the tiles partition" dead-end).
Co-Authored-By: Tesso Codemonkey <798026+codemonkeybr@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- New "Web" app: on-device HTTPS text browser (strip HTML to readable text,
tappable links, back/fwd/refresh, no proxy). Gated to 8 MB boards via
CAP_WEB_BROWSER; hidden on the 2 MB V4 (can't do the TLS handshake).
- Tappable URLs in chat -> Open in web (8 MB) / Create QR (all boards).
- Drawn vector globe icon for the Web tile.
- Fix: French AZERTY on-screen keyboard lost its spacebar/OK/kbd-switch row
(a stray "" mid-map terminated the LVGL button map early). Restored.
- V4 web fetch resilience (192->96->48->24 KB buffer fallback).
- Home signal box: "tap for details" cue back at the top.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The browser control panel gains full Chats / Contacts / Discovered / Settings
tabs (search, sort, filter, per-contact actions, notifications + live refresh,
ACK/repeats, add-from-discovered, live radio settings, quick-command picker).
Heltec V4 map tiles: fixed the "only the top renders" bug on the 2 MB-PSRAM
board with a persistent tile-buffer pool + viewport culling (no more per-render
128 KB churn/fragmentation). Adds an opt-in "Tile debug overlay" (Map options).
Also: V4 physical-keyboard input in remote/VNC, clearer remote-access screen,
complete Terminal help on device + web, WADAMESH header + status icons.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Remote mode showed a black screen on 2 MB-PSRAM boards (Heltec V4): the
mirror ring/shadow were too big to allocate. Size the ring to one frame
and drop the remote render to 400x240 so the whole footprint is smaller
than VNC's (which already worked). Add a touch-and-hold (3 s) exit for
keyboard-less touch boards and an Exit button on the web page.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stream the live LVGL UI to a phone/desktop browser over the WS companion
server (VNC app) plus a headless REMOTE mode that renders the UI at a
browser-friendly resolution. Non-blocking per-client TX buffering, a
core-0 stream task guarded by a recursive mutex, an on-page Rotate
orientation toggle, and a small 480x288 render upscaled in the browser.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Tanmatsu (ESP32-P4) now bakes FIRMWARE_VERSION="wadamesh <tag>" like the S3
release path, and the app-store publish passes the exact beta tag into the IDF
build — so the About page shows the real beta number instead of the MeshCore
default "v1.16.0-touch".
- beta_40 stable release notes: rolls up beta_36 through beta_40.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fixes:
- Card-less devices (Heltec V4) froze for seconds: a full contacts rewrite to
SPIFFS on every advert refresh triggered a multi-second GC in the mesh loop.
Coalesce advert-driven saves (a contact-set change still saves promptly); SD
boards unchanged. Flush on reboot/power-off so nothing is lost.
- Long translations (FR/DE/...) overflowed fixed-width labels: new
uiFitLabelWidth() shrinks the font to fit one line instead of clipping/wrapping
- applied to the message menu, confirm dialogs, and app-drawer tiles.
- Home signal graph: "tap for details" hint moved to bottom-right so it no longer
overlaps the "Sig" chip in longer languages.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Edit menu (Cut/Copy/Paste/All/Sym) + double-tap select on every settings
field via attachSettingsTaEvents; menu actions route through the keyboard
mirror when bound (#122)
- Wi-Fi join/hidden/details sheets: full-screen settings-style pages riding
the tall status bar title (s_apppage hook), on lv_scr_act so the bar's
glass row isn't clipped
- Lock screen unread badge (envelope + count, anti-burn-in drift) (#93)
- About: Save update bin to SD (/BINS/wadamesh-<tag>-<channel>.bin) for
Launcher installs; beta-channel toggle no longer gated on the OTA slot
- Australia (Mid) preset 915.075/125/SF9/CR5 (#121)
- M9: [M9KB] key debug print (bring-up)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- History flush runs on the core-0 worker (snapshot + storage-busy gate +
bounded shutdown wait): kills the V4's multi-second ui:hist stalls and
the refuses-to-wake-after-message symptom (SPIFFS GC off the UI thread).
- BLE + Wi-Fi runtime enables share the boot co-init heap guard (50 KB
free + 20 KB block): refuse with a toast + revert the switch instead of
panicking (BLE) or silently not starting while claiming on (Wi-Fi).
- Internal DRAM: static footprint 95,365 -> 64,908 B (30.5 KB freed):
serial_interface -> PSRAM; 23 keyboard layout maps const'd -> flash;
nine rings/tables -> psAlloc PSRAM (UITask/TouchPrefsStore/MyMesh);
unused TinyUSB MSC + DFU-mode class drivers stubbed out of the link
(usb_unused_class_stubs.c) — CDC + runtime-DFU untouched, double-flash
verified over the stubbed stack.
- DataStore prefs writes are crash-safe (write .tmp, swap) with a
self-healing loader (.tmp recovery) and a truthful save result up to
the profile-name toast — fixes the boots-with-default-name-once report.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Consumes the new core (buffered receive drain task + RX counters, #13
stock payload layout, GPS-date guard). Fork side:
- TouchPrefs v33 rx_queue, DEFAULT ON for the test channel (fresh
installs + a one-time migrate for upgraders); opt-out toggle
'Buffered receive (experimental)' in Radio & Mesh, applies live.
- About live tier shows LoRa RX heard/read/err/late-lost/qdrop, the
field evidence for the missed-messages fix.
- Spectrum parks/resumes the drain task around raw radio use; MyMesh
setParams sequences hold the radio mutex.
- TanmatsuLoraRadio: no-op API stubs (P4 keeps its own RX path).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- MqttBridge: reconnect() (blocking DNS + TCP + CONNACK, 2-10 s vs an
unreachable broker, every 15 s) now runs on a one-shot core-0 task;
_connecting hands the client between threads. Broker socket writes get
the same zero-timeout writability probe as the TCP/WS companion
servers, so a wedged broker fails a publish instead of stalling loop().
- About: ESP.getSketchSize()/getFreeSketchSpace() esp_image_verify-walk
the whole ~3 MB image (~190 ms each); the 1 Hz refresh cost ~390 ms/s
and flooded the stall ring (the ui:sbar entries field testers
photographed). Computed once and cached.
- Favorites: adding past the 16-cap now toasts 'Favorites full (max 16)'
instead of the wrong 'Removed from favorites'.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Root cause of the beta_31 periodic 1-2s freezes with Wi-Fi on: every
received mesh packet pushes an RX-log frame to all connected TCP/WS
companion clients from the loop thread, and writeAllBytes called
WiFiClient::write() unguarded — against a stale peer (phone asleep,
half-open socket) that blocks in the framework's 1s select() retries.
The 120ms app timeout only bounded attempts, not the first call.
- TCP+WS servers: probe writability (zero-timeout select on the client
fd) before every write; lwIP reports writable only with ~2.8KB free,
a whole frame is ~180B, so probed writes complete instantly.
- Reap clients whose writes fail continuously for 10s (half-open
sockets previously stayed "connected" forever, eating the write
budget on every pushed frame).
- Chat-history ring: chunked writer + wider flush spacing (same
treatment saveContacts got in beta_30).
- Stall tracer: 16-entry ring of >=0.2s loop stalls, shown in About.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Default chat list: 56px rows with a round initials avatar in the thread's
FNV-hue signature colour, last-message preview (getThreadLastMessage ring
accessor), time top-right, unread pill + @ below; compact chat mode keeps
the dense 34px contact-style rows (layout mode mixed into the rebuild sig)
- Per-channel avatar emoji: 'Chat icon' in the thread-settings sheet (tap =
emoji sheet in new pick mode, long-press = reset to letters); persisted in
a chmute-style keyed blob (touchPrefsGet/SetChannelEmoji, 24 x 48B)
- Fix: name/preview overlap (LONG_DOT labels need fixed one-line heights)
- Thread-sheet grid gap 6->4 so the 7th channel cell keeps one screen on T-Deck
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- DataStore::saveContacts packs byte-identical 152B records into ~5KB chunk
writes (was ~12 tiny FS writes per contact: 2.6-3.0s at ~570 contacts on the
loop thread — the #82 sluggishness); falls back to per-field writes on alloc failure
- Contacts 60s age tick updates the Heard labels in place (was a ~1.3s full
teardown+rebuild); advert-driven rebuilds coalesced to one per 2.5s
- Spectrum: rolling waterfall row + live trace every quarter sweep (~250ms),
8-bin/8ms sweep chunks (~20% faster full sweep); trace Y range now tracks the
live min/max — instant expand, 3dB/sweep contract, 30dB minimum span
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Rooms: re-enable the keep-alive pinger (checkConnections), arm a 128s
keep-alive on LOGIN_OK (servers send 0), blank-relogin self-heal while a
room chat is open, 'Log in again' in the room sheet, read-only warning.
Root-caused against simple_room_server: 3 unACKed pushes freeze a client
until the server hears from it — and we never pinged (issue #89).
- Burn-in: ST7789 SLPIN/SLPOUT on screen-off (backlight-off alone kept the
panel driving the static image), lit-lock dim guard on all boards, 10s
notify-wake re-dim, lock clock pixel drift.
- wyvern.red batch: scroll-keys map zoom, backspace exits empty composer,
Reset path in the chat sheet, compact chat toggle (TouchPrefs v31),
clearer delivery glyphs + tap-to-resend on failed sends.
- OTA: hide Install-update when the running image's physical address falls
outside the esp_ota running slot (mixed/legacy tables; beta_21 coredump).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
touchHasOtaUpdateSlot() checked only that a spare OTA partition exists
(esp_ota_get_next_update_partition != NULL). Under bmorcelli's Launcher a
spare slot exists but is smaller than our image, so the check passed, the
Install-update button showed, and Update.begin() failed "won't fit: Bad Size
Given" (reported by Keith/KM1USR on beta_24 under Launcher). Require the target
slot be at least as large as the running slot; the whole OTA block (Install /
previous-version / beta toggle, already gated on this) then hides on Launcher
installs, where updates go through the Launcher. The update-available notice
still shows.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Decoded a T-Deck coredump (Task WDT, loopTask stuck in spiffs_gc_clean under
DataStore::saveContacts): a contact save on a churned SPIFFS can trigger a
multi-second garbage-collection pass that starves core 0 and trips the task
watchdog, giving a reboot loop.
- Route contacts/channels to SD when a card is present, even on upgraded
devices whose data is still on SPIFFS (main.cpp mounts SD every boot; if not
fully adopting SD, store.setSecondaryFS(&SD)). DataStore::begin() migrates the
existing /contacts3 + /channels2 to the card once; identity/prefs stay put.
- Move the ref-counted WdtHeavyGuard into a shared header so the core
DataStore::saveContacts shares one count with the UI history/backup saves, and
wrap saveContacts with it (guaranteed fix for card-less devices).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Contacts list rebuilds on advert (force past the count-cache) + a count-delta safety
net, so a node discovered off-tab or added by the phone app shows immediately (#73)
- New "Advertise on boot" toggle in the Advertise app, off by default (#76)
- Tanmatsu: cache Wi-Fi map tiles on microSD (the P4's internal FFat metadata layer is
broken — f_getfree/f_stat lie); read tiles via open() not the misreporting exists()/size()
- Tanmatsu: persist contacts/channels/chat on microSD (DataStore secondary FS + chat
history) so they survive reboot; identity/prefs stay on the (working) internal FFat
- Tanmatsu: boot fix (drop Serial.begin re-init of USB-Serial-JTAG), MQTT disabled, popups
fit + scroll, keyboard-nav scoped to the open popup, 2000 contacts, Large UI default
- Emoji/quick-reply Esc/red-X closes the popup not the chat; lock-screen unlock after msg-wake
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The signal probe now sends a zero-hop NODE_DISCOVER_REQ control packet
(the standard MeshCore node-discovery that the Ultra / KiekR apps use)
instead of a trace, which repeaters do not answer. Repeaters reply
directly with a NODE_DISCOVER_RESP, captured in onControlDataRecv by
matching the probe tag into _ui_sig_* SNR/RSSI. Thanks to Tarmo for
decoding the exact packet.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The device broadcast a PUSH_CODE_LOG_RX_DATA frame to every connected companion —
including BLE — for every LoRa packet it heard. BLE's ~16 frames/sec budget got
saturated on a busy mesh, delaying/dropping the frames that matter: chat messages
(#46) and repeater/room-server admin responses (#54, the "Streamsink" disconnects).
Skip the RX log on the BLE transport in writeFrameToAll; USB/TCP/WS still get it for
the on-device Monitor app. The MeshCore app never consumed it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signal probe: replace the beta_21 zero-hop advert (which nothing replies to, so the
signal never updated) with a directed TRACE ping to the nearest reachable repeater.
It retransmits — a real reply we measure — without flooding the mesh. New
MyMesh::uiSendSignalProbe() picks the shortest-path repeater; the reply is captured
silently in onTraceRecv via _ui_sig_probe_tag. Falls back to a zero-hop advert when
no repeater is known. Thanks to Tarmo for the insight.
Contacts (#73 part A): a contact discovered while a companion app is connected over
BLE now refreshes the device's own Contacts list + notification. onDiscoveredContact
fired the UI notify only in the standalone branch — move it out so it always fires,
and flag the list dirty for UITask::loop to rebuild on the LVGL thread.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The beta_21 MQTT bridge is based on @samuelcoustet's PR #71, reworked for privacy
(consent gate, direct messages off by default, payload encryption). Record the
attribution in the release notes + the version.json "what's new".
Co-authored-by: Samuel Coustet <257299705+samuelcoustet@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New: stable/test update channels with an opt-in "Get test builds (beta)" toggle on
OTA devices (switches both the update check and what you install); experimental
opt-in MQTT bridge (consent-gated, payload encryption, direct messages off by
default); Portugal (Narrow) region preset (#74); saved-contacts counter in the
Contacts overflow menu (#72).
Fixed: the signal probe is now strictly zero-hop so a repeater can't re-flood it;
the contact list sorts before capping so the most relevant contacts show, with a
"+N more — search to narrow" footer (#73); the blocked-users list opened from
Contacts shows the two-line title bar with a back button; the Contacts overflow
popup fits the screen again.
Also lands the two-channel release tooling (scripts/release.sh stable/beta modes +
gen-flasher-meta channel arg), the docs site, and the MQTT reference decryptor.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New: Spectrum analyzer app; custom notification sounds (SD WAV per event);
saved Wi-Fi networks with auto-join; unified chat settings screen; per-channel
mute; Heltec V4.3 high-gain receiver (FEM LNA) toggle; Apps button on the V4
home screen; Blocked list reachable from Contacts + chat settings; Portuguese
(BR) UI language.
Fixed: touch-screen flood adverts now region-scoped so region repeaters relay
them (#68); channel sends matched by name so a message can't go out on the
wrong channel's key; opt-in "scope direct messages to region" so room-server
logins work through a region-only path (#64); Wi-Fi scan no longer cancelled
by the reconnect retry (empty SSID list).
Under the hood: flood-scope rework (channel vs direct floods); Spectrum owns
the SX1262 while open and restores mesh RX on exit; wifiScanIsActive() gate;
FEM KCT8103L LNA wired; TouchPrefsStore migrations for the new prefs. Adds the
previously-untracked device_caps.h.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Fix LVGL scroll-momentum use-after-free reboot when a scrollable overlay
(emoji / quick-reply / add-channel / channel sheets, Wi-Fi scan, pickers,
app drawer) is freed mid-throw: new closeScrollOverlay() helper
(lv_indev_wait_release + lv_obj_del_async). Root-caused from field beta_18
coredumps.
- Radio & Mesh settings: airtime / duty-cycle readout + "Answer telemetry
requests" toggle, grouped into RADIO / MESH / SIGNAL sections.
- Accent popup dismissed on Enter-to-send (T-Deck physical keyboard).
- Heltec V4: Expansion-Kit Home env line + chart flow below the stats line
so they fit the 240x320 screen.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>