Prefer reported primary channel names (#363)

This commit is contained in:
l5y
2025-10-16 20:35:24 +02:00
committed by GitHub
parent 81335cbf7b
commit 4bfc0e25cb
2 changed files with 57 additions and 15 deletions
+26 -11
View File
@@ -78,17 +78,36 @@ def _iter_channel_objects(channels_obj: Any) -> Iterator[Any]:
def _primary_channel_name() -> str | None:
"""Return the name to use for the primary channel when available."""
"""Return the fallback name to use for the primary channel when needed."""
preset = getattr(config, "MODEM_PRESET", None)
if isinstance(preset, str) and preset.strip():
return preset
return preset.strip()
env_name = os.environ.get("CHANNEL", "").strip()
if env_name:
return env_name
return None
def _extract_channel_name(settings_obj: Any) -> str | None:
"""Normalise the configured channel name extracted from ``settings_obj``."""
if settings_obj is None:
return None
if isinstance(settings_obj, dict):
candidate = settings_obj.get("name")
else:
candidate = getattr(settings_obj, "name", None)
if isinstance(candidate, str):
candidate = candidate.strip()
if candidate:
return candidate
return None
def _normalize_role(role: Any) -> int | None:
"""Convert a channel role descriptor into an integer value."""
@@ -122,27 +141,23 @@ def _channel_tuple(channel_obj: Any) -> tuple[int, str] | None:
role_value = _normalize_role(getattr(channel_obj, "role", None))
if role_value == _ROLE_PRIMARY:
channel_index = 0
channel_name = _primary_channel_name()
channel_name = _extract_channel_name(getattr(channel_obj, "settings", None))
if channel_name is None:
channel_name = _primary_channel_name()
elif role_value == _ROLE_SECONDARY:
raw_index = getattr(channel_obj, "index", None)
try:
channel_index = int(raw_index)
except Exception:
channel_index = None
settings = getattr(channel_obj, "settings", None)
channel_name = getattr(settings, "name", None) if settings else None
channel_name = _extract_channel_name(getattr(channel_obj, "settings", None))
else:
return None
if not isinstance(channel_index, int):
return None
if isinstance(channel_name, str):
channel_name = channel_name.strip()
else:
channel_name = None
if not channel_name:
if not isinstance(channel_name, str) or not channel_name:
return None
return channel_index, channel_name
+31 -4
View File
@@ -407,11 +407,14 @@ def test_capture_channels_from_interface_records_metadata(mesh_module, capsys):
mesh = mesh_module
mesh.config.MODEM_PRESET = "MediumFast"
mesh.channels._reset_channel_cache()
class DummyInterface:
def __init__(self) -> None:
self.wait_calls = 0
primary = SimpleNamespace(role=1, settings=SimpleNamespace())
primary = SimpleNamespace(
role=1, settings=SimpleNamespace(name=" radioamator ")
)
secondary = SimpleNamespace(
role="SECONDARY",
index="7",
@@ -428,19 +431,20 @@ def test_capture_channels_from_interface_records_metadata(mesh_module, capsys):
log_output = capsys.readouterr().out
assert iface.wait_calls == 1
assert mesh.channels.channel_mappings() == ((0, "MediumFast"), (7, "TestChannel"))
assert mesh.channels.channel_mappings() == ((0, "radioamator"), (7, "TestChannel"))
assert mesh.channels.channel_name(7) == "TestChannel"
assert "Captured channel metadata" in log_output
assert "channels=((0, 'MediumFast'), (7, 'TestChannel'))" in log_output
assert "channels=((0, 'radioamator'), (7, 'TestChannel'))" in log_output
mesh.channels.capture_from_interface(SimpleNamespace(localNode=None))
assert mesh.channels.channel_mappings() == ((0, "MediumFast"), (7, "TestChannel"))
assert mesh.channels.channel_mappings() == ((0, "radioamator"), (7, "TestChannel"))
def test_capture_channels_primary_falls_back_to_env(mesh_module, monkeypatch, capsys):
mesh = mesh_module
mesh.config.MODEM_PRESET = None
mesh.channels._reset_channel_cache()
monkeypatch.setenv("CHANNEL", "FallbackName")
class DummyInterface:
@@ -461,6 +465,29 @@ def test_capture_channels_primary_falls_back_to_env(mesh_module, monkeypatch, ca
assert "FallbackName" in log_output
def test_capture_channels_primary_falls_back_to_preset(mesh_module, capsys):
mesh = mesh_module
mesh.config.MODEM_PRESET = " MediumFast "
mesh.channels._reset_channel_cache()
class DummyInterface:
def __init__(self) -> None:
self.localNode = SimpleNamespace(
channels=[SimpleNamespace(role="PRIMARY", settings=SimpleNamespace())]
)
def waitForConfig(self) -> None: # noqa: D401 - matches interface contract
return None
mesh.channels.capture_from_interface(DummyInterface())
log_output = capsys.readouterr().out
assert mesh.channels.channel_mappings() == ((0, "MediumFast"),)
assert mesh.channels.channel_name(0) == "MediumFast"
assert "MediumFast" in log_output
def test_create_default_interface_falls_back_to_tcp(mesh_module, monkeypatch):
mesh = mesh_module
attempts = []