mirror of
https://github.com/pyMC-dev/pyMC_Repeater.git
synced 2026-08-07 01:13:11 +02:00
docs(engine): state TX delay factor semantics at startup
The TX delay factors changed from absolute seconds to firmware-matching airtime multipliers (random delay in [0, 5 * airtime * factor], per MeshCore getRetransmitDelay), but deployed configs tuned under the old seconds interpretation get no signal on upgrade. Log the interpretation and both factors at startup, and fix the stale wording in config.yaml.example and the web API docstring. Defaults are unchanged (flood 1.0, direct 0.5; firmware ships 0.5/0.3).
This commit is contained in:
+4
-2
@@ -483,10 +483,12 @@ sx1262:
|
||||
is_waveshare: false
|
||||
|
||||
delays:
|
||||
# TX delay factor for flood mode (multiplier)
|
||||
# Flood TX delay: airtime multiplier, NOT seconds. The actual pre-transmit
|
||||
# delay is a random value in [0, 5 * packet_airtime * factor] seconds.
|
||||
tx_delay_factor: 1.0
|
||||
|
||||
# TX delay factor for direct mode (faster)
|
||||
# Direct TX delay: same random 0-5*airtime*factor window, usually lower so
|
||||
# directed traffic clears faster.
|
||||
direct_tx_delay_factor: 0.5
|
||||
|
||||
duty_cycle:
|
||||
|
||||
@@ -77,6 +77,14 @@ class RepeaterHandler(BaseHandler):
|
||||
self.max_duplicates_per_packet = 20
|
||||
self.tx_delay_factor = config.get("delays", {}).get("tx_delay_factor", 1.0)
|
||||
self.direct_tx_delay_factor = config.get("delays", {}).get("direct_tx_delay_factor", 0.5)
|
||||
# These are airtime multipliers, not seconds: TX delay is a random value in
|
||||
# [0, 5 * airtime * factor] (matching MeshCore getRetransmitDelay). Flood and
|
||||
# direct share the formula and differ only in the factor.
|
||||
logger.info(
|
||||
"TX delay factors (airtime multipliers, not seconds): "
|
||||
f"flood random 0-5*airtime*F (F={self.tx_delay_factor}), "
|
||||
f"direct random 0-5*airtime*F (F={self.direct_tx_delay_factor})"
|
||||
)
|
||||
self.use_score_for_tx = config.get("repeater", {}).get("use_score_for_tx", False)
|
||||
self.score_threshold = config.get("repeater", {}).get("score_threshold", 0.3)
|
||||
self.max_flood_hops = config.get("repeater", {}).get("max_flood_hops", 64)
|
||||
|
||||
@@ -3868,8 +3868,8 @@ class APIEndpoints:
|
||||
"bandwidth": 62500, # Bandwidth in Hz (valid: 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250, 500 kHz)
|
||||
"spreading_factor": 8, # Spreading factor (5-12)
|
||||
"coding_rate": 8, # Coding rate (5-8 for 4/5 to 4/8)
|
||||
"tx_delay_factor": 1.0, # TX delay factor (0.0-5.0)
|
||||
"direct_tx_delay_factor": 0.5, # Direct TX delay (0.0-5.0)
|
||||
"tx_delay_factor": 1.0, # Flood TX delay airtime multiplier (0.0-5.0)
|
||||
"direct_tx_delay_factor": 0.5, # Direct TX delay airtime multiplier (0.0-5.0)
|
||||
"rx_delay_base": 0.0, # RX delay base (>= 0)
|
||||
"node_name": "MyNode", # Node name
|
||||
"owner_info": "Owner text", # Owner info text
|
||||
|
||||
@@ -8,6 +8,7 @@ airtime duty-cycle, TX mode (forward/monitor/no_tx), and config reloading.
|
||||
|
||||
import asyncio
|
||||
import base64
|
||||
import logging
|
||||
import time
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
@@ -849,6 +850,14 @@ class TestTxDelay:
|
||||
delay = handler._calculate_tx_delay(pkt, snr=0.0)
|
||||
assert delay == 0.0
|
||||
|
||||
def test_startup_log_states_delay_factor_semantics(self, caplog):
|
||||
with caplog.at_level(logging.INFO, logger="RepeaterHandler"):
|
||||
_make_handler_with_hash(bytes([LOCAL_HASH]))
|
||||
assert any(
|
||||
"TX delay factors" in record.message and "airtime multipliers" in record.message
|
||||
for record in caplog.records
|
||||
)
|
||||
|
||||
def test_transport_direct_uses_random_window(self, handler):
|
||||
handler.direct_tx_delay_factor = 0.77
|
||||
pkt = _make_transport_direct_packet()
|
||||
|
||||
Reference in New Issue
Block a user