gui: add File source type to connection tab

- ConnectionConfig: new file_path and delay fields
- ConnectionRow: File page with path input, Browse button, delay
  spinner (0–10 s), and auto-fill of receiver-ID from filename
- ReceiverManager.connect_receiver: FileBackend wired for 'file' type;
  UBX poll timer skipped for file sources
- FileBackend.register_xcvr: fallback to first unoccupied entry when
  name does not match filename pattern

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 12:47:28 +02:00
co-authored by Claude Sonnet 4.6
parent 4c00f57a85
commit ff686b64f7
3 changed files with 80 additions and 20 deletions
+20 -13
View File
@@ -52,16 +52,20 @@ class SatelliteData:
@dataclass
class ConnectionConfig:
receiver_id: str
conn_type: str = 'tcp'
host: str = ''
port: int = 8721
serial_port: str = ''
baud_rate: int = 115200
conn_type: str = 'tcp'
host: str = ''
port: int = 8721
serial_port: str = ''
baud_rate: int = 115200
file_path: str = ''
delay: float = 1.0
def display_str(self) -> str:
if self.conn_type == 'tcp':
return f"{self.receiver_id} [{self.host}:{self.port}]"
return f"{self.receiver_id} [{self.serial_port} @ {self.baud_rate}]"
if self.conn_type == 'serial':
return f"{self.receiver_id} [{self.serial_port} @ {self.baud_rate}]"
return f"{self.receiver_id} [file: {os.path.basename(self.file_path)}]"
def to_dict(self):
return dataclasses.asdict(self)
@@ -148,6 +152,7 @@ class ReceiverManager(QObject):
def connect_receiver(self, rid: str):
from listeners import NavSatQtListener, GsaQtListener
from backend.serial_backend import SerialBackend
from backend.file_backend import FileBackend
config = self._configs.get(rid)
state = self._states.get(rid)
@@ -160,8 +165,10 @@ class ReceiverManager(QObject):
backend = NetworkBackend(
[{'name': rid, 'host': config.host, 'port': config.port}]
)
else:
elif config.conn_type == 'serial':
backend = SerialBackend(config.serial_port, config.baud_rate)
else:
backend = FileBackend([config.file_path], delay=config.delay)
backend.register_xcvr(xcvr)
@@ -184,12 +191,12 @@ class ReceiverManager(QObject):
state.transceiver = xcvr
state.connected = True
# Poll UBX messages every second (receiver only sends on request by default)
timer = QTimer(self)
timer.setInterval(1000)
timer.timeout.connect(lambda r=rid: self._poll_ubx(r))
timer.start()
state.poll_timer = timer
if config.conn_type != 'file':
timer = QTimer(self)
timer.setInterval(1000)
timer.timeout.connect(lambda r=rid: self._poll_ubx(r))
timer.start()
state.poll_timer = timer
self._push_lru(config)
self.connection_changed.emit(rid, True)