Files
skyplot/CLAUDE.md
T
2026-07-26 21:22:44 +02:00

3.0 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Running the application

# Activate the virtual environment first
source .venv/bin/activate

# Run the app
python sky_plot.py

Architecture

This is a PyQt5 desktop app that reads GNSS satellite data from a u-blox receiver (UBX protocol) over serial or TCP/IP and visualizes it in real time.

Data flow

  1. GnssReader (QThread in gnss_thread.py) polls the device in a loop: sends NAV-SAT and NAV-DOP poll requests, reads 512 bytes, feeds them through UbxPacketizer.
  2. Decoded frames are passed to extract_satellites() in ubx.py, which returns a dict with optional keys 'sat' (list of satellite dicts) and 'dop' (dict with p_dop, h_dop, etc.).
  3. GnssReader emits the satellites_updated(dict) signal.
  4. MainWindow._on_satellites() routes the payload to three widgets: SkyPlotWidget, SatelliteTable, and PlotTab.

Module overview

File Responsibility
sky_plot.py Entry point; MainWindow with three tabs: Connection, Sky View, Plot
gnss_thread.py GnssReader(QThread) — device I/O loop, emits signals
ubx.py UBX protocol: UbxPacketizer (byte-stream → frames), parse_nav_sat, parse_nav_dop, extract_satellites
transport.py Abstract GnssTransport base class
transport_serial.py SerialTransport — wraps pyserial
transport_network.py TcpTransport — wraps socket (for ser2net)
connection_panel.py ConnectionPanel(QGroupBox) — serial/TCP UI, emits connect_requested(factory, label)
lru_store.py LruStore — persists up to 5 recent TCP connections via QSettings
sky_plot_widget.py SkyPlotWidget(QWidget) — polar sky plot, custom paintEvent
sat_table.py SatelliteTable(QTableWidget) — tabular satellite list
plot_tab.py PlotTab — 2×4 grid of SinglePlotPanels (pyqtgraph), time-series plots with persistent settings
defines.py GNSS_NAMES and GNSS_COLORS shared constants

Key design notes

  • Transport factory pattern: ConnectionPanel emits a factory callable (a lambda that creates a transport). GnssReader calls the factory in its thread, keeping socket/serial construction off the main thread.
  • Disabled old code: MainWindow.__build_ui and MainWindow.__connect (double-underscore prefix) are the original single-view implementations, effectively disabled by Python name mangling. The active methods are _build_ui and _connect.
  • sat_table.py duplicates GNSS_NAMES/GNSS_COLORS from defines.py — prefer defines.py as the source of truth when extending.
  • Plot settings persistence: PlotSettingsStore saves each panel's selected field and SV filter to QSettings("gnss_skyplot", "connections") (same org/app as LruStore).
  • History cap: each SinglePlotPanel keeps at most MAX_HISTORY = 300 data points per satellite/PDOP curve.