mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-10-30 23:51:57 +01:00
Firmware v1.17 changed no protocol constants and left FIRMWARE_VER_CODE at 13, so the companion protocol cannot tell a v1.16 node from a v1.17 one. Capability is instead read from the CLI reply text, which self-describes and works for any version and board without an extra round-trip: `??: <field>` / `unknown config: <field>` → firmware has no such setting `Error: unsupported` → hardware cannot do it `> <value>` → supported Both of the first two now yield an 'unsupported' status rather than a failure, rendered as a muted badge with the control locked and excluded from Apply. Without this, every field added below would read as a red error on each repeater that predates it. Applying to an unsupported field deliberately asserts nothing about the stored value: v1.17 persists radio.rxgain before it learns the radio cannot apply it, so the old value may or may not still hold. The baseline is dropped instead of being reasserted, and only Refresh reveals the truth. Also guards a pre-existing trap: up to v1.16 the `radio.rxgain` getter was compiled out on non-SX126x radios, and `get radio.rxgain` fell through to the `radio` branch (its memcmp has no trailing space), answering with the radio parameters. That parsed as a valid reply and silently rendered the switch as off. An on/off field that answers neither on nor off is now treated as absent. New fields: cad (v1.17+), flood.max.unscoped and flood.max.advert (both present since v1.16, previously just undocumented upstream). New action: poweroff (v1.17+). Unlike reboot it cannot be undone over the mesh, so it takes a typed repeater name rather than a confirm(), checked server-side as well as in the UI. Telemetry: the MCU temperature v1.17 appends to channel 1 is labelled as silicon rather than as an environmental reading. Absent stays absent — boards without a usable sensor emit nothing, and a zero would be a lie. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
48 lines
1.7 KiB
Python
48 lines
1.7 KiB
Python
"""
|
|
Unit tests for classifying repeater CLI replies in the settings batch.
|
|
|
|
The firmware's reply text is the only capability signal available for a remote
|
|
repeater: FIRMWARE_VER_CODE stayed at 13 across v1.16 → v1.17, so it cannot
|
|
tell us whether a node knows a setting added in v1.17 (`cad`).
|
|
|
|
Run: python -m pytest tests/test_repeater_cli_replies.py -v
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from app.routes.api import _reply_is_unsupported
|
|
|
|
|
|
# ================================================================
|
|
# Replies that mean "this node does not have that setting"
|
|
# ================================================================
|
|
|
|
@pytest.mark.parametrize('reply', [
|
|
'??: cad', # unknown `get` field (any version)
|
|
'unknown config: cad on', # unknown `set` field
|
|
'Error: unsupported', # v1.17 hardware refusal
|
|
'Error: unsupported by this board', # v1.16 wording, still recognised
|
|
' ??: radio.fem.rxgain ', # surrounding whitespace
|
|
'ERROR: UNSUPPORTED', # case-insensitive
|
|
])
|
|
def test_unsupported_replies(reply):
|
|
assert _reply_is_unsupported(reply) is True
|
|
|
|
|
|
# ================================================================
|
|
# Everything else — a value, a real failure, or nothing at all
|
|
# ================================================================
|
|
|
|
@pytest.mark.parametrize('reply', [
|
|
'> on',
|
|
'> 869.525,250.00,11,5',
|
|
'OK',
|
|
'OK - repeat is now ON',
|
|
'Error, max 64', # a genuine rejection, not a capability gap
|
|
'Error: failed to apply LoRa FEM RX gain',
|
|
'',
|
|
None,
|
|
])
|
|
def test_supported_or_failed_replies(reply):
|
|
assert _reply_is_unsupported(reply) is False
|