add UBX-MON-VER support and surface device identification in CLI/GUI

Add the Ver message parser and a fixed UbxQuery (was unused and had a
broken semaphore/state bug) to poll MON-VER once on connect. The CLI
prints hw/sw version and extensions; the GUI polls it per receiver,
pre-fills the read-only ID field with a connection counter and
rewrites it from the MOD= extension once the device answers, and
propagates the resolved display name to the Sky and Plot tabs so they
no longer show the stale placeholder ID.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XM4FNUjhu9x8df5Dp1hHvd
This commit is contained in:
2026-07-16 20:22:25 +02:00
co-authored by Claude Sonnet 5
parent d506f9afe0
commit 2dba3a9a2f
8 changed files with 176 additions and 27 deletions
+28 -4
View File
@@ -1,4 +1,4 @@
import sys, os
import sys, os, itertools
_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
_gui = os.path.dirname(os.path.abspath(__file__))
@@ -19,6 +19,8 @@ from backend.file_backend import source_id_from_path
BAUD_RATES = ['4800', '9600', '19200', '38400', '57600', '115200',
'230400', '460800', '921600']
_connection_counter = itertools.count(1)
class _StatusDot(QLabel):
def __init__(self):
@@ -45,10 +47,11 @@ class ConnectionRow(QWidget):
layout.setContentsMargins(4, 2, 4, 2)
layout.setSpacing(6)
# ── Receiver ID ──────────────────────────────────────────────────────
# ── Receiver ID (read-only: pre-filled with a counter, rewritten from
# MON-VER once the device answers, or derived from the file path) ──
layout.addWidget(QLabel("ID:"))
self._id_edit = QLineEdit()
self._id_edit.setPlaceholderText("receiver-id")
self._id_edit.setReadOnly(True)
self._id_edit.setFixedWidth(110)
layout.addWidget(self._id_edit)
@@ -125,6 +128,11 @@ class ConnectionRow(QWidget):
layout.addWidget(self._stack)
layout.addStretch()
# ── Device identification (read-only, from MON-VER on connect) ────────
self._version_label = QLabel("")
self._version_label.setStyleSheet("color: #888888; font-size: 11px;")
layout.addWidget(self._version_label)
# ── Status / buttons ─────────────────────────────────────────────────
self._dot = _StatusDot()
layout.addWidget(self._dot)
@@ -141,6 +149,8 @@ class ConnectionRow(QWidget):
if config:
self.apply_config(config)
else:
self._id_edit.setText(f"conn-{next(_connection_counter)}")
# ── File browse ──────────────────────────────────────────────────────────
@@ -199,10 +209,17 @@ class ConnectionRow(QWidget):
self._connected = connected
self._dot.set_connected(connected)
self._conn_btn.setText("Disconnect" if connected else "Connect")
for w in [self._id_edit, self._type_combo, self._host_edit,
for w in [self._type_combo, self._host_edit,
self._port_spin, self._ser_combo, self._baud_combo,
self._file_edit, self._delay_spin]:
w.setEnabled(not connected)
if not connected:
self._version_label.setText("")
def set_version_info(self, device_id: str, sw_version: str):
if device_id:
self._id_edit.setText(device_id)
self._version_label.setText(sw_version)
# ── Slots ────────────────────────────────────────────────────────────────
@@ -287,6 +304,7 @@ class ConnectionTab(QWidget):
outer.addLayout(bottom)
model.connection_changed.connect(self._on_connection_changed)
model.version_update.connect(self._on_version_update)
# ── History combo ─────────────────────────────────────────────────────────
@@ -332,3 +350,9 @@ class ConnectionTab(QWidget):
break
if connected:
self._refresh_history_combo()
def _on_version_update(self, rid: str, device_id: str, sw_version: str):
for row in self._rows:
if row.get_receiver_id() == rid:
row.set_version_info(device_id, sw_version)
break