This commit is contained in:
MarekZegare4
2026-07-18 08:11:35 +00:00
parent d2ccbd7f03
commit c5e6676e74
31 changed files with 567 additions and 143 deletions

View File

@@ -17,7 +17,7 @@
<link rel="icon" href="/meshcore/assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -25,7 +25,7 @@
<link rel="stylesheet" href="/meshcore/assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="/meshcore/assets/stylesheets/main.ec1eaa64.min.css">
@@ -1319,7 +1319,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "/meshcore/", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "/meshcore/assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="/meshcore/assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="/meshcore/assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -4646,7 +4646,7 @@ region save
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -3591,7 +3591,7 @@ response = wait_for_response(PACKET_MSG_SENT)
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1984,7 +1984,7 @@ spójność (jedna lista, jedno menu wszędzie).</p>
<script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1763,8 +1763,14 @@ pixel sizes</strong> — derive everything from these:</p>
</table>
<p>Drawing helpers (all clip/measure for you):</p>
<ul>
<li><code>drawCenteredHeader(title)</code> — plain centered title + separator.</li>
<li><code>drawInvertedHeader(label)</code> — filled title bar (used by detail views).</li>
<li><code>drawCenteredHeader(title, menu_hint=false, menu_open=false)</code> — plain centered
title + separator.</li>
<li><code>drawInvertedHeader(label, menu_hint=false, menu_open=false)</code> — filled title
bar (used by detail views).</li>
<li>Both take an optional <code>menu_hint</code>: pass <code>true</code> on a screen with a Hold-Enter
context menu to reserve a <code></code> glyph (<code>menuHintWidth()</code>/<code>drawContextMenuHint()</code>)
in the header, so the menu is discoverable without already knowing the
shortcut; <code>menu_open</code> highlights it while the menu is actually up.</li>
<li><code>drawSelectionRow(x, y, w, h, sel)</code> — the highlight bar behind a list row.</li>
<li><code>drawTextEllipsized(x, y, max_w, str)</code> — truncates with <code></code>; <strong>use this for
any user string</strong> (names, labels) so long/UTF-8 text can't overrun.</li>
@@ -1854,6 +1860,34 @@ _menu.active = true;
sensor tokens) via <code>addPlaceholder()</code> / <code>clearPlaceholders()</code>; the shared
<code>kbAddSensorPlaceholders()</code> (<code>ui-new/SensorPlaceholders.h</code>) adds only the tokens
the board's sensors actually provide. Expand them with <code>expandMsg()</code> at send time.</p>
<p>Two layouts share every grid: <strong>ABC</strong> (one key per letter) and <strong>T9</strong>
(phone-keypad multi-tap — repeated Enter within <code>KB_T9_TIMEOUT_MS</code> cycles a
cell's letter group, then its digit). Page 0 is no longer hardcoded to Latin:
<code>NodePrefs::keyboard_main_alphabet</code>/<code>keyboard_alt_alphabet</code> (Settings &gt;
Keyboard's Main/Additional rows) each pick a script — Latin, Cyrillic, or
Greek — for page 0 and page 1 respectively (<code>KeyboardWidget::mainScript()</code>/
<code>altScript()</code>); equal values collapse to a single script + Symbols (2 pages
instead of 3, see <code>hasAltAlphabet()</code>). <code>scriptCellStr()</code>/<code>scriptT9GroupStr()</code>
dispatch each script to its own ABC grid (<code>KB_CHARS</code>/<code>KB_CYRILLIC_CHARS</code>/
<code>KB_GREEK_CHARS</code>) and T9 group table (<code>KB_T9_GROUPS</code>/<code>KB_T9_GROUPS_CYRILLIC</code>/
<code>_GREEK</code>) so the two layouts always offer the same letters regardless of which
page they're on. Latin-diacritic letters (Polish, Czech, German, etc.) aren't
alt-alphabet pages — they're reached by Hold-Enter on whichever page currently
shows Latin instead (see <code>KB_ACCENT_VARIANTS</code> below).
Shift is one-shot by default (capitalises the next letter, including whichever
candidate a T9 multi-tap cycle settles on) or Hold-Enter to toggle caps-lock;
Hold-Clear erases the whole field. <strong>UP from the top letter row</strong> enters
<strong>cursor mode</strong> (LEFT/RIGHT move the insertion point; UP/DOWN jump to
start/end, then — pressed again once already at that boundary — continue on
to the special row / letter grid, the same destinations the plain grid wrap
used to reach directly) so edits/inserts can target any point in the typed
text, not just the end; Enter/Cancel exit immediately from anywhere.
Hold-Enter on a Latin-page letter cell with accented variants instead opens
the <strong>accent popup</strong>: one horizontal row of <code>KB_ACCENT_VARIANTS[group]</code>
(a UTF-8 string per base letter, same shape as a T9 group string), LEFT/RIGHT
to pick, Enter to insert via the shared <code>insertGlyph()</code> helper, Cancel to
dismiss. Holding a letter with no variants, or any T9/alt-alphabet/symbols
cell, is a no-op.</p>
<p><code>FullscreenMsgView::wrapLines()</code> is a standalone pixel-accurate word-wrapper
(O(n), variable-width-font aware) reusable by any multi-line layout; it writes
into the shared <code>s_wrap_trans</code> / <code>s_wrap_lines</code> scratch (single-threaded render,
@@ -1898,6 +1932,15 @@ use <code>BIG_ICON</code> / <code>bigIconDraw</code>. The home status bar compos
with a <code>blinkOn()</code> cadence for "leave it on and forget" broadcasts (auto-advert,
Live Share, trail, repeater) — follow that pattern when adding an indicator:
always shown on e-ink, blinking on OLED.</p>
<p>Icons are drawn from a fixed priority-ordered table (<code>HomeScreen::renderBatteryIndicator()</code>,
<code>UITask.cpp</code>); once the row runs out of horizontal space the loop just stops,
so the lowest-priority icons silently drop first rather than the whole bar
crushing the node name. A blinking icon still reserves its width on the
off-phase of its blink, so the row's layout can't visibly shift width as icons
blink in and out.</p>
<p>Screens with a Hold-Enter context menu (Nodes, Bot, Admin, Diagnostics, …) pass
<code>menu_hint=true</code> to their header call (see §2) so a <code></code> glyph advertises the
menu; <code>KEY_CONTEXT_MENU</code> (Hold-Enter) opens it.</p>
<hr />
<h2 id="7-input">7. Input</h2>
<p>Keys arrive as the <code>KEY_*</code> codes in <code>UIScreen.h</code>: <code>KEY_UP/DOWN/LEFT/RIGHT</code>,
@@ -2074,7 +2117,7 @@ the framework.</p>
<script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1902,7 +1902,7 @@ Etapy 23 = czyszczenie logiki mapy/siatki bez zmiany wyglądu.</p>
<script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1442,7 +1442,7 @@ pip install mkdocs-material
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -4019,7 +4019,7 @@ For companion radios, you can set these radios' transmit power in the smartphone
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -21,7 +21,7 @@
<link rel="icon" href="assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -29,7 +29,7 @@
<link rel="stylesheet" href="assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="assets/stylesheets/main.ec1eaa64.min.css">
@@ -1377,7 +1377,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": ".", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -2841,7 +2841,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -2228,7 +2228,7 @@ DEBUG: PWRMGT: LPCOMP wake configured (AIN7, ref=3/8 VDD)
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1404,7 +1404,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1947,7 +1947,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -2162,7 +2162,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1481,7 +1481,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

File diff suppressed because one or more lines are too long

View File

@@ -2,90 +2,90 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://meshcore-dev.github.io/meshcore/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/cli_commands/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/companion_protocol/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/docs/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/faq/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/kiss_modem_protocol/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/nrf52_power_management/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/number_allocations/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/packet_format/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/payloads/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/qr_codes/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/stats_binary_frames/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/terminal_chat_cli/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/design/nearby_redesign/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/design/solo_ui_framework/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/design/trail_redesign/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/solo_features/clock_screen/clock_screen/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/solo_features/favourites_dial/favourites_dial/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/solo_features/message_screen/message_screen/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/solo_features/screen_lock/screen_lock/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/solo_features/settings_screen/settings_screen/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/solo_features/tools_screen/tools_screen/</loc>
<lastmod>2026-07-06</lastmod>
<lastmod>2026-07-18</lastmod>
</url>
</urlset>

Binary file not shown.

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1740,9 +1740,9 @@
<h3 id="clock-tools-alarm-timer-stopwatch">Clock tools — Alarm, Timer, Stopwatch</h3>
<p><strong>Press Enter</strong> (short press) on the Clock page to open <strong>Clock Tools</strong>, a small menu with three time utilities. <strong>Cancel</strong> backs out one level (tool → menu → home). The same menu also has an entry under <strong>Tools System</strong>, so it's reachable without the Clock page.</p>
<h4 id="alarm">Alarm</h4>
<p>A single one-shot wake alarm. Rows: <strong>Hour</strong>, <strong>Minute</strong> and <strong>Armed</strong>. <strong>Enter</strong> on Hour or Minute opens the digit editor (LEFT/RIGHT moves between the tens/units, UP/DOWN changes the digit); <strong>Enter</strong> on Armed toggles ON/OFF. The configured time is shown next to the <strong>Alarm</strong> menu row when armed, and the setting persists across reboots.</p>
<p>A wake alarm with an optional repeat. Rows: <strong>Hour</strong>, <strong>Minute</strong>, <strong>Repeat</strong> and <strong>Armed</strong>. <strong>Enter</strong> on Hour or Minute opens the digit editor (LEFT/RIGHT moves between the tens/units, UP/DOWN changes the digit); <strong>Enter</strong> on Repeat cycles <strong>Off → Daily → Weekdays → Weekends → Off</strong>; <strong>Enter</strong> on Armed toggles ON/OFF. The configured time is shown next to the <strong>Alarm</strong> menu row when armed, and the setting persists across reboots.</p>
<p>While an alarm is armed a bell icon signals it in two places: the top-left corner of the <strong>Clock page</strong> itself, and the <strong>top status bar</strong> of the other home pages (the status bar is hidden on the Clock page, which is why the clock face carries its own indicator). The bell is icon-only — the exact alarm time is on the <strong>Alarm</strong> row inside Clock Tools.</p>
<p>The alarm is scheduled as an absolute fire instant, so it is <strong>robust to clock re-syncs</strong> — the mesh (every inbound packet), the companion app, GPS and the CLI can all jump the device clock at any moment. A correction that moves the clock a little still fires at the right wall-clock time; a jump that skips over the alarm time still fires (late). After firing once, the alarm disarms itself.</p>
<p>The alarm is scheduled as an absolute fire instant, so it is <strong>robust to clock re-syncs</strong> — the mesh (every inbound packet), the companion app, GPS and the CLI can all jump the device clock at any moment. A correction that moves the clock a little still fires at the right wall-clock time; a jump that skips over the alarm time still fires (late). With <strong>Repeat</strong> set to Off (the default) the alarm disarms itself after firing once, same as before; with a repeat pattern set, it stays armed and re-schedules itself for the next matching day instead.</p>
<p>The alarm only fires while the device is <strong>awake</strong> (it keeps running with the display off or locked). It cannot wake the device from a full <strong>Shutdown</strong> (the CPU and RAM are powered down), and needs a valid time source — it stays pending until the clock is synced.</p>
<h4 id="timer-countdown">Timer (countdown)</h4>
<p>A large <strong>HH:MM:SS</strong> readout with one digit underlined. <strong>LEFT/RIGHT</strong> moves the cursor one digit at a time, <strong>Up/Down</strong> changes the digit under it (minute/second tens cap at 5, hours at 23), and <strong>Enter</strong> starts the countdown. While running it shows <strong>H:MM:SS</strong><strong>Enter</strong> stops it, <strong>Cancel</strong> returns to the menu and leaves it counting. When it reaches zero the device rings, even if you have navigated to another screen.</p>
@@ -1805,7 +1805,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "../../..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1640,7 +1640,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "../../..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1121,6 +1121,17 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#adding-editing-a-channel" class="md-nav__link">
<span class="md-ellipsis">
Adding / editing a channel
</span>
</a>
</li>
<li class="md-nav__item">
@@ -1523,6 +1534,17 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#adding-editing-a-channel" class="md-nav__link">
<span class="md-ellipsis">
Adding / editing a channel
</span>
</a>
</li>
<li class="md-nav__item">
@@ -1602,11 +1624,12 @@
</tr>
</tbody>
</table>
<p>Press <strong>Enter</strong> on a contact or channel to open its history, then press <strong>Enter</strong> again (or select an empty send row) to compose a message. Choose between:</p>
<p>Press <strong>Enter</strong> on a contact or channel to open its history, then press <strong>Enter</strong> again (or select the <strong>[+ send]</strong> button, anchored at the right edge of the history) to compose a message. Choose between:</p>
<ul>
<li><strong>Custom message</strong> — opens the on-screen keyboard</li>
<li><strong>Q1Q10</strong> — quick reply templates editable in Settings Messages</li>
</ul>
<p>While typing, <strong>UP</strong> from the top letter row enters cursor mode (LEFT/RIGHT move the insertion point; UP/DOWN jump to start/end, then continue on to the special row / letter grid if pressed again once already there; Enter/Cancel exit immediately from anywhere) so you can edit or insert in the middle of what you've typed instead of only at the end. <strong>Hold Enter</strong> on a Latin letter with accented variants (e.g. a, e, c, n, o, s, z…) instead opens a one-row popup of that letter's accents — LEFT/RIGHT to pick, Enter to insert, Cancel to dismiss. See the on-screen keyboard section of the <a href="../../../design/solo_ui_framework/">UI framework guide</a> for the full key set (Shift, T9 multi-tap, Cyrillic/Greek).</p>
<p>The keyboard supports placeholders that insert live data at send time:</p>
<table>
<thead>
@@ -1667,10 +1690,11 @@
<li><strong>Passwords are remembered across reboots.</strong> After a successful login the password is saved on the device, so picking that room again — even after a power cycle — logs back in silently and drops you straight into the chat.</li>
<li><strong>A wrong or changed password self-heals.</strong> If a saved password stops working (e.g. the server's password was changed), the failed login forgets it, so the next <strong>Enter</strong> prompts you to type a new one.</li>
<li><strong>Re-login any time</strong> with <strong>Hold Enter</strong> on the room → <strong>Login…</strong> (see the room context menu below) — useful to switch to a new password without waiting for a failure.</li>
<li><strong>Log out</strong> with <strong>Hold Enter</strong> on a room you're currently logged into → <strong>Logout</strong> (only offered once logged in). Forgets the saved password on the device, so the next time you open that room it prompts for one again instead of silently reusing the old one.</li>
<li>Passwords set from the <strong>phone app</strong> are saved on the device too, so it can post to that room standalone after a reboot.</li>
</ul>
<blockquote>
<p>The on-screen keyboard is limited to ASCII (letters, digits and common symbols); accented characters such as <code>ą</code>/<code>ę</code> can't be typed on the device. A password containing them can still be set from the phone app — the device stores and replays it byte-for-byte.</p>
<p>The on-screen keyboard's default (Latin) page is ASCII only. Typing accented or non-Latin characters — Polish, Czech, Slovak, German, French, Spanish, Portuguese or Nordic diacritics, Cyrillic, or Greek — needs Settings Keyboard Alphabet set to the matching language first; the keyboard's <strong>#@/abc</strong> key then cycles Latin → that alphabet → Symbols → Latin. A password containing characters outside whatever's currently enabled can still be set from the phone app — the device stores and replays it byte-for-byte.</p>
</blockquote>
<hr />
<h3 id="message-history">Message history</h3>
@@ -1688,7 +1712,7 @@
</tr>
</tbody>
</table>
<p>Each entry in the history list shows the sender name and a compact age indicator (<code>3m</code>, <code>2h</code>, <code>&gt;1d</code>) in the top-right corner.</p>
<p>Messages are drawn as chat bubbles sized to fit their content, anchored <strong>right</strong> for your own outgoing messages and <strong>left</strong> for incoming ones (like a typical messenger), with the sender name and a compact age indicator (<code>3m</code>, <code>2h</code>, <code>&gt;1d</code>) in the top-right corner of each bubble. The list runs <strong>newest at the bottom</strong> — opening a history starts you at the latest message, and scrolling <strong>up</strong> goes further into the past.</p>
<p><strong>Short Enter</strong> on a message opens it in fullscreen. <strong>Hold Enter</strong> — on a history row or in fullscreen — opens the same options menu: Reply, plus <strong>Navigate</strong> / <strong>Save waypoint</strong> when the message contains a location (see Fullscreen message view). You don't need to open the message first.</p>
<hr />
<h3 id="fullscreen-message-view">Fullscreen message view</h3>
@@ -1772,7 +1796,7 @@
</tbody>
</table>
<p>When <strong>Pin to dial</strong> is selected, a slot picker opens (Slot 16 showing current occupant name or "empty"). Choosing a slot that already holds another contact moves the new contact there.</p>
<p>In the <strong>Rooms</strong> list the context menu instead offers a single item:</p>
<p>In the <strong>Rooms</strong> list the context menu instead offers:</p>
<table>
<thead>
<tr>
@@ -1785,6 +1809,10 @@
<td>Login…</td>
<td>Opens the password prompt to (re-)log in to this room (see Rooms — logging in)</td>
</tr>
<tr>
<td>Logout</td>
<td>Only shown once logged in. Forgets the saved password so the next open prompts for one again</td>
</tr>
</tbody>
</table>
<hr />
@@ -1828,9 +1856,49 @@
<td>Fav: yes / no</td>
<td>Add or remove this channel from favourites — <strong>LEFT/RIGHT</strong> to toggle</td>
</tr>
<tr>
<td>Edit</td>
<td>Opens the Add/Edit form below, pre-filled with the channel's name</td>
</tr>
<tr>
<td>Delete</td>
<td>Removes the channel immediately (no confirm prompt)</td>
</tr>
</tbody>
</table>
<hr />
<h3 id="adding-editing-a-channel">Adding / editing a channel</h3>
<p>Joining a new community channel, or creating one to share with others, no longer needs the phone app. The <strong>Channels</strong> list ends with a <strong>"+ Add channel"</strong> row — press <strong>Enter</strong> on it to pick a channel type, or use <strong>Edit</strong> from the context menu above to change an existing channel's name or secret (Edit skips the type picker and opens the Name/Secret form directly).</p>
<p><strong>+ Add channel</strong> first asks which type of channel to create — the same three types the phone app offers:</p>
<ul>
<li><strong>Public</strong> — instantly re-adds the well-known default public channel (no fields to fill in). Useful if it was deleted and you want it back without remembering its key.</li>
<li><strong>Hashtag</strong> — type a topic name (e.g. <code>test</code>); the channel's name and secret are both derived from it (name becomes <code>#test</code>, secret is the first 16 bytes of <code>sha256("#test")</code>). A topic-based public group chat — anyone who types the same topic elsewhere ends up on the same channel — separate from the default Public channel.</li>
<li><strong>Private</strong> — the manual Name + Secret form:</li>
</ul>
<table>
<thead>
<tr>
<th>Field</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name</td>
<td>Up to 31 characters</td>
</tr>
<tr>
<td>Secret</td>
<td><strong>LEFT/RIGHT</strong> toggles between two entry modes; <strong>Enter</strong> opens the keyboard for whichever is selected</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>Passphrase</strong> (default) — type any text; the device hashes it down to the channel's 16-byte secret. Easiest to agree on verbally, the same idea as a room password — two people who type the same passphrase end up on the same channel.</li>
<li><strong>Hex key</strong> — type the exact 32-hex-character secret (the format used by channel QR codes, see <a href="../../../qr_codes/">QR Codes</a>), for joining a channel whose precise secret you were given rather than agreeing on a new passphrase. An all-zero secret (<code>00…0</code>) is rejected ("Invalid secret") — that value is reserved internally to mark an empty channel slot.</li>
</ul>
<p>Select <strong>[Save]</strong> to commit. The secret can't be redisplayed once saved (only the derived key is kept) — editing it later means typing a new passphrase or hex key, the same as re-logging into a room with a new password.</p>
<hr />
<h3 id="mark-all-read">Mark all read</h3>
<p><strong>Hold Enter</strong> on the DM / Channels / Rooms mode-select screen to clear all unread counters for the highlighted category at once.</p>
@@ -1885,7 +1953,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "../../..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1604,7 +1604,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "../../..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1651,11 +1651,6 @@
<td>12 h appends AM/PM</td>
</tr>
<tr>
<td>Font</td>
<td>Default / Lemon</td>
<td>Default: 5×7 Adafruit with ASCII transliteration; Lemon: native Unicode with pixel-accurate line wrap</td>
</tr>
<tr>
<td>Display rotation <em>(e-ink only)</em></td>
<td>0° / 90° / 180° / 270°</td>
<td>Applied immediately</td>
@@ -1820,6 +1815,11 @@
</thead>
<tbody>
<tr>
<td>Name</td>
<td>keyboard entry (up to 31 chars)</td>
<td>This device's node name, shown to others and in every advert. <strong>Enter</strong> opens the keyboard pre-filled with the current name; applied and saved on submit</td>
</tr>
<tr>
<td>Timezone</td>
<td>12 h … +14 h</td>
<td>UTC offset in whole hours</td>
@@ -1834,6 +1834,11 @@
<td>Metric / Imperial</td>
<td>Global unit system for every distance/speed shown in Tools (Nearby Nodes, Trail, navigate-to-point). Metric: m / km, km/h, min/km. Imperial: ft / mi, mph, min/mi</td>
</tr>
<tr>
<td>Reboot</td>
<td>action (<strong>Enter</strong>)</td>
<td>Restarts this device. Pending setting changes are saved first. Last row, so it isn't the default-selected one</td>
</tr>
</tbody>
</table>
<hr />
@@ -1850,11 +1855,22 @@
<tr>
<td>Layout</td>
<td>ABC / T9</td>
<td>On-screen keyboard style. <strong>ABC</strong>: an a-b-c…z grid, one key per letter (the original layout). <strong>T9</strong>: phone-keypad multi-tap — each key is labelled with its <strong>digit</strong> and a letter group (e.g. <code>2abc</code>); repeated <strong>Enter</strong> presses cycle through the letters and then the digit itself.</td>
<td>On-screen keyboard style. <strong>ABC</strong>: an a-b-c…z grid, one key per letter (the original layout). <strong>T9</strong>: phone-keypad multi-tap — each key is labelled with its <strong>digit</strong> and a letter group (e.g. <code>2abc</code>); repeated <strong>Enter</strong> presses cycle through the letters and then the digit itself. Applies to whichever script page is active (see Main/Additional below), not just Latin.</td>
</tr>
<tr>
<td>Main</td>
<td>Latin / Cyrillic / Greek</td>
<td>Which script the keyboard <strong>opens on by default</strong>. <strong>Latin</strong> (default) matches earlier releases; pick <strong>Cyrillic</strong> or <strong>Greek</strong> here instead to make that script the one you land on every time, with Latin becoming the one reached via cycling (see Additional below) instead of the other way round.</td>
</tr>
<tr>
<td>Additional</td>
<td>Latin / Cyrillic / Greek</td>
<td>The second script added to the same <strong>#@/abc</strong> key's cycle (Main → Additional → Symbols → Main) — no separate key to switch scripts. Setting Additional to the <strong>same</strong> script as Main drops the cycle back to just that script plus Symbols (no second script page at all). <strong>Greek</strong> covers the 24-letter alphabet plus final sigma (<code>ς</code>) but not the tonos stress accents used in proper Modern Greek spelling. Every script's letters render natively — the display font (a single unified Unicode font used everywhere on-screen) covers all of them, no separate toggle needed.</td>
</tr>
</tbody>
</table>
<p>Applies to every on-screen text field (messages, waypoint labels, room passwords, preset names). Earlier releases labelled the grid <em>QWERTY</em>; the layout has always been alphabetical, so it is now named <strong>ABC</strong>.</p>
<p>European Latin-diacritic letters (Polish, Czech, Slovak, German, French, Spanish, Portuguese, Nordic, etc.) aren't separate alphabet pages — instead, <strong>Hold Enter</strong> on a plain Latin letter that has accented variants (<code>a c d e i l n o r s t u y z</code>) opens a one-row popup of its accents (e.g. holding <code>a</code> offers <code>á à â ã ä å ą</code>); <strong>LEFT/RIGHT</strong> picks, <strong>Enter</strong> inserts it, <strong>Cancel</strong> dismisses with no change. Holding a letter with no accented variants (e.g. <code>b</code>) does nothing. Works on whichever page is currently showing Latin, whether that's Main or Additional.</p>
<hr />
<h3 id="contacts">Contacts</h3>
<table>
@@ -1954,7 +1970,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "../../..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -21,7 +21,7 @@
<link rel="icon" href="../../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -29,7 +29,7 @@
<link rel="stylesheet" href="../../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1454,6 +1454,50 @@
<nav class="md-nav" aria-label="Auto-Reply Bot">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#channel-tab" class="md-nav__link">
<span class="md-ellipsis">
Channel tab
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#room-tab" class="md-nav__link">
<span class="md-ellipsis">
Room tab
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#direct-tab" class="md-nav__link">
<span class="md-ellipsis">
Direct tab
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#other-tab" class="md-nav__link">
<span class="md-ellipsis">
Other tab
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#commands" class="md-nav__link">
<span class="md-ellipsis">
@@ -1490,6 +1534,34 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#admin" class="md-nav__link">
<span class="md-ellipsis">
Admin
</span>
</a>
<nav class="md-nav" aria-label="Admin">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#this-device" class="md-nav__link">
<span class="md-ellipsis">
This device
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
@@ -1713,6 +1785,50 @@
<nav class="md-nav" aria-label="Auto-Reply Bot">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#channel-tab" class="md-nav__link">
<span class="md-ellipsis">
Channel tab
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#room-tab" class="md-nav__link">
<span class="md-ellipsis">
Room tab
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#direct-tab" class="md-nav__link">
<span class="md-ellipsis">
Direct tab
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#other-tab" class="md-nav__link">
<span class="md-ellipsis">
Other tab
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#commands" class="md-nav__link">
<span class="md-ellipsis">
@@ -1749,6 +1865,34 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#admin" class="md-nav__link">
<span class="md-ellipsis">
Admin
</span>
</a>
<nav class="md-nav" aria-label="Admin">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#this-device" class="md-nav__link">
<span class="md-ellipsis">
This device
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
@@ -1795,7 +1939,7 @@
</tr>
</tbody>
</table>
<p>The Tools screen is a hub for GPS trail recording, nearby node browsing, ringtone editing, auto-reply bot, auto-advert, live location sharing, locator, compass, clock tools (alarm / timer / stopwatch), device diagnostics, and repeater mode. Tools are grouped into collapsible <strong>Location</strong> / <strong>Comms</strong> / <strong>System</strong> sections — the same fold-in-place model as Settings; Tools always opens folded back to the section list. Navigate with <strong>UP/DOWN</strong>, press <strong>Enter</strong> on a section header to expand or collapse it, or on a tool to open it.</p>
<p>The Tools screen is a hub for GPS trail recording, nearby node browsing, ringtone editing, auto-reply bot, auto-advert, live location sharing, locator, compass, clock tools (alarm / timer / stopwatch), device diagnostics, repeater mode, and remote admin. Tools are grouped into collapsible <strong>Location</strong> / <strong>Comms</strong> / <strong>System</strong> sections — the same fold-in-place model as Settings; Tools always opens folded back to the section list. Navigate with <strong>UP/DOWN</strong>, press <strong>Enter</strong> on a section header to expand or collapse it, or on a tool to open it.</p>
<hr />
<h2 id="nearby-nodes">Nearby Nodes</h2>
<table>
@@ -1875,6 +2019,10 @@
<td>selected node has GPS <strong>and</strong> a public key — pins it as the active <strong>Locator/Nav target</strong> right away (see <strong>Locator</strong>)</td>
</tr>
<tr>
<td>Admin</td>
<td>selected node is a saved <strong>repeater or room server</strong> contact — opens <strong>Tools Admin</strong> for it directly (see <strong>Admin</strong>)</td>
</tr>
<tr>
<td>Sort: Dist/Recent</td>
<td>browsing stored nodes — <strong>LEFT/RIGHT</strong> on the row flips distance ↔ last-heard in place</td>
</tr>
@@ -2486,8 +2634,13 @@ Mark the spot first with <strong>Tools Trail → Hold Enter → Mark here</s
</tr>
</tbody>
</table>
<p>Automatically replies to incoming messages that contain a configured trigger word (case-insensitive, contains match).</p>
<p>When the bot is enabled it listens to DMs by default. Channel monitoring is an optional addition — select a channel separately to activate it alongside DM mode.</p>
<!-- screenshots pending: these predate the tab-carousel layout below (still show the old flat grouped list) -->
<p>Automatically replies to incoming messages that contain a configured trigger word (case-insensitive, contains match). The bot has three independent targets — <strong>DM</strong>, a monitored <strong>Channel</strong>, and a monitored <strong>Room</strong> — each with its own trigger/reply pair.</p>
<p>The screen is a <strong>circular tab carousel</strong>, the same style as Tools Nearby Nodes' filter tabs: <strong>LEFT/RIGHT</strong> switches between the <strong>Channel</strong> / <strong>Room</strong> / <strong>Direct</strong> / <strong>Other</strong> tabs (opens on Channel), <strong>UP/DOWN</strong> moves between the rows within the active tab, and <strong>Enter</strong> acts on the selected row (LEFT/RIGHT is reserved entirely for tab-switching, so every row's value is changed via Enter, not by cycling it in place).</p>
<p>Each target has its own <strong>Enable</strong> toggle on its own tab, and they're fully independent — you can run only a channel bot, only a room bot, only DM, or any combination, with no need to also switch on the others.</p>
<p>Each target also has its own <strong>Commands</strong> toggle (see below) — DM, channel and room can each independently answer <code>!</code> queries or stay quiet, same as Enable.</p>
<h4 id="channel-tab">Channel tab</h4>
<table>
<thead>
<tr>
@@ -2498,44 +2651,115 @@ Mark the spot first with <strong>Tools Trail → Hold Enter → Mark here</s
<tbody>
<tr>
<td>Enable</td>
<td>ON / OFF — enables DM listening</td>
<td>ON / OFF — <strong>Enter</strong> toggles. Independent of which channel is picked below, so switching it off and back on remembers the last channel.</td>
</tr>
<tr>
<td>Channel</td>
<td>OFF, or which channel to additionally monitor (cycles through your channels)</td>
</tr>
<tr>
<td>Trigger DM</td>
<td>Word or phrase that activates the DM reply (case-insensitive). A lone <code>*</code> means <strong>reply to every DM</strong> (away mode) and is shown as <code>(any msg)</code>.</td>
</tr>
<tr>
<td>Reply DM</td>
<td>Reply text for DMs; supports <code>{time}</code>, <code>{loc}</code> and sensor placeholders</td>
</tr>
<tr>
<td>Trigger Ch</td>
<td>Independent trigger for the monitored channel. <code>*</code> means <strong>reply to every channel message</strong> — bounded by the per-channel cooldown, but use sparingly on a busy channel.</td>
</tr>
<tr>
<td>Reply Ch</td>
<td>Reply text for channel messages; supports the same placeholders</td>
<td>Which channel the bot monitors — always shows the last-picked channel (or <code>(none)</code> if none exist yet), regardless of Enable. <strong>Enter</strong> opens the full channel picker (the same one Live Share's <strong>To</strong> row uses).</td>
</tr>
<tr>
<td>Commands</td>
<td>ON / OFF — answer <code>!</code> query commands (see below)</td>
<td>ON / OFF — <strong>Enter</strong> toggles. Answer <code>!</code> query commands on the monitored channel, independent of the other two tabs' Commands settings.</td>
</tr>
<tr>
<td>Quiet from/to</td>
<td>Local-time window during which auto-replies stay silent; set both equal (<code>OFF</code>) to disable</td>
<td>Trigger</td>
<td>Independent trigger for the monitored channel. <code>*</code> means <strong>reply to every channel message</strong> — bounded by the per-channel cooldown, but use sparingly on a busy channel.</td>
</tr>
<tr>
<td>Reply</td>
<td>Reply text for channel messages; supports the same placeholders as Direct's Reply.</td>
</tr>
</tbody>
</table>
<p>The DM and channel triggers are independent, so you can run e.g. an away-message (<code>*</code>) in DMs while the channel reacts only to a specific keyword (or vice-versa).</p>
<p>The header shows a running count of auto-replies sent since boot.</p>
<p><strong>Throttle.</strong> Auto-replies are rate-limited <strong>per contact</strong> (10 s), so a second sender is never starved while one contact is on cooldown. The channel bot keeps a single 10 s cooldown and won't echo a message identical to its own reply (so two bots running the same reply text on one channel can't ping-pong); the cooldown caps any residual back-and-forth.</p>
<h4 id="room-tab">Room tab</h4>
<table>
<thead>
<tr>
<th>Setting</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Enable</td>
<td>ON / OFF — <strong>Enter</strong> toggles. Independent of which room is picked below.</td>
</tr>
<tr>
<td>Room</td>
<td>Which room server the bot posts to — always shows the last-picked room (or <code>(none)</code> if you have none yet), regardless of Enable. <strong>Enter</strong> opens the full room picker. Picking a room you've never logged into prompts for its password right there — the bot can't post to a room it has no working login for, so this is the moment to set one up.</td>
</tr>
<tr>
<td>Commands</td>
<td>ON / OFF — <strong>Enter</strong> toggles. Answer <code>!</code> query commands on the monitored room, independent of the other two tabs' Commands settings.</td>
</tr>
<tr>
<td>Trigger</td>
<td>Independent trigger for the monitored room. <code>*</code> means <strong>reply to every post in the room</strong>.</td>
</tr>
<tr>
<td>Reply</td>
<td>Reply text for room posts; supports the same placeholders as Direct's Reply.</td>
</tr>
</tbody>
</table>
<h4 id="direct-tab">Direct tab</h4>
<table>
<thead>
<tr>
<th>Setting</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Enable</td>
<td>ON / OFF — <strong>Enter</strong> toggles. Enables DM listening.</td>
</tr>
<tr>
<td>DM allow</td>
<td><strong>All</strong> / <strong>Fav</strong><strong>Enter</strong> toggles. Who the DM bot (trigger-reply and commands) responds to. All (default): any DM sender. Fav: only contacts you've starred (the same star Settings Contacts filters on) — use this to keep a public bot from being spammed by strangers while it still answers people you trust.</td>
</tr>
<tr>
<td>Commands</td>
<td>ON / OFF — <strong>Enter</strong> toggles. Answer <code>!</code> query commands (see below) in DMs.</td>
</tr>
<tr>
<td>Trigger</td>
<td>Word or phrase that activates the DM reply (case-insensitive). A lone <code>*</code> means <strong>reply to every DM</strong> (away mode) and is shown as <code>(any msg)</code>. <strong>Enter</strong> opens the keyboard.</td>
</tr>
<tr>
<td>Reply</td>
<td>Reply text for DMs; supports <code>{time}</code>, <code>{loc}</code>, <code>{name}</code>, <code>{hops}</code> and sensor placeholders. <strong>Enter</strong> opens the keyboard.</td>
</tr>
</tbody>
</table>
<h4 id="other-tab">Other tab</h4>
<table>
<thead>
<tr>
<th>Setting</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Quiet from</td>
<td><strong>Enter</strong> opens a stepper (value shown bracketed, e.g. <code>[14:00]</code>) — <strong>UP/DOWN</strong> steps the hour, <strong>Enter</strong>/<strong>Cancel</strong> confirms. Local-time window start; set from = to (<code>OFF</code>) to disable quiet hours entirely. Applies to all three targets' trigger-replies.</td>
</tr>
<tr>
<td>Quiet to</td>
<td>Same stepper; window end.</td>
</tr>
</tbody>
</table>
<p>The DM, channel and room triggers are independent, so you can run e.g. an away-message (<code>*</code>) in DMs while the channel or room reacts only to a specific keyword (or vice-versa).</p>
<p><code>{name}</code> (the triggering sender's name) and <code>{hops}</code> (<code>direct</code> or <code>N hops</code>) are only meaningful when replying to an actual incoming message, so — unlike <code>{time}</code>/<code>{loc}</code>/the sensor placeholders — they're offered only while editing a <strong>Reply</strong> field here, not on the general message-compose keyboard.</p>
<p>The header shows a running count of auto-replies sent since boot, alongside the tab bar.</p>
<p><strong>Room posting requires a login.</strong> The room bot reuses whatever session the device already has with that room server (Messages Rooms <strong>Login…</strong>, or a password saved from an earlier login/the phone app) — it has no way to prompt for a password itself in the background. If the saved password stops working, the room bot just silently stops posting there, the same as a manual post would; log back in from Messages to fix it.</p>
<p><strong>Throttle.</strong> DM auto-replies are rate-limited <strong>per contact</strong> (10 s), so a second sender is never starved while one contact is on cooldown. The channel and room bots each keep their own single 10 s cooldown and won't echo a message identical to their own reply (so two bots running the same reply text on one channel/room can't ping-pong); the cooldown caps any residual back-and-forth.</p>
<p><strong>Quiet hours</strong> suppress the push (trigger) replies between the configured local hours; a window where <em>from</em> is later than <em>to</em> wraps past midnight. Commands are a pull (explicitly requested), so they answer even during quiet hours.</p>
<h3 id="commands">Commands</h3>
<p>With <strong>Commands</strong> ON, a DM beginning with <code>!</code> is answered with live node data, independent of the trigger:</p>
<p>With a tab's <strong>Commands</strong> ON, a message beginning with <code>!</code> on that target is answered with live node data, independent of the trigger:</p>
<table>
<thead>
<tr>
@@ -2579,7 +2803,7 @@ Mark the spot first with <strong>Tools Trail → Hold Enter → Mark here</s
</tbody>
</table>
<p>Several commands can be combined in one message — <code>!batt !time !hops</code> is answered with a single <code>4.10V | 14:30 | 3 hops</code> reply (one transmission). A message with no recognised command falls through to the trigger bot.</p>
<p>Commands also work on the <strong>monitored channel</strong> (the one selected for channel mode) — anyone there can query the node. Channel replies are broadcast to everyone, so unlike DM commands they respect quiet hours and use the shared per-channel cooldown. DM commands use the per-contact throttle.</p>
<p>Each target's Commands toggle is independent — e.g. answer <code>!ping</code> in DMs but stay quiet on a busy public channel. Channel and room replies are broadcast/posted to everyone there, so unlike DM commands they respect quiet hours and use their own shared cooldown. DM commands use the per-contact throttle and the <strong>DM allow</strong> scope above.</p>
<hr />
<h2 id="diagnostics">Diagnostics</h2>
<table>
@@ -2598,7 +2822,30 @@ Mark the spot first with <strong>Tools Trail → Hold Enter → Mark here</s
</table>
<!-- screenshot pending: Diagnostics — live device/mesh stats rows (uptime, rx/tx counters, heap, RSSI/SNR, queue, errors) -->
<p>A single read-only screen of live device and mesh stats, refreshed once a second. On a small OLED the rows scroll with <strong>UP/DOWN</strong>; on a larger e-ink display they all fit at once.</p>
<p>A circular tab carousel of live device and mesh stats, refreshed once a second (same tab idiom as Auto-Reply Bot / Nodes). <strong>LEFT/RIGHT</strong> switches tab; <strong>UP/DOWN</strong> scrolls within it on a small OLED — on a larger e-ink display a tab's rows all fit at once.</p>
<table>
<thead>
<tr>
<th>Tab</th>
<th>Shows</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Live</strong></td>
<td>Live counters — see table below.</td>
</tr>
<tr>
<td><strong>System</strong></td>
<td>Static device identity: firmware version + build date, device model, node name, and the active radio parameters.</td>
</tr>
<tr>
<td><strong>Font</strong></td>
<td>A rendering test card — one sample line per script the on-device font claims to cover (Latin, diacritics, Greek, Cyrillic, digits, symbols), so its coverage can be eyeballed directly.</td>
</tr>
</tbody>
</table>
<p><strong>Live</strong> tab rows:</p>
<table>
<thead>
<tr>
@@ -2665,7 +2912,7 @@ Mark the spot first with <strong>Tools Trail → Hold Enter → Mark here</s
</tr>
</tbody>
</table>
<p>The packet counters, <strong>Forwarded</strong> and <strong>Errors</strong> are cumulative since boot. <strong>Hold Enter</strong> opens a one-item <em>Reset counters</em> menu (Back dismisses it); the live readings (noise, RSSI/SNR, pool, queue, uptime) are not affected. <strong>Cancel/Back</strong> returns to the Tools list.</p>
<p>The packet counters, <strong>Forwarded</strong> and <strong>Errors</strong> are cumulative since boot. On the <strong>Live</strong> tab, <strong>Hold Enter</strong> opens a one-item <em>Reset counters</em> menu (Back dismisses it); the live readings (noise, RSSI/SNR, pool, queue, uptime) are not affected. <strong>Cancel/Back</strong> returns to the Tools list.</p>
<p>The counters make the repeater behaviour observable: <strong>Forwarded</strong> confirms the node is actually relaying (not just configured to), and <strong>Pool free</strong> / <strong>Queue</strong> show whether forwarding is exhausting the packet pool. See <strong>Tools Repeater</strong> for the relaying options.</p>
<hr />
<h2 id="repeater">Repeater</h2>
@@ -2752,6 +2999,56 @@ Mark the spot first with <strong>Tools Trail → Hold Enter → Mark here</s
<p><strong>Same network vs. separate network.</strong> With <strong>Network = Current</strong> (or a Custom profile set equal to your companion settings) the repeater stays on your own network — you keep messaging while relaying. With a <em>different</em> Custom profile the device moves entirely onto that network while relaying (a single radio can't be on two at once) and returns to your companion network when the repeater is switched off. The profile also re-applies after a reboot if the repeater was left on.</p>
<p>While the repeater is on, a <strong>»</strong> indicator appears in the status bar (same blink convention as the auto-advert and trail markers) so you can tell it's relaying at a glance. Two radio settings are also overridden while relaying and restored afterwards: <strong>Settings Radio Pwr save</strong> is forced off (a repeater must listen continuously) and <strong>Auto pwr</strong> is forced off (a repeater holds full TX power for consistent relay reach). Both show <code>--</code> in Settings while the repeater is on.</p>
<p>Live forwarding stats — <strong>Forwarded</strong>, <strong>Pool free</strong>, <strong>Queue</strong> — are shown on <strong>Tools Diagnostics</strong> (this screen is config-only).</p>
<hr />
<h2 id="admin">Admin</h2>
<!-- screenshot pending: Admin — target picker, command entry, reply view -->
<p>Send commands to a <strong>repeater/room server you have admin permission on</strong> — the on-device equivalent of the companion app's repeater-admin feature. See <a href="../../../cli_commands/">CLI Commands</a> for the full command grammar. (Admin only manages <em>remote</em> nodes; this device's own name, radio, TX power and reboot live in <strong>Settings</strong> — see below.)</p>
<ol>
<li><strong>Select a node</strong> — opening <strong>Tools Admin</strong> goes straight to <strong>Tools Nodes</strong> (the same screen, filters, sort and live scan as browsing it normally) so picking a node for Admin looks exactly like using Nodes for anything else; <strong>Enter</strong> on a repeater/room row hands it to Admin, <strong>Cancel</strong> returns to Tools. Admin is also reachable directly from a node's own <strong>Hold Enter</strong> menu in Nodes.</li>
<li><strong>Log in</strong> — type the node's <strong>admin password</strong> (the same login handshake Messages uses for room servers; a repeater's admin password is set with the <code>password</code> CLI command). If a password was already saved for this node from an earlier successful login, it retries silently instead of prompting. Only a login that comes back with <strong>admin</strong>-level permission unlocks the next step — anything less shows "Not admin on this node".</li>
<li><strong>Pick a category and a field</strong> — a tab carousel (<strong>LEFT/RIGHT</strong> to switch category, <strong>UP/DOWN</strong> to move within it, same as Auto-Reply Bot's tabs), so common settings don't need the CLI grammar memorised:</li>
</ol>
<table>
<thead>
<tr>
<th>Tab</th>
<th>Rows</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>System</strong></td>
<td>Name, Owner info, Admin password</td>
</tr>
<tr>
<td><strong>Radio</strong></td>
<td>Frequency, Bandwidth, Spreading factor, Coding rate, TX power</td>
</tr>
<tr>
<td><strong>Routing</strong></td>
<td>Repeat, Advert interval, Flood advert interval, Max hops</td>
</tr>
<tr>
<td><strong>Actions</strong></td>
<td>Send advert, Send zero-hop advert, Sync clock, Reboot, <strong>Custom command...</strong></td>
</tr>
</tbody>
</table>
<p><strong>Enter</strong> on a row does one of four things, depending on the field:
- <strong>Name / Owner info</strong> first <strong>fetch</strong> the node's current value, then open the keyboard <strong>pre-filled</strong> with it to edit — submitting sends the change. If the fetch fails or times out, the keyboard still opens (blank), so the value can be set blind.
- <strong>Radio and Routing rows</strong> are typed, not free text: <strong>Repeat</strong> is an ON/OFF toggle; <strong>Advert interval / Flood advert interval / Max hops / TX power</strong> are number steppers (<strong>LEFT/RIGHT</strong> to adjust, within that field's valid range); <strong>Frequency</strong> uses the same digit-by-digit cursor editor as Settings' own Radio screen (<strong>LEFT/RIGHT</strong> moves between digits, <strong>UP/DOWN</strong> changes the selected one); <strong>Bandwidth / Spreading factor / Coding rate</strong> step through their valid discrete LoRa values with <strong>LEFT/RIGHT</strong>. All four Radio-tuple fields (Frequency/Bandwidth/SF/Coding rate) fetch and re-send the same underlying <code>radio</code> value together — editing any one of them still only overwrites that one, the other three round-trip unchanged. <strong>Enter</strong> sends the change; <strong>Cancel</strong> discards it and returns to the row list without sending anything.
- <strong>Admin password</strong> has no fetch (there's no way to read a password back) — it opens straight to a blank keyboard.
- <strong>Actions</strong> (Reboot, Send advert, …) send immediately, no editing step.
- <strong>Custom command...</strong> (last row of Actions) opens the same free-text entry for anything not covered above — up to 160 characters, see the linked reference for the full grammar. The keyboard's <strong>{}</strong> key doubles as command completion here: it lists commands matching whatever's typed since the last space (narrowing as you type), and picking one completes that word instead of just inserting after it.
4. <strong>Read the reply</strong> — the text reply opens in a scrollable view (<strong>UP/DOWN</strong> to scroll, <strong>Cancel/Enter</strong> to go back to the category tabs).</p>
<blockquote>
<p>[!WARNING]
This screen can run <strong>destructive</strong> commands on the <em>remote</em> node — <code>reboot</code>, <code>erase</code>, a new admin password, and others. That's the same capability the phone app's repeater-admin feature already exposes, not a new risk, but double-check the value and the target before sending.</p>
</blockquote>
<p><strong>Passwords are remembered across reboots</strong>, the same self-healing behaviour as room logins in Messages: after a successful admin login the password is saved on the device, so picking that node again — even after a power cycle — logs back in silently. If a saved password stops working (e.g. it was changed on the node), the failed login forgets it, so the next pick prompts for a new one. A correct password that just lacks admin permission is left alone — retyping the same one wouldn't change the outcome. Some commands are marked <strong>Serial Only</strong> in the CLI reference — those reject a remote CLI request and only work over that node's own USB serial connection.</p>
<h3 id="this-device">This device</h3>
<p>Admin doesn't manage the companion itself — its own settings live in <strong>Settings</strong>: <strong>Radio</strong> (preset / freq / SF / BW / CR) and <strong>TX power</strong> in the Radio section, and <strong>Name</strong> and <strong>Reboot</strong> in the System section. <strong>Send advert</strong> is the home <strong>ADVERT</strong> page.</p>
@@ -2804,7 +3101,7 @@ Mark the spot first with <strong>Tools Trail → Hold Enter → Mark here</s
<script id="__config" type="application/json">{"annotate": null, "base": "../../..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -2318,7 +2318,7 @@ function parseStatsPackets(buffer: ArrayBuffer): StatsPackets {
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>

View File

@@ -23,7 +23,7 @@
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
@@ -31,7 +31,7 @@
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
@@ -1424,7 +1424,7 @@
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>