From 780de4fe2b943be83047e776ee7d808d2469dc5a Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Wed, 11 Feb 2026 06:05:06 -0700 Subject: [PATCH] Implement HAL 0.0.00 search kill, expand CLAUDE.md with firmware reference HAL 0.0.00 kills the search task via the OS task manager (os -> kill Search) rather than the ngsearch submenu used by HAL 2.05. Boot signal is NoGPS only. Source: saveitforparts/Travler_Rotor upstream repo. CLAUDE.md now includes firmware variant comparison table, full command reference, NVS indices, RS-485 pinout, and cable wiring notes. --- CLAUDE.md | 75 ++++++++++++++++++++++++++++++++--- src/travler_rotor/protocol.py | 29 ++++++++------ 2 files changed, 86 insertions(+), 18 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index ea0777a..63609a2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -32,15 +32,80 @@ rotctld.py — RotctldServer: Hamlib rotctld TCP protocol (p/P/S/_/q) cli.py — Click CLI with init/serve/pos/move subcommands ``` +## Firmware Variants + +Three known Winegard dish variants exist (Gabe Emerson / saveitforparts): + +| Detail | HAL 0.0.00 | HAL 2.05.003 | Trav'ler Pro | +|--------|-----------|-------------|-------------| +| **Repo** | saveitforparts/Travler_Rotor | saveitforparts/Trav-ler-Rotor-For-HAL-2.05 | saveitforparts/Travler-Pro-Rotor | +| **Connection** | RS-485 / RJ-25 | RS-485 / RJ-25 | USB A-to-A | +| **Motor submenu** | `mot` | `motor` | `mot` | +| **Search kill** | `os` -> `kill Search` -> `q` | `ngsearch` -> `s` -> `q` | `os` -> `kill Search` | +| **Boot signal** | `NoGPS` | `NoGPS` or `No LNB Voltage` | undocumented | +| **Max elevation** | 90 deg | 90 deg | 75 deg (hardware limit) | +| **Tested model** | LG-2112 | LG-2112 | SK2DISH | + +Related: saveitforparts/Carryout-Rotor (Winegard Carryout, HAL 1.00.065, very similar commands). + ## Hardware Protocol Notes -- RS-485 serial, 57600 baud, 8N1 +- RS-485 serial, 57600 baud, 8N1 (via USB-to-RS232 + DTECH RS232-to-RS485 + RJ-25) - Motor commands: `a ` (0=azimuth, 1=elevation) -- Position query: `a` returns `AZ = EL = SK = ` -- HAL 2.05 motor submenu: `motor` command; search kill via `ngsearch -> s -> q` -- HAL 0.0.00 motor submenu: `mot` command; search kill sequence undocumented -- Boot signals (HAL 2.05): "NoGPS" or "No LNB Voltage" indicate homing complete +- Position query: `a` (in motor submenu) returns `AZ = EL = SK = ` +- Two motor control methods: + - `a ` — queues command, waits for current motor to stop before next + - `g ` — immediate move, aborts on any new keystroke - Elevation floor: HAL 2.05 unreliable below 15 degrees with direct motor commands +- Cable wrap limit: usually 360 or 455 degrees, dish reverses at limit + +### RS-485 Pinout (RJ-25, bottom view, tip up) + +| Pin | Function | +|-----|----------| +| 1 | GND | +| 2 | T/R- | +| 3 | T/R+ | +| 4 | RXD- | +| 5 | RXD+ | +| 6 | Not used | + +### Firmware Console Commands + +``` +? — list available commands +motor / mot — enter motor submenu (firmware-dependent) +a — show position (in motor submenu) +a — move motor to absolute position +g — go to AZ/EL (aborts on new input) +q — exit current submenu +os — enter OS submenu + tasks — list running tasks + kill — kill a named task (e.g. "kill Search") +ngsearch — enter search submenu (HAL 2.05 only) + s — stop search +nvs — enter non-volatile storage submenu + e — read NVS value + e — write NVS value + s — save changes +reboot — reboot firmware +``` + +### Known NVS Indices + +| Index | Setting | +|-------|---------| +| 102 | Max elevation | +| 125 | Search minimum elevation | +| 127 | Safe minimum elevation | + +### IDU/ODU Cable Wiring (if cut) + +Top row: Green, Yellow, Orange. Bottom row: Red, Brown, Black. + +### Power + +48-52VDC power supply for the IDU. The internal coax supplies 14-18VDC bias — do not connect 5V equipment without bypassing the power injector. ## Known Bugs (from upstream) diff --git a/src/travler_rotor/protocol.py b/src/travler_rotor/protocol.py index 9ea67f8..23beefd 100644 --- a/src/travler_rotor/protocol.py +++ b/src/travler_rotor/protocol.py @@ -178,19 +178,20 @@ class HAL205Protocol(FirmwareProtocol): class HAL000Protocol(FirmwareProtocol): - """HAL 0.0.00 firmware. + """HAL 0.0.00 firmware (older Trav'ler units). - Uses shorter command names and a different init sequence. + Boot signal: "NoGPS" Motor submenu: "mot" + Search kill: os -> kill Search -> q (OS task manager approach) + + Source: github.com/saveitforparts/Travler_Rotor (v2.0, HAL 0.0.00 branch) """ + BOOT_SIGNALS = ("NoGPS",) MOTOR_COMMAND = "mot" def initialize(self, callback: Callable[[str], None] | None = None) -> None: - # HAL 0.0.00 has a different boot sequence — the exact signals - # are not documented in the upstream repo. This is a best-effort - # implementation that should be validated against real hardware. - logger.info("Waiting for HAL 0.0.00 boot...") + logger.info("Waiting for HAL 0.0.00 boot (ensure IDU is powered on)...") while True: line = self._readline() @@ -201,20 +202,22 @@ class HAL000Protocol(FirmwareProtocol): callback(line) logger.debug("Boot: %s", line) - # HAL 0.0.00 boot detection — adjust if hardware reveals - # different signals - if "NoGPS" in line or "ready" in line.lower(): - logger.info("Boot complete") + if any(signal in line for signal in self.BOOT_SIGNALS): + logger.info("Boot complete — homing finished") break self.kill_search() self.reset_to_root() def kill_search(self) -> None: - # HAL 0.0.00 may have a different search-kill sequence. - # Falling back to root-menu reset as a safe default. self.reset_to_root() - logger.info("Search task cancelled (HAL 0.0.00)") + self._write("os") + time.sleep(0.2) + self._write("kill Search") + time.sleep(0.2) + self._write("q") + self._write("") + logger.info("Search task cancelled via OS task manager") def enter_motor_menu(self) -> None: self.reset_to_root()