Files
meshcore-bot/path-command-config/index.html
T
2026-09-20 19:56:33 +00:00

2235 lines
59 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Documentation for the MeshCore bot and its services">
<link rel="canonical" href="https://agessaman.github.io/meshcore-bot/path-command-config/">
<link rel="prev" href="../checkin-api/">
<link rel="next" href="../config-validation/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
<title>Path Command - Meshcore Bot Documentation</title>
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="cyan">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#path-command-configuration-guide" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="Meshcore Bot Documentation" class="md-header__button md-logo" aria-label="Meshcore Bot Documentation" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Meshcore Bot Documentation
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Path Command
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="cyan" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="cyan" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/agessaman/meshcore-bot" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
meshcore-bot
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href=".." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="../getting-started/" class="md-tabs__link">
Quick Start
</a>
</li>
<li class="md-tabs__item">
<a href="../installation/" class="md-tabs__link">
Installation
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="../configuration/" class="md-tabs__link">
Configuration
</a>
</li>
<li class="md-tabs__item">
<a href="../web-viewer/" class="md-tabs__link">
Web Viewer
</a>
</li>
<li class="md-tabs__item">
<a href="../command-reference/" class="md-tabs__link">
Command Reference
</a>
</li>
<li class="md-tabs__item">
<a href="../service-plugins/" class="md-tabs__link">
Service Plugins
</a>
</li>
<li class="md-tabs__item">
<a href="../faq/" class="md-tabs__link">
FAQ
</a>
</li>
<li class="md-tabs__item">
<a href="../upgrade/" class="md-tabs__link">
Upgrade
</a>
</li>
<li class="md-tabs__item">
<a href="../solar-conditions-provenance/" class="md-tabs__link">
Project
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted md-nav--integrated" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="Meshcore Bot Documentation" class="md-nav__button md-logo" aria-label="Meshcore Bot Documentation" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
Meshcore Bot Documentation
</label>
<div class="md-nav__source">
<a href="https://github.com/agessaman/meshcore-bot" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
meshcore-bot
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../getting-started/" class="md-nav__link">
<span class="md-ellipsis">
Quick Start
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
<span class="md-ellipsis">
Installation
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Installation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../installation/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../docker/" class="md-nav__link">
<span class="md-ellipsis">
Docker
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../service-installation/" class="md-nav__link">
<span class="md-ellipsis">
Service
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" checked>
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="">
<span class="md-ellipsis">
Configuration
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Configuration
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../configuration/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../data-retention/" class="md-nav__link">
<span class="md-ellipsis">
Data retention
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../local-plugins/" class="md-nav__link">
<span class="md-ellipsis">
Local plugins and services
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../checkin-api/" class="md-nav__link">
<span class="md-ellipsis">
Check-in API
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Path Command
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Path Command
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#multi-byte-path-support" class="md-nav__link">
<span class="md-ellipsis">
Multi-byte path support
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#reply-prefix-and-repeater-name-gating" class="md-nav__link">
<span class="md-ellipsis">
Reply prefix and repeater name gating
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#quick-start-presets" class="md-nav__link">
<span class="md-ellipsis">
Quick Start: Presets
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#core-settings" class="md-nav__link">
<span class="md-ellipsis">
Core Settings
</span>
</a>
<nav class="md-nav" aria-label="Core Settings">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#geographic-proximity" class="md-nav__link">
<span class="md-ellipsis">
Geographic Proximity
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#graph-based-selection" class="md-nav__link">
<span class="md-ellipsis">
Graph-Based Selection
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#graph-vs-geographic-selection" class="md-nav__link">
<span class="md-ellipsis">
Graph vs Geographic Selection
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#distance-penalties-intermediate-hops" class="md-nav__link">
<span class="md-ellipsis">
Distance Penalties (Intermediate Hops)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#zero-hop-bonus" class="md-nav__link">
<span class="md-ellipsis">
Zero-Hop Bonus
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#final-hop-proximity-advanced" class="md-nav__link">
<span class="md-ellipsis">
Final Hop Proximity (Advanced)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#path-validation-bonus" class="md-nav__link">
<span class="md-ellipsis">
Path Validation Bonus
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#graph-persistence-advanced" class="md-nav__link">
<span class="md-ellipsis">
Graph Persistence (Advanced)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#raspberry-pi-low-power-profile" class="md-nav__link">
<span class="md-ellipsis">
Raspberry Pi / Low-Power Profile
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#preset-configurations" class="md-nav__link">
<span class="md-ellipsis">
Preset Configurations
</span>
</a>
<nav class="md-nav" aria-label="Preset Configurations">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#balanced-default" class="md-nav__link">
<span class="md-ellipsis">
balanced (Default)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#geographic" class="md-nav__link">
<span class="md-ellipsis">
geographic
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#graph" class="md-nav__link">
<span class="md-ellipsis">
graph
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#geographic-scoring-toggle" class="md-nav__link">
<span class="md-ellipsis">
Geographic scoring toggle
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#typical-lora-transmission-ranges" class="md-nav__link">
<span class="md-ellipsis">
Typical LoRa Transmission Ranges
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../config-validation/" class="md-nav__link">
<span class="md-ellipsis">
Config validation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../region-warnings/" class="md-nav__link">
<span class="md-ellipsis">
Region warnings
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../web-viewer/" class="md-nav__link">
<span class="md-ellipsis">
Web Viewer
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
Command Reference
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Command Reference
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../command-reference/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../repeater-commands/" class="md-nav__link">
<span class="md-ellipsis">
Repeater Commands
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../command-reference-website/" class="md-nav__link">
<span class="md-ellipsis">
Custom Command Website
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../develop-command-scripts/" class="md-nav__link">
<span class="md-ellipsis">
Developing Commands
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7" >
<label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="0">
<span class="md-ellipsis">
Service Plugins
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
Service Plugins
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../service-plugins/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../discord-bridge/" class="md-nav__link">
<span class="md-ellipsis">
Discord Bridge
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../telegram-bridge/" class="md-nav__link">
<span class="md-ellipsis">
Telegram Bridge
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../packet-capture/" class="md-nav__link">
<span class="md-ellipsis">
Packet Capture
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../map-uploader/" class="md-nav__link">
<span class="md-ellipsis">
Map Uploader
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../weather-service/" class="md-nav__link">
<span class="md-ellipsis">
Weather Service
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../earthquake-service/" class="md-nav__link">
<span class="md-ellipsis">
Earthquake Service
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../repeater-prefix-collision-service/" class="md-nav__link">
<span class="md-ellipsis">
Repeater Prefix Collision
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../worldcup/" class="md-nav__link">
<span class="md-ellipsis">
World Cup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../FEEDS/" class="md-nav__link">
<span class="md-ellipsis">
Feed Management
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../faq/" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../upgrade/" class="md-nav__link">
<span class="md-ellipsis">
Upgrade
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_10" >
<label class="md-nav__link" for="__nav_10" id="__nav_10_label" tabindex="0">
<span class="md-ellipsis">
Project
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_10_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_10">
<span class="md-nav__icon md-icon"></span>
Project
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../solar-conditions-provenance/" class="md-nav__link">
<span class="md-ellipsis">
Solar conditions provenance
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="path-command-configuration-guide">Path Command Configuration Guide</h1>
<p>This document explains all configuration parameters for the Path Command, which decodes hex path data to identify repeaters in message routing paths.</p>
<h2 id="multi-byte-path-support">Multi-byte path support</h2>
<p>The path command supports <strong>1-, 2-, and 3-byte-per-hop</strong> paths (2, 4, or 6 hex characters per node).</p>
<ul>
<li><strong><code>path</code> with no arguments</strong>: Uses the current message’s decoded path when available (from routing info). No re-parsing; node list and hop size come from the packet.</li>
<li><strong><code>path &lt;hex&gt;</code> with arguments</strong>:</li>
<li><strong>Comma-separated</strong> (e.g. <code>path 0102,5f7e</code>): Hop size is inferred from token length. All tokens must be the same length (2, 4, or 6 hex chars). Example: <code>0102,5f7e</code> → two 2-byte hops.</li>
<li><strong>Continuous hex</strong> (e.g. <code>path 01025f7e</code>): The bot’s [Bot] <strong><code>prefix_bytes</code></strong> is used (2 hex chars = 1 byte, 4 = 2 bytes, 6 = 3 bytes). Use comma-separated input to force a multi-byte interpretation when the bot is in 1-byte mode.</li>
</ul>
<h2 id="reply-prefix-and-repeater-name-gating">Reply prefix and repeater name gating</h2>
<p>These options only affect the <strong>path</strong> command’s reply text and whether repeater names are resolved from the database.</p>
<p><strong><code>reply_prefix</code></strong> (string, default empty)</p>
<ul>
<li>Prepended as the first line of path command RF replies (only the <strong>first</strong> chunk when the reply is split for length).</li>
<li>Placeholders: <code>{sender}</code>, <code>{connection_info}</code>, <code>{path}</code>, <code>{hops}</code>, <code>{hops_label}</code>, <code>{timestamp}</code>, <code>{snr}</code>, <code>{rssi}</code>, <code>{packet_hash}</code>, <code>{path_distance}</code>.</li>
<li><code>{path_distance}</code> is the total distance travelled, summed sender → each resolved hop → bot (e.g. <code>12.4km</code>). It is <strong>empty</strong> whenever the chain cannot be measured end to end: an unresolved hop, a prefix collision, a node with no stored coordinates, an unknown sender position, or no <code>[Bot] bot_latitude</code>/<code>bot_longitude</code>. A partial sum is never reported, since it would understate the real distance.</li>
<li><code>{packet_hash}</code> is the 16-char MeshCore packet identity hash (uppercase hex) of the packet that carried the request. It is <strong>empty</strong> when RF correlation could not tie a heard packet to this message, so a hash from an unrelated transmission is never shown.</li>
<li>Supports the same <strong>feed-style pipe filters</strong> as the test command's <code>response_format</code> (see <code>modules/response_template.py</code>). Use <code>prefix_if_nonempty</code> so a label disappears along with an empty distance:</li>
</ul>
<p><div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="na">reply_prefix</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"{path_distance|prefix_if_nonempty:📏 }\n"</span>
</code></pre></div>
- <code>hops_min:N</code> clears a field unless the message actually travelled at least N hops. <code>{path_distance}</code> renders <code>N/A</code> on a direct message, which <code>prefix_if_nonempty</code> treats as a value, so gate it first: <code>{path_distance|hops_min:1|prefix_if_nonempty:📏 }</code>. Unlike <code>pathbytes_min:N</code>, which asks how the path is <em>encoded</em>, this keeps a measurable one-byte multi-hop path.
- <code>if_nonempty:LITERAL</code> (alias <code>if_notempty</code>) renders <code>LITERAL</code> when the value is non-empty after prior filters, and clears entirely otherwise — the opposite pairing of <code>prefix_if_nonempty</code>, useful when the whole output should be a fixed (or field-built) literal rather than the value with a label prepended. Since <code>{packet_hash}</code> is empty whenever RF correlation fails, gating on it hides the whole clause instead of printing a broken link:</p>
<p><div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="na">reply_prefix = {packet_hash|if_nonempty</span><span class="o">:</span><span class="s">"https://scope.example.net/#/packets/{packet_hash}"</span><span class="na">}</span>
</code></pre></div>
The <code>LITERAL</code> argument may itself be a double-quoted string containing nested <code>{field}</code> placeholders (expanded before the filter runs), so the link above still carries the packet hash even though the field being gated on (<code>packet_hash</code>) and the field inside the literal are the same one. Quoting also ends the argument at the closing quote, so more filters can follow it — including after <code>prefix_if_nonempty</code>, whose <em>unquoted</em> argument still swallows the rest of the chain so that a literal may contain <code>|</code>.
- <code>shorten</code> (alias <code>shorten_url</code>, the same filter feed formats document) runs the value through the shared shortener configured under <code>[External_Data]</code> (<code>short_url_website</code>, <code>short_url_website_service</code> — <code>gd</code> for v.gd/is.gd-compatible or <code>shlink</code>, and <code>short_url_website_api_key</code> where required). It falls back to the original, unshortened value if shortening fails or isn't configured, so a clause never silently disappears because of a network error. Chain it after building the link so only the final URL is sent over RF:</p>
<p><div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="na">reply_prefix = {packet_hash|if_nonempty</span><span class="o">:</span><span class="s">"https://scope.example.net/#/packets/{packet_hash}"</span><span class="na">|shorten}</span>
</code></pre></div>
For <code>shlink</code>, <code>short_url_website</code> is required — with no base configured the bot skips shortening rather than sending your API key to the default <code>gd</code> host.</p>
<p><strong><code>minimum_path_bytes</code></strong> (integer <code>0</code>–<code>3</code>, default <code>0</code>)</p>
<ul>
<li><strong><code>0</code> or <code>1</code></strong>: Always resolve repeater names when decoding a path (legacy behavior).</li>
<li><strong><code>2</code> or <code>3</code></strong>: Resolve names only when the packet path uses at least that many <strong>bytes per hop</strong> (from routing metadata or inferred from comma-separated hex width). Otherwise the bot replies with <code>Path: …</code> (hex) and a short tip, without a DB lookup.</li>
<li><strong>Not</strong> the same as <code>require_path_bytes_greater_or_equal_to</code>: that setting can block the path command entirely; <code>minimum_path_bytes</code> only gates naming.</li>
</ul>
<h2 id="quick-start-presets">Quick Start: Presets</h2>
<p>The Path Command supports three presets that configure multiple related settings:</p>
<ul>
<li><strong><code>balanced</code></strong> (default): Balanced approach using both graph evidence and geographic proximity</li>
<li><strong><code>geographic</code></strong>: Prioritize geographic proximity over graph evidence (better for local networks)</li>
<li><strong><code>graph</code></strong>: Prioritize graph evidence over geographic proximity (better for well-connected networks)</li>
</ul>
<p>Set the preset using:
<div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="na">path_selection_preset</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">balanced</span>
</code></pre></div></p>
<h2 id="core-settings">Core Settings</h2>
<h3 id="geographic-proximity">Geographic Proximity</h3>
<p><strong><code>proximity_method</code></strong> (<code>simple</code> | <code>path</code>)
- <code>simple</code>: Use proximity to bot location only
- <code>path</code>: Use proximity to previous/next nodes in path (more realistic routing)
- Default: <code>simple</code></p>
<p><strong><code>path_proximity_fallback</code></strong> (boolean)
- When path proximity can't be calculated, fall back to simple proximity
- Default: <code>true</code></p>
<p><strong><code>max_proximity_range</code></strong> (kilometers, 0 = disabled)
- Maximum distance for geographic proximity consideration
- Repeaters beyond this distance are filtered out or have reduced confidence
- Default: <code>200</code> (long LoRa transmission range)</p>
<p><strong><code>recency_weight</code></strong> (0.0 to 1.0)
- Controls recency vs proximity weighting
- <code>0.0</code> = 100% proximity (only distance matters)
- <code>1.0</code> = 100% recency (only when last heard matters)
- <code>0.4</code> = 40% recency, 60% proximity (balanced)
- Default: <code>0.4</code></p>
<p><strong><code>recency_decay_half_life_hours</code></strong> (hours)
- How quickly recency scores decay for older repeaters
- Default: <code>12</code> hours
- For 48-72 hour advert intervals, use <code>36-48</code> hours</p>
<p><strong><code>max_repeater_age_days</code></strong> (days, 0 = disabled)
- Only include repeaters heard within this many days
- Helps filter out stale repeaters
- Default: <code>14</code> days</p>
<h2 id="graph-based-selection">Graph-Based Selection</h2>
<p><strong>Prefix length and graph conflation</strong></p>
<p>The graph stores edges using the bot’s prefix length ([Bot] <code>prefix_bytes</code>). Paths from packets can be 1-, 2-, or 3-byte encoded (per sender); when we record edges we normalize to the bot’s prefix. If the bot uses <strong>prefix_bytes=1</strong> (2 hex chars) and the mesh often uses 2-byte paths, <strong>distinct links can be merged</strong>: e.g. 7E42→8611 and 7E99→86FF both become a single edge (7e, 86). That can overcount observations and make path resolution ambiguous when several repeaters share the same short prefix. <strong>Recommendation:</strong> set <code>prefix_bytes</code> to match the mesh (e.g. 2 if most traffic is 2-byte) so the graph keeps finer resolution and the mesh viewer shows one node per prefix instead of collapsing many repeaters into one.</p>
<p><strong><code>graph_based_validation</code></strong> (boolean)
- Enable graph-based path validation using observed mesh connections
- Default: <code>true</code></p>
<p><strong><code>min_edge_observations</code></strong> (integer)
- Minimum edge observations required for graph confidence
- Higher values = more conservative (requires more evidence)
- Default: <code>3</code></p>
<p><strong><code>graph_edge_expiration_days</code></strong> (days)
- Edges not observed for this many days are ignored
- Default: <code>7</code> days</p>
<p><strong><code>graph_use_bidirectional</code></strong> (boolean)
- Check for reverse edges for higher confidence
- Default: <code>true</code></p>
<p><strong><code>graph_use_hop_position</code></strong> (boolean)
- Validate candidates appear in expected positions based on observed routing patterns
- Default: <code>true</code></p>
<p><strong><code>graph_multi_hop_enabled</code></strong> (boolean)
- Use 2-hop or 3-hop paths to find intermediate nodes when direct edges don't exist
- Default: <code>true</code></p>
<p><strong><code>graph_multi_hop_max_hops</code></strong> (integer)
- Maximum hops for multi-hop path inference
- <code>2</code> = only 2-hop paths (A-&gt;B-&gt;C)
- <code>3</code> = also try 3-hop paths (A-&gt;B-&gt;C-&gt;D)
- Default: <code>2</code></p>
<p><strong><code>graph_prefer_stored_keys</code></strong> (boolean)
- Prioritize candidates whose public key matches stored keys in graph edges
- Stored keys indicate high confidence (+0.4 bonus)
- Default: <code>true</code></p>
<h2 id="graph-vs-geographic-selection">Graph vs Geographic Selection</h2>
<p><strong><code>graph_geographic_combined</code></strong> (boolean)
- Combine graph and geographic scores into weighted average
- Only combines when both methods select the same repeater
- Default: <code>false</code> (uses graph-first fallback)</p>
<p><strong><code>graph_geographic_weight</code></strong> (0.0 to 1.0)
- Weight for graph score when combining (only used if <code>graph_geographic_combined = true</code>)
- <code>0.7</code> = 70% graph, 30% geographic
- Default: <code>0.7</code></p>
<p><strong><code>graph_confidence_override_threshold</code></strong> (0.0 to 1.0)
- When graph confidence &gt;= this value, graph overrides geographic selection
- Lower values = geographic gets more consideration
- <code>1.0</code> = always prefer geographic when available
- <code>0.0</code> = always prefer graph
- Default: <code>0.7</code></p>
<h2 id="distance-penalties-intermediate-hops">Distance Penalties (Intermediate Hops)</h2>
<p><strong><code>graph_distance_penalty_enabled</code></strong> (boolean)
- Penalize graph scores for candidates creating long-distance hops
- Prevents selecting very distant repeaters even with strong graph evidence
- Default: <code>true</code></p>
<p><strong><code>graph_max_reasonable_hop_distance_km</code></strong> (kilometers)
- Maximum reasonable hop distance before applying penalty
- Typical LoRa transmission: &lt; 30km
- Long LoRa transmission: up to 200km
- Default: <code>30</code> (typical transmission range)</p>
<p><strong><code>graph_distance_penalty_strength</code></strong> (0.0 to 1.0)
- How much to penalize graph scores for long-distance hops
- <code>0.3</code> = 30% penalty for hops beyond max_reasonable_hop_distance
- Default: <code>0.3</code></p>
<h2 id="zero-hop-bonus">Zero-Hop Bonus</h2>
<p><strong><code>graph_zero_hop_bonus</code></strong> (0.0 to 1.0)
- Bonus for repeaters heard directly by the bot (zero-hop adverts)
- Strong evidence the repeater is close, even for intermediate hops
- Based on actual observed direct communication, not proximity guessing
- Default: <code>0.4</code></p>
<h2 id="final-hop-proximity-advanced">Final Hop Proximity (Advanced)</h2>
<p>The final hop (last repeater before bot) gets special proximity consideration. These settings are advanced and typically don't need adjustment.</p>
<p><strong><code>graph_final_hop_proximity_enabled</code></strong> (boolean)
- Enable bot location proximity consideration for final hop
- Default: <code>true</code></p>
<p><strong><code>graph_final_hop_proximity_weight</code></strong> (0.0 to 1.0)
- Base weight for proximity when combining with graph score for final hop
- <code>0.25</code> = 25% proximity, 75% graph score
- Default: <code>0.25</code></p>
<p><strong><code>graph_final_hop_max_distance</code></strong> (kilometers, 0 = no limit)
- Maximum distance for final hop proximity consideration
- Repeaters beyond this distance don't receive proximity bonus
- Default: <code>0</code> (no limit)</p>
<p><strong><code>graph_final_hop_proximity_normalization_km</code></strong> (kilometers)
- Distance normalization for final hop proximity scoring
- Lower values = more aggressive scoring
- Default: <code>200</code> (long LoRa range)</p>
<p><strong><code>graph_final_hop_very_close_threshold_km</code></strong> (kilometers)
- Repeaters within this distance get 2x proximity weight boost
- Default: <code>10</code> km</p>
<p><strong><code>graph_final_hop_close_threshold_km</code></strong> (kilometers)
- Repeaters within this distance get 1.5x proximity weight boost
- Default: <code>30</code> km (typical transmission range)</p>
<p><strong><code>graph_final_hop_max_proximity_weight</code></strong> (0.0 to 1.0)
- Maximum proximity weight for very close repeaters
- Default: <code>0.6</code></p>
<h2 id="path-validation-bonus">Path Validation Bonus</h2>
<p><strong><code>graph_path_validation_max_bonus</code></strong> (0.0 to 1.0)
- Maximum bonus for path validation matches
- Helps resolve prefix collisions by matching stored path patterns
- Default: <code>0.3</code></p>
<p><strong><code>graph_path_validation_obs_divisor</code></strong> (float)
- Divisor for observation count bonus
- Lower values = stronger bonus from observation count
- <code>50.0</code> means 50 observations = 0.15 bonus
- Default: <code>50.0</code></p>
<h2 id="graph-persistence-advanced">Graph Persistence (Advanced)</h2>
<p>These settings control how graph edges are stored in the database.</p>
<p><strong><code>graph_write_strategy</code></strong> (<code>immediate</code> | <code>batched</code> | <code>hybrid</code>)
- <code>immediate</code>: Write each edge update immediately (safer, higher I/O)
- <code>batched</code>: Accumulate updates, flush periodically (better performance)
- <code>hybrid</code>: Immediate for new edges, batched for increments (balanced)
- Default: <code>batched</code> (recommended for SD-card installations)</p>
<p><strong><code>graph_batch_interval_seconds</code></strong> (seconds)
- How often to flush pending edge updates (only for batched/hybrid)
- Default: <code>30</code></p>
<p><strong><code>graph_batch_max_pending</code></strong> (integer)
- Maximum pending updates before forcing a flush
- Default: <code>100</code></p>
<p><strong><code>graph_startup_load_days</code></strong> (days, 0 = load all)
- Load only edges seen in last N days on startup
- <code>0</code> = load all edges (use on servers with ample RAM)
- Default: <code>14</code> (set to <code>0</code> in <code>config.ini</code> to load all)</p>
<p><strong><code>graph_capture_enabled</code></strong> (boolean)
- When <code>false</code>, no new edge data is collected from packets and the background
batch writer thread is not started — reducing CPU and RAM overhead
- Edges already in the database are still used for path validation
- Set to <code>false</code> on devices that don't use the path command
- Default: <code>true</code></p>
<h2 id="raspberry-pi-low-power-profile">Raspberry Pi / Low-Power Profile</h2>
<p>For a Raspberry Pi 4 using an SD card, start with:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="k">[Path_Command]</span>
<a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="na">graph_based_validation</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">true</span>
<a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="na">graph_capture_enabled</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">true</span>
<a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="na">min_edge_observations</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">5</span>
<a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a><span class="na">graph_edge_expiration_days</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">7</span>
<a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a><span class="na">graph_startup_load_days</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">7</span>
<a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a><span class="na">graph_write_strategy</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">batched</span>
<a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a><span class="na">graph_batch_interval_seconds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">60</span>
<a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a><span class="na">graph_batch_max_pending</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">250</span>
<a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a><span class="na">graph_use_bidirectional</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">true</span>
<a id="__codelineno-4-11" name="__codelineno-4-11" href="#__codelineno-4-11"></a><span class="na">graph_use_hop_position</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">true</span>
<a id="__codelineno-4-12" name="__codelineno-4-12" href="#__codelineno-4-12"></a><span class="na">graph_multi_hop_enabled</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">true</span>
<a id="__codelineno-4-13" name="__codelineno-4-13" href="#__codelineno-4-13"></a><span class="na">graph_multi_hop_max_hops</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">2</span>
<a id="__codelineno-4-14" name="__codelineno-4-14" href="#__codelineno-4-14"></a><span class="na">graph_prefer_stored_keys</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">true</span>
<a id="__codelineno-4-15" name="__codelineno-4-15" href="#__codelineno-4-15"></a>
<a id="__codelineno-4-16" name="__codelineno-4-16" href="#__codelineno-4-16"></a><span class="k">[Data_Retention]</span>
<a id="__codelineno-4-17" name="__codelineno-4-17" href="#__codelineno-4-17"></a><span class="na">packet_stream_retention_days</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">3</span>
<a id="__codelineno-4-18" name="__codelineno-4-18" href="#__codelineno-4-18"></a><span class="na">observed_paths_retention_days</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">30</span>
<a id="__codelineno-4-19" name="__codelineno-4-19" href="#__codelineno-4-19"></a><span class="na">mesh_connections_retention_days</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">7</span>
<a id="__codelineno-4-20" name="__codelineno-4-20" href="#__codelineno-4-20"></a><span class="na">daily_stats_retention_days</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">90</span>
<a id="__codelineno-4-21" name="__codelineno-4-21" href="#__codelineno-4-21"></a><span class="na">purging_log_retention_days</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">90</span>
<a id="__codelineno-4-22" name="__codelineno-4-22" href="#__codelineno-4-22"></a><span class="na">retention_delete_batch_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">1000</span>
<a id="__codelineno-4-23" name="__codelineno-4-23" href="#__codelineno-4-23"></a><span class="na">retention_delete_pause_seconds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">0.1</span>
</code></pre></div>
<p><code>batched</code> persistence groups dirty edges into one transaction, reducing WAL
and SD-card transaction churn. A 60-second interval can lose at most roughly
one minute of not-yet-flushed graph updates after abrupt power loss. Use
<code>hybrid</code> if immediate persistence of newly discovered edges matters more than
write volume.</p>
<p><code>observed_paths_retention_days</code> is the main bound on multi-byte graph
derivation work because lifetime edge identity and counts are derived from all
retained path evidence before the selected browser timeframe is applied.
Thirty days is a practical Pi baseline; use 14 days for very busy meshes or 90
days when historical fidelity matters more than database size and query cost.</p>
<p>Retention deletes are committed in chunks and pause briefly between batches.
This prevents a large first cleanup from holding SQLite's only writer lock for
minutes. Reduce <code>retention_delete_batch_size</code> or increase
<code>retention_delete_pause_seconds</code> if maintenance still causes visible I/O-wait
spikes; doing so lengthens the cleanup.</p>
<p>For the web graph, use <strong>Multi-byte Only</strong>, a <strong>72-hour edge window</strong>, a
<strong>7-day node window</strong>, and a minimum observation threshold around <strong>5</strong>. These
settings reduce response and rendering work; retained-history length controls
the underlying multi-byte aggregation cost.</p>
<p>The installed systemd service allows up to 1GB of memory and 200% CPU (two
cores). These are upper limits rather than reserved resources. A USB SSD is
still the most effective way to reduce SD-card wear on high-volume nodes.</p>
<p>The web viewer caches the lifetime multi-byte edge aggregate for 30 seconds and
coalesces live mesh events into one refresh per 30 seconds. On unusually large
meshes, increase <code>[Web_Viewer] mesh_graph_cache_seconds</code> to 60. Keep
<code>[Logging] log_level = INFO</code> during normal operation; <code>DEBUG</code> emits multiple
records per observed edge and can create substantial SD-card write traffic.</p>
<h2 id="preset-configurations">Preset Configurations</h2>
<h3 id="balanced-default"><code>balanced</code> (Default)</h3>
<ul>
<li>Uses both graph evidence and geographic proximity</li>
<li>Graph confidence threshold: 0.7</li>
<li>Distance penalties: enabled (30km threshold)</li>
<li>Final hop proximity: enabled</li>
<li>Good for: Most networks with mixed connectivity</li>
</ul>
<h3 id="geographic"><code>geographic</code></h3>
<ul>
<li>Prioritizes geographic proximity</li>
<li>Graph confidence threshold: 0.5 (lower, gives geographic more weight)</li>
<li>Distance penalties: enabled (30km threshold, stronger penalty)</li>
<li>Final hop proximity: enabled with higher weight</li>
<li>Good for: Local networks where repeaters are close together</li>
</ul>
<h3 id="graph"><code>graph</code></h3>
<ul>
<li>Prioritizes graph evidence</li>
<li>Graph confidence threshold: 0.9 (higher, graph wins more often)</li>
<li>Distance penalties: enabled (50km threshold, weaker penalty)</li>
<li>Final hop proximity: enabled with lower weight</li>
<li>Good for: Well-connected networks with strong graph evidence</li>
</ul>
<h2 id="geographic-scoring-toggle">Geographic scoring toggle</h2>
<p><strong><code>geographic_scoring_enabled</code></strong> in <code>[Path_Command]</code> (default <code>true</code>):</p>
<ul>
<li>When <strong><code>true</code></strong>, geographic proximity scoring is used during path decode (subject to other preset and graph settings).</li>
<li>When <strong><code>false</code></strong>, geographic proximity guessing is disabled entirely for path decode.</li>
</ul>
<p>This is a <strong>configuration</strong> option only — there is no chat subcommand to toggle it at runtime. Restart the bot (or reload config if supported) after changing it.</p>
<p>See also the <a href="../command-reference/#path-or-decode-or-route"><code>path</code> command</a> in the command reference.</p>
<h2 id="typical-lora-transmission-ranges">Typical LoRa Transmission Ranges</h2>
<ul>
<li><strong>Typical transmission</strong>: &lt; 30km</li>
<li><strong>Long transmission</strong>: up to 200km</li>
<li><strong>Very close</strong>: &lt; 10km (often direct line-of-sight)</li>
</ul>
<p>These ranges inform the default distance thresholds used throughout the path selection algorithm.</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["navigation.instant", "navigation.tracking", "navigation.tabs", "navigation.sections", "toc.integrate", "content.code.copy"], "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.d7400e89.min.js"></script>
</body>
</html>