From 4bfc0e25cb5ec0a4ec3768ca032470cad23c4b47 Mon Sep 17 00:00:00 2001 From: l5y <220195275+l5yth@users.noreply.github.com> Date: Thu, 16 Oct 2025 20:35:24 +0200 Subject: [PATCH] Prefer reported primary channel names (#363) --- data/mesh_ingestor/channels.py | 37 ++++++++++++++++++++++++---------- tests/test_mesh.py | 35 ++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/data/mesh_ingestor/channels.py b/data/mesh_ingestor/channels.py index a2546a5..b03c69f 100644 --- a/data/mesh_ingestor/channels.py +++ b/data/mesh_ingestor/channels.py @@ -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 diff --git a/tests/test_mesh.py b/tests/test_mesh.py index e506429..507071a 100644 --- a/tests/test_mesh.py +++ b/tests/test_mesh.py @@ -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 = []