# dwarfctl — Open-source DWARF telescope control CLI A Go command-line tool for controlling **DWARF II** (and upcoming DWARF III) smart telescopes over Wi-Fi via their WebSocket API. Built from reverse-engineered protocol specs (see `../analysis/`). ## Quick start ```bash make build ./dwarfctl --ip 192.168.1.100 state ``` ## Prerequisites The telescope must be connected to your Wi-Fi (or your phone joined to the telescope's AP hotspot). Once you can ping the telescope's IP, `dwarfctl` can reach it. Find the IP from: - The official DWARFLAB app's Settings → My Device - Your router's DHCP table (hostname like `DWARFxxxx`) - The BLE handshake (see `../analysis/API_REFERENCE.md`) ## Usage examples ```bash # Device state dwarfctl --ip 192.168.1.100 state # Camera dwarfctl camera open --cam tele dwarfctl camera photo --cam tele dwarfctl camera photo --cam wide --raw dwarfctl camera burst start --cam tele dwarfctl camera exp --cam tele 156 # 1/4s exposure dwarfctl camera gain --cam tele 60 dwarfctl camera params --cam tele # Motor / slew dwarfctl motor slew 90 0.5 # angle 90°, half speed dwarfctl motor stop 0 # stop RA motor dwarfctl motor goto 0 45.0 5.0 # RA motor to 45° at speed 5 # Astrophotography dwarfctl astro calibrate start dwarfctl astro goto-dso 10.6847 41.2687 "M31 Andromeda" dwarfctl astro goto-solar 3 # Earth = index 3 dwarfctl astro stack start dwarfctl astro eq-solve start # polar alignment # Focus dwarfctl focus auto dwarfctl focus step 1 # 1=out, 0=in dwarfctl focus astro-af start # Tracking dwarfctl track start 640 360 100 100 0 # bbox at center of tele cam dwarfctl track stop # System dwarfctl system sync-time dwarfctl system set-location 48.8566 2.3522 35 # Power dwarfctl power rgb-on dwarfctl power rgb-off dwarfctl power reboot dwarfctl power off # Monitor notifications (live status events) dwarfctl monitor ``` ## Architecture ``` dwarfctl/ ├── proto/dwarf.proto # unified proto3 definitions (397 messages) ├── proto/dwarf.pb.go # generated Go bindings (24948 lines) ├── internal/ │ ├── transport/client.go # WebSocket client + WsPacket envelope │ └── api/ │ ├── commands.go # 323 command IDs + module routing │ └── client.go # typed Telescope API (camera/motor/astro/...) └── cmd/dwarfctl/main.go # cobra CLI ``` ### Protocol summary | Layer | Transport | Port | |-------|-----------|------| | Control | WebSocket (binary protobuf) | 9900 | | Preview | RTSP (not implemented here) | 554 | Every command is a serialized `WsPacket{major=2, minor=3, device_id, module_id, cmd, type, data, client_id}`. The `module_id` is derived from `cmd` by range. See `../analysis/API_REFERENCE.md` for details. ## Regenerating protos If the proto definitions change: ```bash # From the APK analysis directory: python3 ../analysis/extract_protos.py ../extracted/jadx/.../proto ../analysis/protos # Merge into unified proto: cd dwarfctl/proto python3 merge.py . dwarf.proto protoc --go_out=. --go_opt=paths=source_relative dwarf.proto ``` ## Roadmap - [ ] BLE discovery + handshake (DwarfPing/DwarfEcho) - [ ] RTSP preview viewer - [ ] Interactive REPL mode - [ ] Schedule plan management - [ ] OTA firmware update - [ ] Full Notify event parsing (typed)