Bumped version to 2026.02.17, added classifiers/keywords/URLs.
Documented camera extra (Pillow + astropy) in CLAUDE.md.
Added TUI section with uvx usage and extras table.
Core library published as winegard-birdcage (import stays `birdcage`).
MCP server renamed birdcage-mcp → mcbirdcage, matching mcserial pattern.
Both packages live on PyPI — `uvx mcbirdcage` works out of the box.
Camera backend abstraction wrapping fswebcam/ffmpeg/libcamera-still via
subprocess, with DemoCamera fallback generating valid JPEG from raw bytes.
Capture pipeline writes JPEG + JSON sidecar always, optional FITS (astropy)
and EXIF (Pillow) when available. Thread-safe orchestrator with session
tracking, sequence numbering, and date-based output directories.
Trigger system: manual capture, configurable interval timer, and pass event
detection (AOS/TCA/LOS) with 0.5-degree TCA hysteresis. PassEventDetector
runs in the Craft tracking loop, fires callbacks to the camera overlay.
F6 overlay follows the F5 ConsoleOverlay pattern — ModalScreen with
install_screen persistence. Status panel, scrollable capture log, interval
controls, and AOS/TCA/LOS toggle buttons.
Tagline: "a generic AZ/EL positioner that doesn't care about wavelength"
added to TUI header subtitle.
51 new tests (77 total passing).
Replace sidebar + 5-screen layout with horizontal tab bar (F1-F4)
and persistent StatusStrip. Consolidate Position + Scan screens into
Signal (F3) with Monitor/Sweep/Sky Map sub-modes via ModeBar.
Screens:
- F1 Dashboard: system health, tracking panel, quick actions, presets
- F2 Control: motor tuning, compass rose, preset management
- F3 Signal: RSSI monitor, 1D sweep (SweepPlot), 2D sky map (heatmap)
- F4 System: NVS editor with regex filter, EEPROM, firmware info
- F5 Console: push/pop overlay (no longer a tab)
New widgets: StatusStrip, ModeBar, SweepPlot, QuickActions, PresetList,
ReceiverInfo, MotorTuning, NvsFilter, SystemHealth, TrackingPanel.
Removed: PositionScreen, ScanScreen, DeviceStatusBar (functionality
absorbed into new screens and StatusStrip).
App-level position poll feeds StatusStrip and active screen at ~2 Hz.
Fix shared threading.Event across instances (class-level mutable default).
F1 Position (compass rose, motor control, sparklines),
F2 Signal (RSSI gauge with sub-char precision, DVB/ADC sparklines, LNA toggle),
F3 Scan (AZ/EL grid sweep with heatmap and CSV export),
F4 System (NVS table, A3981 diagnostics, motor dynamics),
F5 Console (raw serial terminal with prompt detection and safety gates).
Includes SerialBridge (thread-safe protocol wrapper), DemoDevice
(synthetic simulation for --demo mode), dark RF theme with rounded
borders and teal accents, and send_raw() on CarryoutG2Protocol.