Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
"""SkyWalker-1 TUI — main application.
|
|
|
|
|
|
Add Device, Stream, and Config screens to TUI (F6-F8)
Expand from 5 to 8 mode screens. F6 Device provides firmware
management, EEPROM flash with full safety state machine (C2
validation, auto-backup, 3s countdown, page write, byte verify),
and diagnostics (boot test, I2C scan, register dump). F7 Stream
does live TS capture with PID distribution and PAT/PMT tree.
F8 Config manages LNB power, DiSEqC switching, and modulation/FEC.
Foundation: 12 new SkyWalker1 methods (device info, FX2 RAM,
EEPROM I2C, diagnostics), matching DemoDevice synthetics with
realistic C2 image and TS packets, 20 bridge wrappers (RLock).
2026-02-14 16:08:58 -07:00
|
|
|
Provides mode switching between 8 operating modes via a sidebar and F-key
|
|
|
|
|
shortcuts. Each mode is a Container subclass that manages its own workers.
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
|
Add Device, Stream, and Config screens to TUI (F6-F8)
Expand from 5 to 8 mode screens. F6 Device provides firmware
management, EEPROM flash with full safety state machine (C2
validation, auto-backup, 3s countdown, page write, byte verify),
and diagnostics (boot test, I2C scan, register dump). F7 Stream
does live TS capture with PID distribution and PAT/PMT tree.
F8 Config manages LNB power, DiSEqC switching, and modulation/FEC.
Foundation: 12 new SkyWalker1 methods (device info, FX2 RAM,
EEPROM I2C, diagnostics), matching DemoDevice synthetics with
realistic C2 image and TS packets, 20 bridge wrappers (RLock).
2026-02-14 16:08:58 -07:00
|
|
|
Note: We use "rf_mode" terminology for our operating modes to avoid colliding
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
with Textual's built-in App.mode / _current_mode / _screen_stacks system.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
from textual.app import App, ComposeResult
|
|
|
|
|
from textual.binding import Binding
|
|
|
|
|
from textual.containers import Horizontal, Vertical
|
|
|
|
|
from textual.widgets import Header, Footer, Button, Label, Static, ContentSwitcher
|
|
|
|
|
|
|
|
|
|
from skywalker_tui.bridge import USBBridge
|
|
|
|
|
from skywalker_tui.demo import DemoDevice
|
|
|
|
|
from skywalker_tui.widgets.status_bar import DeviceStatusBar
|
|
|
|
|
|
|
|
|
|
from skywalker_tui.screens.spectrum import SpectrumScreen
|
|
|
|
|
from skywalker_tui.screens.scan import ScanScreen
|
|
|
|
|
from skywalker_tui.screens.monitor import MonitorScreen
|
|
|
|
|
from skywalker_tui.screens.lband import LBandScreen
|
|
|
|
|
from skywalker_tui.screens.track import TrackScreen
|
Add Device, Stream, and Config screens to TUI (F6-F8)
Expand from 5 to 8 mode screens. F6 Device provides firmware
management, EEPROM flash with full safety state machine (C2
validation, auto-backup, 3s countdown, page write, byte verify),
and diagnostics (boot test, I2C scan, register dump). F7 Stream
does live TS capture with PID distribution and PAT/PMT tree.
F8 Config manages LNB power, DiSEqC switching, and modulation/FEC.
Foundation: 12 new SkyWalker1 methods (device info, FX2 RAM,
EEPROM I2C, diagnostics), matching DemoDevice synthetics with
realistic C2 image and TS packets, 20 bridge wrappers (RLock).
2026-02-14 16:08:58 -07:00
|
|
|
from skywalker_tui.screens.device import DeviceScreen
|
|
|
|
|
from skywalker_tui.screens.stream import StreamScreen
|
|
|
|
|
from skywalker_tui.screens.config import ConfigScreen
|
Add DiSEqC motor control, QO-100 DATV reception, and carrier survey
Firmware v3.03.0: DiSEqC Manchester encoder (cmd 0x8D extended),
parameterized spectrum sweep (0xBA), adaptive blind scan (0xBB),
error code reporting (0xBC). All new function locals moved to XDATA
to fit within FX2LP 256-byte internal RAM constraint.
Motor control: DiSEqC 1.2 positioner with USALS GotoX, stored
positions, interactive keyboard jog, 30-second safety auto-halt.
QO-100 DATV: Es'hail-2 wideband transponder tools — LNB IF
calculator, narrowband scan, tune, and TS-to-video pipe (ffplay/mpv).
Carrier survey: six-stage pipeline (coarse sweep → peak detection →
fine sweep → blind scan → TS sample → catalog). JSON catalog with
differential analysis, QO-100 optimized mode, CSV/text export.
TUI: F9 Motor screen (3-column layout with signal gauge), F10 Survey
screen (Full Band + QO-100 tabs). Bridge, demo, and theme updated.
Docs: motor.mdx, survey.mdx, qo100-datv.mdx guide, tui.mdx updated
for 10 screens. Site builds 41 pages, all links valid.
2026-02-15 17:01:11 -07:00
|
|
|
from skywalker_tui.screens.motor import MotorScreen
|
|
|
|
|
from skywalker_tui.screens.survey import SurveyScreen
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
MODES = {
|
|
|
|
|
"spectrum": ("F1 Spectrum", SpectrumScreen),
|
|
|
|
|
"scan": ("F2 Scan", ScanScreen),
|
|
|
|
|
"monitor": ("F3 Monitor", MonitorScreen),
|
|
|
|
|
"lband": ("F4 L-Band", LBandScreen),
|
|
|
|
|
"track": ("F5 Track", TrackScreen),
|
Add Device, Stream, and Config screens to TUI (F6-F8)
Expand from 5 to 8 mode screens. F6 Device provides firmware
management, EEPROM flash with full safety state machine (C2
validation, auto-backup, 3s countdown, page write, byte verify),
and diagnostics (boot test, I2C scan, register dump). F7 Stream
does live TS capture with PID distribution and PAT/PMT tree.
F8 Config manages LNB power, DiSEqC switching, and modulation/FEC.
Foundation: 12 new SkyWalker1 methods (device info, FX2 RAM,
EEPROM I2C, diagnostics), matching DemoDevice synthetics with
realistic C2 image and TS packets, 20 bridge wrappers (RLock).
2026-02-14 16:08:58 -07:00
|
|
|
"device": ("F6 Device", DeviceScreen),
|
|
|
|
|
"stream": ("F7 Stream", StreamScreen),
|
|
|
|
|
"config": ("F8 Config", ConfigScreen),
|
Add DiSEqC motor control, QO-100 DATV reception, and carrier survey
Firmware v3.03.0: DiSEqC Manchester encoder (cmd 0x8D extended),
parameterized spectrum sweep (0xBA), adaptive blind scan (0xBB),
error code reporting (0xBC). All new function locals moved to XDATA
to fit within FX2LP 256-byte internal RAM constraint.
Motor control: DiSEqC 1.2 positioner with USALS GotoX, stored
positions, interactive keyboard jog, 30-second safety auto-halt.
QO-100 DATV: Es'hail-2 wideband transponder tools — LNB IF
calculator, narrowband scan, tune, and TS-to-video pipe (ffplay/mpv).
Carrier survey: six-stage pipeline (coarse sweep → peak detection →
fine sweep → blind scan → TS sample → catalog). JSON catalog with
differential analysis, QO-100 optimized mode, CSV/text export.
TUI: F9 Motor screen (3-column layout with signal gauge), F10 Survey
screen (Full Band + QO-100 tabs). Bridge, demo, and theme updated.
Docs: motor.mdx, survey.mdx, qo100-datv.mdx guide, tui.mdx updated
for 10 screens. Site builds 41 pages, all links valid.
2026-02-15 17:01:11 -07:00
|
|
|
"motor": ("F9 Motor", MotorScreen),
|
|
|
|
|
"survey": ("F10 Survey", SurveyScreen),
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SkyWalkerApp(App):
|
|
|
|
|
"""Textual TUI for Genpix SkyWalker-1 DVB-S receiver."""
|
|
|
|
|
|
|
|
|
|
TITLE = "SkyWalker-1"
|
|
|
|
|
SUB_TITLE = "DVB-S RF Tool"
|
|
|
|
|
CSS_PATH = "theme.tcss"
|
|
|
|
|
|
|
|
|
|
BINDINGS = [
|
|
|
|
|
Binding("f1", "rf_mode('spectrum')", "Spectrum", show=True),
|
|
|
|
|
Binding("f2", "rf_mode('scan')", "Scan", show=True),
|
|
|
|
|
Binding("f3", "rf_mode('monitor')", "Monitor", show=True),
|
|
|
|
|
Binding("f4", "rf_mode('lband')", "L-Band", show=True),
|
|
|
|
|
Binding("f5", "rf_mode('track')", "Track", show=True),
|
Add Device, Stream, and Config screens to TUI (F6-F8)
Expand from 5 to 8 mode screens. F6 Device provides firmware
management, EEPROM flash with full safety state machine (C2
validation, auto-backup, 3s countdown, page write, byte verify),
and diagnostics (boot test, I2C scan, register dump). F7 Stream
does live TS capture with PID distribution and PAT/PMT tree.
F8 Config manages LNB power, DiSEqC switching, and modulation/FEC.
Foundation: 12 new SkyWalker1 methods (device info, FX2 RAM,
EEPROM I2C, diagnostics), matching DemoDevice synthetics with
realistic C2 image and TS packets, 20 bridge wrappers (RLock).
2026-02-14 16:08:58 -07:00
|
|
|
Binding("f6", "rf_mode('device')", "Device", show=True),
|
|
|
|
|
Binding("f7", "rf_mode('stream')", "Stream", show=True),
|
|
|
|
|
Binding("f8", "rf_mode('config')", "Config", show=True),
|
Add DiSEqC motor control, QO-100 DATV reception, and carrier survey
Firmware v3.03.0: DiSEqC Manchester encoder (cmd 0x8D extended),
parameterized spectrum sweep (0xBA), adaptive blind scan (0xBB),
error code reporting (0xBC). All new function locals moved to XDATA
to fit within FX2LP 256-byte internal RAM constraint.
Motor control: DiSEqC 1.2 positioner with USALS GotoX, stored
positions, interactive keyboard jog, 30-second safety auto-halt.
QO-100 DATV: Es'hail-2 wideband transponder tools — LNB IF
calculator, narrowband scan, tune, and TS-to-video pipe (ffplay/mpv).
Carrier survey: six-stage pipeline (coarse sweep → peak detection →
fine sweep → blind scan → TS sample → catalog). JSON catalog with
differential analysis, QO-100 optimized mode, CSV/text export.
TUI: F9 Motor screen (3-column layout with signal gauge), F10 Survey
screen (Full Band + QO-100 tabs). Bridge, demo, and theme updated.
Docs: motor.mdx, survey.mdx, qo100-datv.mdx guide, tui.mdx updated
for 10 screens. Site builds 41 pages, all links valid.
2026-02-15 17:01:11 -07:00
|
|
|
Binding("f9", "rf_mode('motor')", "Motor", show=True),
|
|
|
|
|
Binding("f10", "rf_mode('survey')", "Survey", show=True),
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
Binding("q", "quit", "Quit", show=True),
|
|
|
|
|
Binding("d", "toggle_dark", "Theme", show=True),
|
Add radar scope, splash screen, Star Wars easter egg, and harden TUI
New features:
- P1 green phosphor radar scope widget on Track screen with LUT-optimized rendering
- Splash screen with pre-baked ANSI half-block art from 16colo.rs/Mistigris
- Star Wars ASCII animation via telnet (ctrl+w) with IPv6 happy eyeballs and offline fallback
- Dark Side / New Hope toast notifications on theme toggle
- Kitty terminal detection with cat emoji on splash
Robustness (from Apollo code review):
- Circuit breaker in track loop after 10 consecutive errors
- Input validation for frequency, symbol rate, step size across scan/spectrum/track
- Consolidated sys.path manipulation into __init__.py
- Radar scope pre-computes dist/angle LUT per pixel on resize
Cleanup:
- Removed unused imports across lband, monitor, scan, signal_gauge
- Moved Pillow/textual-image to optional dev deps (splash uses pre-baked ANSI)
- Added 41-test pytest suite covering telnet IAC parsing, radar geometry, splash assets
2026-02-14 09:51:58 -07:00
|
|
|
Binding("ctrl+w", "starwars", "Star Wars", show=False),
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
]
|
|
|
|
|
|
Add radar scope, splash screen, Star Wars easter egg, and harden TUI
New features:
- P1 green phosphor radar scope widget on Track screen with LUT-optimized rendering
- Splash screen with pre-baked ANSI half-block art from 16colo.rs/Mistigris
- Star Wars ASCII animation via telnet (ctrl+w) with IPv6 happy eyeballs and offline fallback
- Dark Side / New Hope toast notifications on theme toggle
- Kitty terminal detection with cat emoji on splash
Robustness (from Apollo code review):
- Circuit breaker in track loop after 10 consecutive errors
- Input validation for frequency, symbol rate, step size across scan/spectrum/track
- Consolidated sys.path manipulation into __init__.py
- Radar scope pre-computes dist/angle LUT per pixel on resize
Cleanup:
- Removed unused imports across lband, monitor, scan, signal_gauge
- Moved Pillow/textual-image to optional dev deps (splash uses pre-baked ANSI)
- Added 41-test pytest suite covering telnet IAC parsing, radar geometry, splash assets
2026-02-14 09:51:58 -07:00
|
|
|
def __init__(self, bridge: USBBridge, initial_mode: str = "spectrum",
|
|
|
|
|
show_splash: bool = True):
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
super().__init__()
|
|
|
|
|
self._bridge = bridge
|
|
|
|
|
self._initial_rf_mode = initial_mode
|
|
|
|
|
self._active_rf_mode = initial_mode
|
|
|
|
|
self._rf_screens: dict[str, object] = {}
|
Add radar scope, splash screen, Star Wars easter egg, and harden TUI
New features:
- P1 green phosphor radar scope widget on Track screen with LUT-optimized rendering
- Splash screen with pre-baked ANSI half-block art from 16colo.rs/Mistigris
- Star Wars ASCII animation via telnet (ctrl+w) with IPv6 happy eyeballs and offline fallback
- Dark Side / New Hope toast notifications on theme toggle
- Kitty terminal detection with cat emoji on splash
Robustness (from Apollo code review):
- Circuit breaker in track loop after 10 consecutive errors
- Input validation for frequency, symbol rate, step size across scan/spectrum/track
- Consolidated sys.path manipulation into __init__.py
- Radar scope pre-computes dist/angle LUT per pixel on resize
Cleanup:
- Removed unused imports across lband, monitor, scan, signal_gauge
- Moved Pillow/textual-image to optional dev deps (splash uses pre-baked ANSI)
- Added 41-test pytest suite covering telnet IAC parsing, radar geometry, splash assets
2026-02-14 09:51:58 -07:00
|
|
|
self._show_splash = show_splash
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
|
|
|
|
|
def compose(self) -> ComposeResult:
|
|
|
|
|
yield Header()
|
|
|
|
|
with Horizontal():
|
|
|
|
|
with Vertical(id="sidebar"):
|
|
|
|
|
yield Label("[bold #00d4aa]SkyWalker-1[/]", classes="sidebar-heading")
|
|
|
|
|
yield Label("[#506878]DVB-S RF Tool[/]", classes="sidebar-heading")
|
|
|
|
|
yield Static("")
|
|
|
|
|
for mode_key, (label, _cls) in MODES.items():
|
|
|
|
|
yield Button(label, id=f"btn-{mode_key}", classes="mode-button")
|
|
|
|
|
yield Static("")
|
|
|
|
|
yield DeviceStatusBar(self._bridge)
|
|
|
|
|
yield ContentSwitcher(id="content-area")
|
|
|
|
|
yield Footer()
|
|
|
|
|
|
|
|
|
|
def on_mount(self) -> None:
|
Add radar scope, splash screen, Star Wars easter egg, and harden TUI
New features:
- P1 green phosphor radar scope widget on Track screen with LUT-optimized rendering
- Splash screen with pre-baked ANSI half-block art from 16colo.rs/Mistigris
- Star Wars ASCII animation via telnet (ctrl+w) with IPv6 happy eyeballs and offline fallback
- Dark Side / New Hope toast notifications on theme toggle
- Kitty terminal detection with cat emoji on splash
Robustness (from Apollo code review):
- Circuit breaker in track loop after 10 consecutive errors
- Input validation for frequency, symbol rate, step size across scan/spectrum/track
- Consolidated sys.path manipulation into __init__.py
- Radar scope pre-computes dist/angle LUT per pixel on resize
Cleanup:
- Removed unused imports across lband, monitor, scan, signal_gauge
- Moved Pillow/textual-image to optional dev deps (splash uses pre-baked ANSI)
- Added 41-test pytest suite covering telnet IAC parsing, radar geometry, splash assets
2026-02-14 09:51:58 -07:00
|
|
|
# Initialize status bar (lightweight)
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
status = self.query_one(DeviceStatusBar)
|
|
|
|
|
status.update_status(self._bridge)
|
|
|
|
|
|
Add radar scope, splash screen, Star Wars easter egg, and harden TUI
New features:
- P1 green phosphor radar scope widget on Track screen with LUT-optimized rendering
- Splash screen with pre-baked ANSI half-block art from 16colo.rs/Mistigris
- Star Wars ASCII animation via telnet (ctrl+w) with IPv6 happy eyeballs and offline fallback
- Dark Side / New Hope toast notifications on theme toggle
- Kitty terminal detection with cat emoji on splash
Robustness (from Apollo code review):
- Circuit breaker in track loop after 10 consecutive errors
- Input validation for frequency, symbol rate, step size across scan/spectrum/track
- Consolidated sys.path manipulation into __init__.py
- Radar scope pre-computes dist/angle LUT per pixel on resize
Cleanup:
- Removed unused imports across lband, monitor, scan, signal_gauge
- Moved Pillow/textual-image to optional dev deps (splash uses pre-baked ANSI)
- Added 41-test pytest suite covering telnet IAC parsing, radar geometry, splash assets
2026-02-14 09:51:58 -07:00
|
|
|
if self._show_splash:
|
|
|
|
|
# Push splash FIRST, then init mode screens behind it.
|
|
|
|
|
# Two-tick chain: tick 1 = splash renders, tick 2 = heavy work.
|
|
|
|
|
self.call_later(self._push_splash)
|
|
|
|
|
else:
|
|
|
|
|
self.call_later(self._init_mode_screens)
|
|
|
|
|
|
|
|
|
|
def _push_splash(self) -> None:
|
|
|
|
|
"""Push splash screen, then defer heavy mode screen init."""
|
|
|
|
|
from skywalker_tui.screens.splash import SplashScreen
|
|
|
|
|
try:
|
|
|
|
|
self.push_screen(SplashScreen())
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
# Mode screens mount behind the splash overlay — pre-baked ANSI art
|
|
|
|
|
# renders instantly so no delay needed before heavy work starts
|
|
|
|
|
self.call_later(self._init_mode_screens)
|
|
|
|
|
|
|
|
|
|
def _init_mode_screens(self) -> None:
|
Add Device, Stream, and Config screens to TUI (F6-F8)
Expand from 5 to 8 mode screens. F6 Device provides firmware
management, EEPROM flash with full safety state machine (C2
validation, auto-backup, 3s countdown, page write, byte verify),
and diagnostics (boot test, I2C scan, register dump). F7 Stream
does live TS capture with PID distribution and PAT/PMT tree.
F8 Config manages LNB power, DiSEqC switching, and modulation/FEC.
Foundation: 12 new SkyWalker1 methods (device info, FX2 RAM,
EEPROM I2C, diagnostics), matching DemoDevice synthetics with
realistic C2 image and TS packets, 20 bridge wrappers (RLock).
2026-02-14 16:08:58 -07:00
|
|
|
"""Mount all 8 mode screens into the content switcher."""
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
switcher = self.query_one("#content-area", ContentSwitcher)
|
|
|
|
|
for mode_key, (_label, cls) in MODES.items():
|
|
|
|
|
screen = cls(self._bridge, id=f"screen-{mode_key}")
|
|
|
|
|
self._rf_screens[mode_key] = screen
|
|
|
|
|
switcher.mount(screen)
|
|
|
|
|
self.action_rf_mode(self._initial_rf_mode)
|
|
|
|
|
|
|
|
|
|
def action_rf_mode(self, mode: str) -> None:
|
|
|
|
|
"""Switch to a different RF operating mode."""
|
|
|
|
|
if mode not in MODES:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
self._active_rf_mode = mode
|
|
|
|
|
switcher = self.query_one("#content-area", ContentSwitcher)
|
|
|
|
|
switcher.current = f"screen-{mode}"
|
|
|
|
|
|
|
|
|
|
# Update sidebar button highlights
|
|
|
|
|
for mode_key in MODES:
|
|
|
|
|
btn = self.query_one(f"#btn-{mode_key}", Button)
|
|
|
|
|
btn.remove_class("-active")
|
|
|
|
|
self.query_one(f"#btn-{mode}", Button).add_class("-active")
|
|
|
|
|
|
Add radar scope, splash screen, Star Wars easter egg, and harden TUI
New features:
- P1 green phosphor radar scope widget on Track screen with LUT-optimized rendering
- Splash screen with pre-baked ANSI half-block art from 16colo.rs/Mistigris
- Star Wars ASCII animation via telnet (ctrl+w) with IPv6 happy eyeballs and offline fallback
- Dark Side / New Hope toast notifications on theme toggle
- Kitty terminal detection with cat emoji on splash
Robustness (from Apollo code review):
- Circuit breaker in track loop after 10 consecutive errors
- Input validation for frequency, symbol rate, step size across scan/spectrum/track
- Consolidated sys.path manipulation into __init__.py
- Radar scope pre-computes dist/angle LUT per pixel on resize
Cleanup:
- Removed unused imports across lband, monitor, scan, signal_gauge
- Moved Pillow/textual-image to optional dev deps (splash uses pre-baked ANSI)
- Added 41-test pytest suite covering telnet IAC parsing, radar geometry, splash assets
2026-02-14 09:51:58 -07:00
|
|
|
self.sub_title = f"DVB-S RF Tool \u2014 {MODES[mode][0]}"
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
|
|
|
|
|
def on_button_pressed(self, event: Button.Pressed) -> None:
|
|
|
|
|
"""Handle sidebar mode button clicks."""
|
|
|
|
|
btn_id = event.button.id or ""
|
|
|
|
|
if btn_id.startswith("btn-"):
|
|
|
|
|
mode = btn_id[4:]
|
|
|
|
|
if mode in MODES:
|
|
|
|
|
self.action_rf_mode(mode)
|
|
|
|
|
|
|
|
|
|
def action_toggle_dark(self) -> None:
|
2026-02-14 14:49:02 -07:00
|
|
|
self.theme = (
|
|
|
|
|
"textual-dark" if self.theme == "textual-light" else "textual-light"
|
|
|
|
|
)
|
|
|
|
|
if self.current_theme.dark:
|
Add radar scope, splash screen, Star Wars easter egg, and harden TUI
New features:
- P1 green phosphor radar scope widget on Track screen with LUT-optimized rendering
- Splash screen with pre-baked ANSI half-block art from 16colo.rs/Mistigris
- Star Wars ASCII animation via telnet (ctrl+w) with IPv6 happy eyeballs and offline fallback
- Dark Side / New Hope toast notifications on theme toggle
- Kitty terminal detection with cat emoji on splash
Robustness (from Apollo code review):
- Circuit breaker in track loop after 10 consecutive errors
- Input validation for frequency, symbol rate, step size across scan/spectrum/track
- Consolidated sys.path manipulation into __init__.py
- Radar scope pre-computes dist/angle LUT per pixel on resize
Cleanup:
- Removed unused imports across lband, monitor, scan, signal_gauge
- Moved Pillow/textual-image to optional dev deps (splash uses pre-baked ANSI)
- Added 41-test pytest suite covering telnet IAC parsing, radar geometry, splash assets
2026-02-14 09:51:58 -07:00
|
|
|
self.notify(
|
|
|
|
|
"Welcome to the Dark Side.",
|
|
|
|
|
title="The Force is strong with this one",
|
|
|
|
|
severity="warning",
|
|
|
|
|
timeout=4,
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
self.notify(
|
|
|
|
|
"The Force awakens.",
|
|
|
|
|
title="A New Hope",
|
|
|
|
|
severity="information",
|
|
|
|
|
timeout=4,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def action_starwars(self) -> None:
|
|
|
|
|
"""Easter egg: stream ASCII Star Wars from telnet."""
|
|
|
|
|
from skywalker_tui.screens.starwars import StarWarsScreen
|
|
|
|
|
self.push_screen(StarWarsScreen())
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
|
prog="skywalker-tui",
|
|
|
|
|
description="Textual TUI for Genpix SkyWalker-1 DVB-S receiver",
|
|
|
|
|
)
|
|
|
|
|
parser.add_argument(
|
|
|
|
|
"--demo", action="store_true",
|
|
|
|
|
help="Use synthetic signal data (no hardware required)",
|
|
|
|
|
)
|
Add radar scope, splash screen, Star Wars easter egg, and harden TUI
New features:
- P1 green phosphor radar scope widget on Track screen with LUT-optimized rendering
- Splash screen with pre-baked ANSI half-block art from 16colo.rs/Mistigris
- Star Wars ASCII animation via telnet (ctrl+w) with IPv6 happy eyeballs and offline fallback
- Dark Side / New Hope toast notifications on theme toggle
- Kitty terminal detection with cat emoji on splash
Robustness (from Apollo code review):
- Circuit breaker in track loop after 10 consecutive errors
- Input validation for frequency, symbol rate, step size across scan/spectrum/track
- Consolidated sys.path manipulation into __init__.py
- Radar scope pre-computes dist/angle LUT per pixel on resize
Cleanup:
- Removed unused imports across lband, monitor, scan, signal_gauge
- Moved Pillow/textual-image to optional dev deps (splash uses pre-baked ANSI)
- Added 41-test pytest suite covering telnet IAC parsing, radar geometry, splash assets
2026-02-14 09:51:58 -07:00
|
|
|
parser.add_argument(
|
|
|
|
|
"--no-splash", action="store_true",
|
|
|
|
|
help="Skip the splash screen on startup",
|
|
|
|
|
)
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
parser.add_argument(
|
|
|
|
|
"mode", nargs="?", default="spectrum",
|
|
|
|
|
choices=list(MODES.keys()),
|
|
|
|
|
help="Initial mode (default: spectrum)",
|
|
|
|
|
)
|
|
|
|
|
parser.add_argument(
|
|
|
|
|
"-v", "--verbose", action="store_true",
|
|
|
|
|
help="Verbose USB logging (hardware mode only)",
|
|
|
|
|
)
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
if args.demo:
|
|
|
|
|
device = DemoDevice()
|
|
|
|
|
bridge = USBBridge(device)
|
|
|
|
|
else:
|
|
|
|
|
try:
|
|
|
|
|
from skywalker_lib import SkyWalker1
|
|
|
|
|
device = SkyWalker1(verbose=args.verbose)
|
|
|
|
|
device.open()
|
|
|
|
|
bridge = USBBridge(device)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"Cannot open SkyWalker-1: {e}", file=sys.stderr)
|
|
|
|
|
print("Use --demo for synthetic signal data.", file=sys.stderr)
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
Add radar scope, splash screen, Star Wars easter egg, and harden TUI
New features:
- P1 green phosphor radar scope widget on Track screen with LUT-optimized rendering
- Splash screen with pre-baked ANSI half-block art from 16colo.rs/Mistigris
- Star Wars ASCII animation via telnet (ctrl+w) with IPv6 happy eyeballs and offline fallback
- Dark Side / New Hope toast notifications on theme toggle
- Kitty terminal detection with cat emoji on splash
Robustness (from Apollo code review):
- Circuit breaker in track loop after 10 consecutive errors
- Input validation for frequency, symbol rate, step size across scan/spectrum/track
- Consolidated sys.path manipulation into __init__.py
- Radar scope pre-computes dist/angle LUT per pixel on resize
Cleanup:
- Removed unused imports across lband, monitor, scan, signal_gauge
- Moved Pillow/textual-image to optional dev deps (splash uses pre-baked ANSI)
- Added 41-test pytest suite covering telnet IAC parsing, radar geometry, splash assets
2026-02-14 09:51:58 -07:00
|
|
|
app = SkyWalkerApp(
|
|
|
|
|
bridge=bridge,
|
|
|
|
|
initial_mode=args.mode,
|
|
|
|
|
show_splash=not args.no_splash,
|
|
|
|
|
)
|
Add Textual TUI for SkyWalker-1 RF tool
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
2026-02-13 04:39:55 -07:00
|
|
|
try:
|
|
|
|
|
app.run()
|
|
|
|
|
finally:
|
|
|
|
|
bridge.close()
|