Files
pyMC_Repeater/config.yaml.example
T

481 lines
17 KiB
Plaintext
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.
# Default Repeater Configuration
# radio_type: sx1262 | kiss (use kiss for serial KISS TNC modem)
radio_type: sx1262
repeater:
# Node name for logging and identification
node_name: "mesh-repeater-01"
# TX mode: forward | monitor | no_tx (default: forward)
# forward = repeat on; monitor = no repeat but companions/tenants can send; no_tx = all TX off
# mode: forward
# Geographic location (optional)
# Latitude in decimal degrees (-90 to 90)
latitude: 0.0
# Longitude in decimal degrees (-180 to 180)
longitude: 0.0
# Path to identity file (public/private key)
# If not specified, a new identity will be generated
identity_file: null
# Identity key (alternative to identity_file)
# Store the private key directly in config as binary (set by convert_firmware_key.sh)
# If both identity_file and identity_key are set, identity_key takes precedence
# identity_key: null
# Owner information (shown to clients requesting owner info)
owner_info: ""
# Duplicate packet cache TTL in seconds
cache_ttl: 3600
# Maximum number of hops a flood packet may have already traversed before
# this repeater forwards it.
max_flood_hops: 64
# Score-based transmission filtering
# Enable quality-based packet filtering and adaptive delays
use_score_for_tx: false
# Score threshold for quality monitoring (future use)
# Currently reserved for potential future features like dashboard alerts,
# proactive statistics collection, or advanced filtering strategies.
# Changing this value has no effect on current packet processing.
score_threshold: 0.3
# Automatic advertisement interval in hours
# The repeater will send an advertisement packet at this interval
# Set to 0 to disable automatic adverts (manual only via web interface)
# Range: 0 (disabled) to 24+ hours
# Recommended: 10 hours for typical deployments
send_advert_interval_hours: 10
# Respond to discovery requests from other nodes
# When enabled, the repeater will automatically respond to discovery packets
# with its node information (node type 2 - repeater)
allow_discovery: true
# Incoming advert rate limiter (per advert public key)
# Uses a token bucket to smooth bursts.
advert_rate_limit:
# Master switch for token bucket limiting
enabled: false
# Max burst size allowed immediately per pubkey
# Keep this small for long advert intervals.
bucket_capacity: 2
# Number of tokens added each refill interval
refill_tokens: 1
# Refill interval in seconds (10 hours)
refill_interval_seconds: 36000
# Optional hard minimum spacing between adverts from same pubkey
# Set 0 to disable (recommended - mesh retransmissions are normal in active networks)
min_interval_seconds: 0
# Penalty box for repeat advert limit violations (per pubkey)
advert_penalty_box:
# Master switch for escalating cooldowns
enabled: false
# Number of violations within decay window before cooldown starts
violation_threshold: 2
# Reset violation count if pubkey stays quiet for this long
violation_decay_seconds: 43200
# First penalty duration in seconds
base_penalty_seconds: 21600
# Exponential growth factor for repeated violations
penalty_multiplier: 2.0
# Maximum penalty duration cap
max_penalty_seconds: 86400
# Adaptive rate limiting based on mesh activity
# Rate limits scale with mesh busyness: quiet mesh = lenient, busy mesh = strict
advert_adaptive:
# Master switch for adaptive scaling
enabled: false
# EWMA smoothing factor (0.0-1.0, higher = faster response)
ewma_alpha: 0.1
# Seconds without metrics change before tier change takes effect (hysteresis)
hysteresis_seconds: 300
# Tier thresholds based on adverts per minute EWMA
thresholds:
quiet_max: 0.05 # Below this = QUIET tier (no limiting)
normal_max: 0.20 # Below this = NORMAL tier (1x limits)
busy_max: 0.50 # Below this = BUSY tier (0.5x capacity)
# Above busy_max = CONGESTED tier (0.25x capacity)
# Security settings for login/authentication (shared across all identities)
security:
# Maximum number of authenticated clients (across all identities)
max_clients: 1
# Admin password for full access
admin_password: "admin123"
# Guest password for limited access
guest_password: "guest123"
# Allow read-only access for clients without password/not in ACL
allow_read_only: false
# JWT secret key for signing tokens (auto-generated if not provided)
# Generate with: python -c "import secrets; print(secrets.token_hex(32))"
jwt_secret: ""
# JWT token expiry time in minutes (default: 60 minutes / 1 hour)
# Controls how long users stay logged in before needing to re-authenticate
jwt_expiry_minutes: 60
# Local GPS receiver. When enabled, the daemon reads NMEA sentences from the
# configured source and exposes parsed data at /api/gps.
gps:
enabled: false
# ---------------------------------------------------------------------------
# Source
# ---------------------------------------------------------------------------
# Source type:
# serial = read directly from an attached GPS module
# file = read NMEA lines from source_path (useful for gpsd/sidecar bridges)
source: serial
# Serial source settings (used when source: serial)
device: "/dev/serial0"
baud_rate: 9600
read_timeout_seconds: 1.0
reconnect_interval_seconds: 5.0
# File source settings (used when source: file)
# The file may contain raw NMEA lines or JSON with a "sentences" list /
# "last_sentence" field.
source_path: "/var/lib/pymc_repeater/gps_nmea.txt"
poll_interval_seconds: 2.0
# ---------------------------------------------------------------------------
# Location behaviour
# Three independent controls — read the comments carefully, they do
# different things:
#
# api_fallback_to_config_location — what the API *displays* before a fix
# advertise_gps_location — what the mesh *advertises* in adverts
# persist_gps_fix_to_config — whether the fix is *written* to config
# ---------------------------------------------------------------------------
# API display: while GPS has no valid fix, show repeater.latitude/longitude
# from config in the /api/gps effective position instead of null/0,0.
# The default 0,0 repeater location is treated as unset (no fallback shown).
# Has no effect on mesh adverts or config persistence.
api_fallback_to_config_location: true
# Mesh adverts: use GPS coordinates in repeater-originated location fields
# (flood adverts, etc.). When false, repeater.latitude/longitude from config
# are always used for outgoing mesh packets.
advertise_gps_location: false
# Config persistence: write a valid GPS fix back into repeater.latitude/
# repeater.longitude so adverts location details follow the
# receiver across restarts. Updates are throttled to avoid rewriting config
# on every NMEA sentence. location_precision_digits is applied before saving.
persist_gps_fix_to_config: false
persist_gps_fix_interval_seconds: 600.0
# Optional privacy/obfuscation: round coordinates to this many decimal places
# before they are used for advertising or persisted to config (08).
# Leave null for full precision. Affects both advertise_gps_location and
# persist_gps_fix_to_config.
location_precision_digits: null
# ---------------------------------------------------------------------------
# Diagnostics
# ---------------------------------------------------------------------------
stale_after_seconds: 10.0
retain_sentences: 25
validate_checksum: true
require_checksum: false
# ---------------------------------------------------------------------------
# Time sync
# ---------------------------------------------------------------------------
# Automatically set the Linux system clock from GPS UTC time once the
# receiver has a valid non-stale fix. The systemd service grants
# CAP_SYS_TIME for this.
time_sync_enabled: true
time_sync_interval_seconds: 3600.0
time_sync_min_offset_seconds: 1.0
time_sync_min_valid_year: 2020
# Mesh Network Configuration
mesh:
# Unscoped flood policy - controls whether the repeater allows or denies unscoped flooding
# true = allow unscoped flooding, false = deny flooding globally
unscoped_flood_allow: true
# Path hash mode for flood packets (0-hop): per-hop hash size in path encoding
# 0 = 1-byte hashes (legacy), 1 = 2-byte, 2 = 3-byte. Must match mesh convention.
# Affects originated adverts and any other flood packets sent by the repeater.
path_hash_mode: 0
# Flood loop detection mode
# off = disabled, minimal = allow up to 3 self-hashes, moderate = allow up to 1, strict = allow 0
loop_detect: minimal
# Multiple Identity Configuration (Optional)
# Define additional identities for the repeater to manage
# Each identity operates independently with its own key pair and configuration
identities:
# Room Server Identities
# Each room server acts as a separate logical node on the mesh
room_servers:
# Example room server configuration (commented out by default)
# - name: "TestBBS"
# identity_key: "your_room_identity_key_hex_here"
# type: "room_server"
#
# # Room-specific settings
# settings:
# node_name: "Test BBS Room"
# latitude: 0.0
# longitude: 0.0
# admin_password: "room_admin_password"
# guest_password: "room_guest_password"
# Add more room servers as needed
# - name: "SocialHub"
# identity_key: "another_identity_key_hex_here"
# type: "room_server"
# settings:
# node_name: "Social Hub"
# latitude: 0.0
# longitude: 0.0
# admin_password: "social_admin_123"
# guest_password: "social_guest_123"
# Companion Identities
# Each companion exposes the MeshCore frame protocol over TCP for standard clients.
# One TCP client per companion at a time. Clients connect to repeater-ip:tcp_port.
companions:
# - name: "RepeaterCompanion"
# identity_key: "your_companion_identity_key_hex_here"
# settings:
# node_name: "RepeaterCompanion"
# tcp_port: 5000
# bind_address: "0.0.0.0"
# tcp_timeout: 120 # seconds; default 120 when omitted; 0 = disable (no timeout)
# - name: "BotCompanion"
# identity_key: "another_companion_identity_key_hex"
# settings:
# node_name: "meshcore-bot"
# tcp_port: 5001
# tcp_timeout: 120 # seconds; default 120 when omitted; 0 = disable (no timeout)
# Radio hardware type
# Supported:
# - sx1262 (Linux spidev + system GPIO)
# - sx1262_ch341 (CH341 USB-to-SPI + CH341 GPIO 0-7)
radio_type: sx1262
# CH341 USB-to-SPI adapter settings (only used when radio_type: sx1262_ch341)
# NOTE: VID/PID are integers. Hex is also accepted in YAML, e.g. 0x1A86.
ch341:
vid: 6790 # 0x1A86
pid: 21778 # 0x5512
radio:
# Frequency in Hz (869.618 MHz for EU)
frequency: 869618000
# TX power in dBm
tx_power: 14
# Bandwidth in Hz (62500 = 62.5 kHz)
bandwidth: 62500
# LoRa spreading factor (7-12)
spreading_factor: 8
# Coding rate (5-8)
coding_rate: 8
# Preamble length in symbols
preamble_length: 17
# Sync word (LoRa network ID)
sync_word: 13380
# Use implicit header mode
implicit_header: false
# KISS modem (when radio_type: kiss). Requires pyMC_core with KISS support.
# kiss:
# port: "/dev/ttyUSB0"
# baud_rate: 9600
# SX1262 Hardware Configuration
# NOTE:
# - When radio_type: sx1262, these pins are BCM GPIO numbers.
# - When radio_type: sx1262_ch341, these pins are CH341 GPIO numbers (0-7).
sx1262:
# SPI bus and chip select
# NOTE: For CH341 these are not used but are still required parameters.
bus_id: 0
cs_id: 0
# GPIO pins
cs_pin: 21
reset_pin: 18
busy_pin: 20
irq_pin: 16
# TX/RX enable pins (-1 to disable)
txen_pin: -1
rxen_pin: -1
# Optional radio power-enable pin(s) driven HIGH during init
en_pin: -1
# en_pins: [26, 23]
# LED pins for TX/RX indication (-1 to disable)
txled_pin: -1
rxled_pin: -1
use_dio3_tcxo: false
dio3_tcxo_voltage: 1.8
use_dio2_rf: false
# Waveshare hardware flag
is_waveshare: false
delays:
# TX delay factor for flood mode (multiplier)
tx_delay_factor: 1.0
# TX delay factor for direct mode (faster)
direct_tx_delay_factor: 0.5
duty_cycle:
# Enable/disable duty cycle enforcement
# Set to false to disable airtime limits
enforcement_enabled: false
# Maximum airtime per minute in milliseconds
max_airtime_per_minute: 3600
# Storage Configuration
storage:
# Directory for persistent storage files (SQLite, RRD).
# Use a writable path for local/dev (e.g. "./var/pymc_repeater" or "~/var/pymc_repeater").
storage_dir: "/var/lib/pymc_repeater"
# Data retention settings
retention:
# Clean up SQLite records older than this many days
sqlite_cleanup_days: 31
# RRD archives are managed automatically:
# - 1 minute resolution for 1 week
# - 5 minute resolution for 1 month
# - 1 hour resolution for 1 year
mqtt_brokers:
iata_code: "Test" # e.g., "SFO", "LHR", "Test"
status_interval: 300 # How often a status message is sent (in seconds)
owner: ""
email: ""
brokers: []
# Below is the broker object schema:
# enabled: true|false # Enable this specific mqtt broker
# name: "" # Internal name for this broker
# host: "" # hostname or ip of mqtt endpoints
# port: # Typically 443 for websocket endpoints or 1883 for tcp
# transport: "tcp" or "websockets"
# audience: "" # For JWT auth'd endpoints, this is usually the host unless always stated by endpoint owners
# use_jwt_auth: true|false # Does this endpoint require JWT auth. Mutually Exclusive with Username & Password fields
# username: "" # Username for basic auth. If empty or missing, uses anonymous access
# password: "" # Password for basic auth. Required if username is set
# format: letsmesh|mqtt
# retain_status: true|false # Sets MQTT "retain" on status messages so they remain on the broker when disconnected. Also enforces a QOS of 1 (guaranteed delivery)
# tls:
# enabled: true|false # Enable TLS. If the endpoint's certificate is self-signed, the Root CA should be added to the OS's certificate store.
# insecure: true|false # Validate TLS certificates
# Block specific packet types from being published to the MQTT endpoint
# If not specified or empty list, all types are published
# Available types: REQ, RESPONSE, TXT_MSG, ACK, ADVERT, GRP_TXT,
# GRP_DATA, ANON_REQ, PATH, TRACE, RAW_CUSTOM
# disallowed_packet_types: []
# - REQ # Don't publish requests
# - RESPONSE # Don't publish responses
# - TXT_MSG # Don't publish text messages
# - ACK # Don't publish acknowledgments
# - ADVERT # Don't publish advertisements
# - GRP_TXT # Don't publish group text messages
# - GRP_DATA # Don't publish group data
# - ANON_REQ # Don't publish anonymous requests
# - PATH # Don't publish path packets
# - TRACE # Don't publish trace packets
# - RAW_CUSTOM # Don't publish custom raw packets
# Example of using the US and EU LetsMesh endpoints
# brokers:
# - name: US West (LetsMesh v1)
# host: mqtt-us-v1.letsmesh.net
# port: 443
# audience: mqtt-us-v1.letsmesh.net
# use_jwt_auth: true
# enabled: true
# - name: Europe (LetsMesh v1)
# host: mqtt-eu-v1.letsmesh.net
# port: 443
# audience: mqtt-eu-v1.letsmesh.net
# use_jwt_auth: true
# enabled: true
# pyMC_Glass control-plane integration (optional)
glass:
# Enable repeater -> pyMC_Glass /inform loop
enabled: false
# Base URL of Glass backend
# Example local dev: "http://localhost:8080"
# Example production: "https://glass.example.com"
base_url: "http://localhost:8080"
# Inform interval in seconds (used as initial/default interval;
# backend may override via noop.interval response)
inform_interval_seconds: 30
# HTTP timeout per inform request
request_timeout_seconds: 10
# Verify TLS certificates when using HTTPS
verify_tls: true
# Optional bearer token for future authenticated inform endpoints
api_token: ""
# Where cert_renewal payloads are written
cert_store_dir: "/etc/pymc_repeater/glass"
logging:
# Log level: DEBUG, INFO, WARNING, ERROR
level: INFO
# Log format
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
# Web interface configuration
web:
# Enable Cross-Origin Resource Sharing (CORS) headers
# Allows web frontends from different origins to access the API
cors_enabled: false
# Custom path to web frontend files (optional)
# If not specified, uses the default built-in path
# Example: /opt/custom-web-ui or /home/user/my-frontend
# web_path: null