mirror of
https://github.com/pyMC-dev/pyMC_Repeater.git
synced 2026-07-03 16:32:26 +02:00
Merge pull request #287 from agessaman/kiss/tuning-options
This commit is contained in:
@@ -54,6 +54,7 @@ htmlcov/
|
||||
.env
|
||||
config.yaml
|
||||
config.yaml.backup
|
||||
policy.yaml
|
||||
identity.json
|
||||
|
||||
# Data
|
||||
|
||||
@@ -383,6 +383,16 @@ radio:
|
||||
# kiss:
|
||||
# port: "/dev/ttyUSB0"
|
||||
# baud_rate: 9600
|
||||
# # Optional KISS key-up / CSMA tuning, forwarded to the modem firmware.
|
||||
# # Omit to keep the wrapper/firmware defaults. For a host-managed repeater the
|
||||
# # engine already staggers retransmits, so the firmware's p-persistent CSMA
|
||||
# # backoff is redundant — kiss_persistence: 255 transmits as soon as the channel
|
||||
# # is clear (carrier-sense still prevents talking over a packet already on air).
|
||||
# kiss_persistence: 255 # 0-255; p(tx when clear) = (value+1)/256. Firmware default 63.
|
||||
# kiss_slottime_ms: 20 # CSMA backoff slot; unused at persistence 255. Firmware default 100.
|
||||
# tx_delay_ms: 50 # key-up delay; LoRa needs ~none. Firmware default 500.
|
||||
# # kiss_txtail_ms: 0 # tail after TX (rarely needed)
|
||||
# # kiss_full_duplex: false # disable carrier-sense/CSMA entirely (not recommended)
|
||||
|
||||
# pymc_usb firmware modem over Wi-Fi/TCP (when radio_type: pymc_tcp).
|
||||
# Requires pyMC_core with the TCPLoRaRadio driver
|
||||
|
||||
@@ -543,6 +543,18 @@ def get_radio_for_board(board_config: dict):
|
||||
"tx_power": int(radio_cfg.get("tx_power", 14)),
|
||||
"preamble_length": int(radio_cfg.get("preamble_length", 32)),
|
||||
}
|
||||
|
||||
# Optional KISS key-up / CSMA tuning, forwarded to the modem firmware (via
|
||||
# SetHardware) only when present so the wrapper keeps its own defaults otherwise.
|
||||
# For a host-managed repeater the engine already staggers retransmits, so the
|
||||
# firmware's p-persistent CSMA backoff is usually redundant; set
|
||||
# kiss_persistence: 255 to transmit as soon as the channel is clear.
|
||||
for _key in ("tx_delay_ms", "kiss_persistence", "kiss_slottime_ms", "kiss_txtail_ms"):
|
||||
if kiss_config.get(_key) is not None:
|
||||
radio_config[_key] = int(kiss_config[_key])
|
||||
if kiss_config.get("kiss_full_duplex") is not None:
|
||||
radio_config["kiss_full_duplex"] = bool(kiss_config["kiss_full_duplex"])
|
||||
|
||||
radio = KissModemWrapper(
|
||||
port=port,
|
||||
baudrate=baudrate,
|
||||
|
||||
@@ -188,3 +188,64 @@ def test_get_radio_for_board_pymc_usb_requires_port(monkeypatch):
|
||||
|
||||
with pytest.raises(ValueError, match="Missing 'port'"):
|
||||
get_radio_for_board(board_config)
|
||||
|
||||
|
||||
# ─── kiss branch: optional CSMA / key-up tuning forwarding ────────────
|
||||
|
||||
|
||||
def _kiss_capture_radio_config(monkeypatch):
|
||||
"""Patch KissModemWrapper to capture the radio_config it is built with."""
|
||||
pytest.importorskip("pymc_core.hardware.kiss_modem_wrapper")
|
||||
captured = {}
|
||||
|
||||
class _DummyKissWrapper(_DummyRadio):
|
||||
def __init__(self, **kwargs):
|
||||
captured["kwargs"] = kwargs
|
||||
|
||||
monkeypatch.setattr(
|
||||
"pymc_core.hardware.kiss_modem_wrapper.KissModemWrapper",
|
||||
_DummyKissWrapper,
|
||||
)
|
||||
return captured
|
||||
|
||||
|
||||
def test_get_radio_for_board_kiss_forwards_csma_tuning(monkeypatch):
|
||||
captured = _kiss_capture_radio_config(monkeypatch)
|
||||
|
||||
board_config = {
|
||||
"radio_type": "kiss",
|
||||
"kiss": {
|
||||
"port": "/dev/ttyACM0",
|
||||
"baud_rate": 115200,
|
||||
"kiss_persistence": 255,
|
||||
"kiss_slottime_ms": 20,
|
||||
"tx_delay_ms": 50,
|
||||
"kiss_full_duplex": True,
|
||||
},
|
||||
"radio": _pymc_radio_cfg(),
|
||||
}
|
||||
|
||||
get_radio_for_board(board_config)
|
||||
|
||||
rc = captured["kwargs"]["radio_config"]
|
||||
assert rc["kiss_persistence"] == 255
|
||||
assert rc["kiss_slottime_ms"] == 20
|
||||
assert rc["tx_delay_ms"] == 50
|
||||
assert rc["kiss_full_duplex"] is True
|
||||
|
||||
|
||||
def test_get_radio_for_board_kiss_omits_unset_tuning(monkeypatch):
|
||||
captured = _kiss_capture_radio_config(monkeypatch)
|
||||
|
||||
board_config = {
|
||||
"radio_type": "kiss",
|
||||
"kiss": {"port": "/dev/ttyACM0", "baud_rate": 115200},
|
||||
"radio": _pymc_radio_cfg(),
|
||||
}
|
||||
|
||||
get_radio_for_board(board_config)
|
||||
|
||||
rc = captured["kwargs"]["radio_config"]
|
||||
# Unset keys must not be forwarded, so the wrapper keeps its own defaults.
|
||||
for key in ("kiss_persistence", "kiss_slottime_ms", "tx_delay_ms", "kiss_full_duplex"):
|
||||
assert key not in rc
|
||||
|
||||
Reference in New Issue
Block a user