Add complete DWARFLAB protocol documentation

- Architecture overview, BLE and WebSocket protocols
- All 19 modules with command IDs validated against smali source
- BLE packet format with CRC-16/MODBUS pseudocode
- Complete WsCmd index (~300 commands)
- Connection flow with pseudocode examples
- Methodology section explaining APK decompilation process
This commit is contained in:
Jacquin Antoine
2026-06-13 00:21:19 +02:00
parent fe534ce77b
commit be87e8a4ca
14 changed files with 2373 additions and 0 deletions

97
00_methodology.md Normal file
View File

@ -0,0 +1,97 @@
# Methodology & Sources
## How This Documentation Was Obtained
All information in this documentation was extracted through **static analysis of the decompiled DWARFLAB Android APK** (v3.4.0, build 629, package `com.convergence.dwarflab`). No device was needed — the entire protocol is defined in the app's code.
### Decompilation
The APK was decompiled using **apktool v3.4.0**, which produced:
- `AndroidManifest.xml` — permissions, activities, services
- `smali/` through `smali_classes7/` — 7 DEX files of dalvik bytecode
- `lib/` — native `.so` libraries (arm64, armeabi-v7a, x86_64)
- `assets/` — voice JSON, country JSON, keystores
- `res/` — layouts, drawables, Lottie animations
### Key Smali Files Mapped to Protocol Concepts
| Protocol Concept | Smali File | Location |
|-----------------|------------|----------|
| BLE UUIDs | `cg1.smali` | `smali_classes4/` |
| BLE commands | `j80.smali` | `smali_classes4/` |
| BLE packet format | `l80.smali` | `smali_classes4/` |
| BLE CRC-16 | `vc0.smali` | `smali_classes4/` |
| WebSocket URL | `v55.smali` | `smali_classes4/` |
| WsPacket fields | `BaseProto$WsPacket.smali` | `smali_classes5/` |
| WsModuleId | `WsModuleId.smali` | `smali_classes4/` |
| WsCmd (all commands) | `WsCmd.smali` | `smali_classes4/` |
| WsMessageType | `WsMessageType.smali` | `smali_classes4/` |
| WsRespCode | `WsRespCode.smali` | `smali_classes4/` |
| DeviceType | `DeviceType.smali` | `smali_classes4/` |
| BluetoothPacketSender | `BluetoothPacketSender.smali` | `smali_classes4/` |
| ConnectionManager | `ConnectionManager.smali` | `smali_classes4/` |
| Proto messages | `AstroProto*.smali`, `CameraProto*.smali`, etc. | `smali_classes5/` |
### Extraction Methods
#### 1. UUID Discovery (`cg1.smali`)
The `cg1` class contains 8 static UUID strings. Read directly from the `<clinit>` method — the values are string constants embedded in the bytecode.
#### 2. Command IDs (`WsCmd.smali`)
The `WsCmd` enum contains ~300 entries. Each entry is initialized in `<clinit>` via `<init>(String name, int ordinal, int cmd)`. The third parameter (`cmd`) is the numeric command ID. Extracted by tracing register values through the constructor calls.
**Important**: Kotlin enum ordinals and explicit `cmd` IDs are different numbers. The `cmd` value is what goes on the wire.
#### 3. Module IDs (`WsModuleId.smali`)
The `WsModuleId` enum uses **ordinal values only** (no custom id field). Module ID = ordinal position in the enum (0-18).
#### 4. BLE Packet Format (`l80.smali`)
The `l80` class (obfuscated name for `BluetoothPacket`) encodes packets in method `j()`:
- Magic byte `0xAA` at position 0
- 9-byte header: protocolVersion, cmdInstruction, packageSequence, totalPackages, extendedProtocol (2B), validDataLength (2B)
- Payload: protobuf data
- CRC-16 computed by class `vc0` over header+payload
- End marker `0x0D`
The CRC lookup table in `vc0.smali` starts with `{0x0000, 0xC0C1, 0xC181, 0x0140, ...}` which identifies it as CRC-16/MODBUS (reflected polynomial 0xA001 = 0x8005 reflected, init 0xFFFF).
#### 5. WebSocket URL (`v55.smali`)
The URL is assembled by concatenating: `"ws://"` + `yd3.b()` (host IP) + `":9900/?client_id="` + `y32.c()` (client ID). Two additional constants: `0x1139` (4409) and `0x113A` (4410) for secondary ports.
#### 6. DeviceType IDs (`DeviceType.smali`)
The constructor signature is `<init>(String name, int ordinal, int deviceId, int nameResId)`. The `deviceId` parameter is the on-wire device identifier. Careful register tracing is required because smali reuses registers:
- Unknown: deviceId=0
- DWARF_2: deviceId=1
- DWARF_3: deviceId=2
- DWARF_mini: deviceId=4 (ordinal=3, **gap at deviceId=3**)
- DWARF_4: deviceId=5
- DWARF_DRAGON: deviceId=6
#### 7. Proto Message Fields (`smali_classes5/com/convergence/dwarflab/proto/`)
Each `.smali` file in the proto package corresponds to a protobuf message. Field numbers are embedded as constants in the `writeTo()` method (serialized using `writeString(fieldNumber, value)`, `writeInt32(fieldNumber, value)`, etc.). Field names are preserved in the obfuscated class names via Kotlin metadata annotations.
### Limitations
- **Obfuscated names**: Most class names are obfuscated (e.g., `l80`, `cg1`, `j80`). Kotlin metadata annotations help recover some names.
- **No `.proto` files**: The original `.proto` source files are not included in the APK. Field names and numbers are inferred from the generated Java/Kotlin code.
- **String literals**: Some strings (UUIDs, URLs, keys) are embedded directly and can be extracted with certainty. Others require contextual inference.
- **Behavioral details**: Timing, retry logic, and UI flow are inferred from the code but not directly observable without a device.
- **Version-specific**: This documentation corresponds to APK v3.4.0. Newer or older versions may differ.
### Verification
All data points were cross-validated in two passes:
1. **First pass**: Initial extraction from smali source code
2. **Second pass**: Independent re-reading of each smali file to confirm register values, field numbers, and constants
Key verifications:
- All 8 BLE UUIDs confirmed from `cg1.smali`
- All 19 module IDs confirmed from `WsModuleId.smali` (ordinals)
- All ~300 WsCmd command IDs confirmed from `WsCmd.smali` (hex → decimal conversions)
- All 8 WsPacket field numbers confirmed from `BaseProto$WsPacket.smali`
- DeviceType IDs confirmed with register tracing (including the gap at deviceId=3)
- BLE command bytes (0-7) confirmed from `j80.smali`
- BLE packet format confirmed from `l80.smali` (header layout, CRC, end marker)
- WebSocket URL and ports confirmed from `v55.smali`
- CRC-16/MODBUS confirmed from `vc0.smali` lookup table

99
01_architecture.md Normal file
View File

@ -0,0 +1,99 @@
# Architecture Overview
## Dual-Channel Design
The DWARFLAB app communicates with DWARF telescopes via **two distinct channels**:
1. **BLE (Bluetooth Low Energy)** — Initial setup, authentication, WiFi configuration
2. **WebSocket (TCP)** — Main telescope control after WiFi connection
Both channels use **Protocol Buffers v3 (proto3)** for serialization, but with different transport framing.
```
┌──────────┐ ┌──────────┐
│ App │ BLE (setup/auth) │ DWARF │
│ (Android)│◄──────────────────►│ Device │
│ │ GATT DAF2/DAF3 │ │
│ │ │ │
│ │ WebSocket (ctrl) │ │
│ │◄──────────────────►│ │
│ │ ws://IP:9900 │ │
└──────────┘ └──────────┘
```
## Protocol Stack
| Layer | BLE | WebSocket |
|-------|-----|-----------|
| Transport | GATT (Bluetooth) | TCP (WiFi) |
| Port | — | 9900 (primary), 4409/4410 (secondary) |
| Encoding | Protobuf + BLE header (9B + CRC16 + 0x0D) | Protobuf inside WsPacket envelope |
| Service UUID | `0000DAF2-...` | — |
| Write Char | `0000DAF3-...` | — |
| Notify Char | `0000DAF4-...` | — |
| Proto version | BleProto | WsPacket v2.3 |
## Module Table
The protocol is organized into 19 modules, each with a base command ID:
| Module ID | Name | Proto | Base cmd ID | Description |
|-----------|------|-------|-------------|-------------|
| 0 | NONE | — | — | No module |
| 1 | CAMERA_TELE | CameraProto | 10000 | Telescope camera (51 commands) |
| 2 | CAMERA_WIDE | CameraProto | 12000 | Wide-angle camera (36 commands) |
| 3 | ASTRO | AstroProto | 11000 | Astronomy features (49 commands) |
| 4 | SYSTEM | SystemProto | 13000 | System settings (11 commands) |
| 5 | RGB_POWER | RGBProto | 13500 | RGB LED, power control (6 commands) |
| 6 | MOTOR | MotorControlProto | 14000 | Stepper motor control (6 commands) |
| 7 | TRACK | TrackProto | 14800 | Equatorial tracking, sentry (13 commands) |
| 8 | FOCUS | FocusProto | 15000 | Autofocus, manual focus (8 commands) |
| 9 | NOTIFY | NotifyProto | 15200 | Device notifications (104 commands) |
| 10 | PANORAMA | PanoramaProto | 15500 | Panorama shooting (14 commands) |
| 11 | ITIPS | ITipsProto | 15700 | In-app tips (1 command) |
| 12 | FACTORY_TEST | — | 15900 | Factory testing (0 commands) |
| 13 | SHOOTING_SCHEDULE | ScheduleProto | 16100 | Scheduled shooting (8 commands) |
| 14 | TASK_CENTER | TaskCenterProto | 16400 | Task management (7 commands) |
| 15 | PARAM | ParamProto | 16700 | Generic parameters (7 commands) |
| 16 | VOICE_ASSISTANT | VoiceAssistantProto | 16800 | Voice commands (1 command) |
| 17 | CAMERA_GUIDE | — | 16900 | Camera guide (0 commands) |
| 18 | DEVICE | DeviceProto | 17000 | Defog, cooling, shutdown (3 commands) |
## Message Types
| Type ID | Name | Direction | Description |
|---------|------|-----------|-------------|
| 0 | request | App → Device | Command request |
| 1 | response | Device → App | Command response |
| 2 | notification | Device → App | Spontaneous notification |
| 3 | reply | Device → App | Acknowledgement |
## Response Codes
- `0` = Success
- `>0` = Error (module/command specific)
## Security
- **BLE password**: 8-63 characters, no spaces. Default: `DWARF_12345678`
- **Same password** is used for both BLE auth and WiFi credential
- **WebSocket**: Unencrypted (`ws://`, not `wss://`)
- **Session magic bytes**: `DWfvuu]`, `4dwf`, `aRdWf`, `DWFq`, `dwFS`, `DwftA`, `DWFL`
## Cloud Infrastructure
| Component | Value |
|-----------|-------|
| Backend | `dwarflab-a7062.appspot.com` (Firebase/Google Cloud) |
| Firebase API Key | `9d5ebf662da7e6515bcb7a7ee28a5fba` |
| S3 Bucket | `dwarf-bucket-02-1251529954` (AWS TransferUtility) |
| Google Client ID | `974715938350-1aeid736pk07h0ru7v3tfmpic624nsr1.apps.googleusercontent.com` |
## DWARF mini Specifics
The DWARF mini (deviceId=4, codename "Bilbo") uses the **same modules and protocol** as other models, with these differences:
- No Panorama Create support (`isSupportPanoramaCreate = false`)
- Max device name length = 15 (vs 21 for DWARF 2, 19 for DWARF 3/4)
- Dedicated EQ page: `indexBilbo.html`
- Some features gated by protocol version (`ProtocolVersion`)

145
02_ble_protocol.md Normal file
View File

@ -0,0 +1,145 @@
# BLE Protocol
## GATT Architecture
The device exposes a single BLE service with multiple characteristics:
| UUID | Type | Role |
|------|------|------|
| `0000180A-0000-1000-8000-00805F9B34FB` | Service | Device Information (standard) |
| `0000DAF2-0000-1000-8000-00805f9b34fb` | Service | **DWARF Primary Service** |
| `0000DAF3-0000-1000-8000-00805f9b34fb` | Characteristic | **Write** — Send protobuf requests |
| `0000DAF4-0000-1000-8000-00805F9B34FB` | Characteristic | **Notify** — Receive protobuf responses |
| `0000DAF5-0000-1000-8000-00805F9B34FB` | Characteristic | **Write** — STA mode configuration |
| `0000DAF6-0000-1000-8000-00805F9B34FB` | Characteristic | **Notify** — STA mode responses |
| `0000DAF7-0000-1000-8000-00805F9B34FB` | Characteristic | **Write** — AP mode configuration |
| `00009999-0000-1000-8000-00805F9B34FB` | Characteristic | **Notify** — AP mode responses |
> **Note**: UUIDs DAF2/DAF3 use lowercase `00805f9b34fb` while DAF4-DAF7/9999 use uppercase `00805F9B34FB`. This is as-is in the source code (`cg1.smali`).
## BLE Packet Format (BluetoothPacket)
All BLE data is framed in a custom packet format before being sent over GATT characteristics.
### Binary Layout
```
Offset Size Field Description
------ ---- ----------------- -------------------------------------------
0 1 magic 0xAA (constant)
1 1 protocolVersion Protocol version (typically 1)
2 1 cmdInstruction Command type (0-7, see below)
3 1 packageSequence Current packet sequence number (0-based)
4 1 totalPackages Total number of packets for this message
5 2 extendedProtocol Extended protocol field (big-endian, usually 0)
7 2 validDataLength Length of protobuf payload (big-endian)
9 N dataPayload Protobuf-encoded BleProto message
9+N 2 crc CRC-16/MODBUS (poly=0x8005, init=0xFFFF, reflected, XOR=0x0000)
11+N 1 endMarker 0x0D (constant)
Total packet size = validDataLength + 12
```
### Pseudocode: Building a BLE Packet
```python
import struct
def build_ble_packet(cmd: int, protobuf_data: bytes, seq: int = 0, total: int = 1) -> bytes:
"""Build a BLE packet from protobuf data."""
header = struct.pack('>BBBH', # big-endian: B=cmd, B=seq, B=total, H=extended
0xAA, # magic byte
1, # protocolVersion
cmd, # cmdInstruction
seq, # packageSequence
total, # totalPackages
0 # extendedProtocol (reserved)
)
# validDataLength
length_bytes = struct.pack('>H', len(protobuf_data))
# CRC over header + length + data
crc_input = header + length_bytes + protobuf_data
crc = crc16_modbus(crc_input)
crc_bytes = struct.pack('>H', crc)
# Assemble: header(7B) + length(2B) + data(NB) + crc(2B) + end(1B)
return header + length_bytes + protobuf_data + crc_bytes + b'\x0D'
```
### Pseudocode: CRC-16/MODBUS
```python
def crc16_modbus(data: bytes) -> int:
"""CRC-16/MODBUS: poly=0x8005, init=0xFFFF, reflected=True, XOR_out=0x0000"""
crc = 0xFFFF
for byte in data:
crc ^= byte
for _ in range(8):
if crc & 0x0001:
crc = (crc >> 1) ^ 0xA001 # reflected poly
else:
crc >>= 1
return crc & 0xFFFF
```
### Fragmentation
When a protobuf message exceeds the BLE MTU, it is split across multiple packets:
- `packageSequence` starts at 0, increments per packet
- `totalPackages` indicates total number of packets for the message
- Each packet contains a fragment of the protobuf payload
- `isLastPacket` = (`packageSequence` == `totalPackages` - 1)
## BLE Commands
| cmdInstruction | Name | Description |
|----------------|------|-------------|
| 0 | Unknown | Reserved |
| 1 | GetWiFiConfig | Authenticate and get device config |
| 2 | SetApMode | Configure device as WiFi hotspot (AP) |
| 3 | SetSTAMode | Configure device to connect to WiFi (STA) |
| 4 | SetNamePwd | Set BLE/WiFi name and password |
| 5 | Reset | Factory reset |
| 6 | GetWiFiList | Scan available WiFi networks |
| 7 | GetDeviceInfo | Get system info (protocol version, MAC, firmware) |
## Authentication Flow
```
App Device
│ │
│ BLE SCAN: discover "DWARF*" │
│ GATT CONNECT to service DAF2 │
│ │
│ ReqGetconfig {blePsd, clientId} │
│ ──── DAF3 (write) ────────────────► │
│ │
│ ResGetconfig {code, ip, ssid, ...} │
│ ◄──── DAF4 (notify) ────────────── │
│ │
│ [Optional] ReqSta/ReqAp │
│ ──── DAF5/DAF7 ───────────────────► │
│ │
│ Connect to ws://<ip>:9900 │
│ │
```
## Connection States
| State | Description |
|-------|-------------|
| Loading | Connecting |
| Success | Connected |
| PwdError | Authentication failed |
| DeviceError | Device error |
| Disconnecting | Disconnecting |
| Disconnected | Disconnected |
## BLE Error Types
| Error | Description |
|-------|-------------|
| BluetoothConnection | BLE connection failure |
| MTU | MTU negotiation failure |
| Communication | Communication error |
| ConfigFailed | Configuration failed |

141
03_websocket_protocol.md Normal file
View File

@ -0,0 +1,141 @@
# WebSocket Protocol
## Connection
After BLE authentication, the app connects via WebSocket for all telescope control.
```
URL: ws://<device_ip>:9900/?client_id=<client_id>
Port: 9900 (primary), 4409/4410 (secondary)
Scheme: ws:// (unencrypted, NOT wss://)
```
The device IP is obtained from `ResGetconfig.ip` (if already on WiFi) or `ResSta.ip` (after STA configuration).
The `client_id` is stored in MMKV under key `"data_default_client_id"`, or generated if not present.
Default device IP: `192.168.88.1`
## WsPacket Format
Every WebSocket message is a serialized `BaseProto.WsPacket` protobuf:
```protobuf
message WsPacket {
int32 majorVersion = 1; // Always 2
int32 minorVersion = 2; // Always 3
int32 deviceId = 3; // Target device ID (see DeviceType)
int32 moduleId = 4; // Module ID (0-18, see module table)
int32 cmd = 5; // Command ID (see WsCmd index)
int32 type = 6; // Message type: 0=request, 1=response, 2=notification, 3=reply
bytes data = 7; // Protobuf-encoded payload for the specific module
string clientId = 8; // App client identifier
}
```
### Pseudocode: Sending a Command
```python
import protobuf
def send_command(websocket, device_id, module_id, cmd, payload_bytes, client_id):
"""Send a command via WebSocket."""
packet = WsPacket(
majorVersion=2,
minorVersion=3,
deviceId=device_id,
moduleId=module_id,
cmd=cmd,
type=0, # request
data=payload_bytes,
clientId=client_id
)
websocket.send(packet.SerializeToString())
def send_track_start(websocket, device_id, client_id, x, y, w, h, cam_id):
"""Example: Start tracking."""
track_req = TrackProto.ReqStartTrack(x=x, y=y, w=w, h=h, camId=cam_id)
send_command(websocket, device_id, module_id=7, cmd=14800,
payload_bytes=track_req.SerializeToString(), client_id=client_id)
```
## Message Types
| type | Name | Description |
|------|------|-------------|
| 0 | request | App → Device command |
| 1 | response | Device → App response to a request |
| 2 | notification | Device → App spontaneous notification |
| 3 | reply | Device → App acknowledgement |
## Keepalive: DwarfPing / DwarfEcho
After WebSocket connection, the app periodically sends `DwarfPing` and the device responds with `DwarfEcho`.
```protobuf
message DwarfPing {
int32 vocaltype = 1; // VT_PING = 1
int64 timestamp = 2; // Unix timestamp
bytes magic = 3; // Session magic bytes
repeated DwarfPing vocals = 4;
repeated NifAP mutes = 5;
}
message DwarfEcho {
int32 vocaltype = 1; // VT_ECHO = 2
int64 timestamp = 2; // Unix timestamp
bytes magic = 3; // Session magic bytes
int64 tsPing = 4; // Echo of the ping timestamp
bytes macAddress = 5; // Device MAC address
BleProto model = 6; // Device model info
string sn = 7; // Serial number
string name = 8; // Device name
string psw = 9; // Password
string fwVersion = 10; // Firmware version
string wsScheme = 11; // WebSocket scheme ("ws")
int32 session = 12; // Session ID
BleProto ap = 13; // AP info
BleProto sta = 14; // STA info
}
```
> **Note**: DwarfEcho contains complete device info (firmware, MAC, SSID, IP, etc.).
## Response Routing
The client uses `WsRequestHandle` to dispatch responses:
1. Parse `WsPacket` from received bytes
2. Extract `cmd` (command ID)
3. Look up registered handlers in a `HashMap<Integer, List>` for this cmd
4. Execute callbacks with `WsPacket.getData()` (deserialized payload)
## Typical Exchange
```
App Device
│ │
│ WsPacket(type=0, moduleId=1, │
│ cmd=10000, data=ReqOpenCamera) │
│ ─────────────────────────────────────► │
│ │
│ WsPacket(type=1, cmd=10000, │
│ data=ComResponse{code=0}) │
│ ◄───────────────────────────────────── │
│ │
│ WsPacket(type=0, moduleId=7, │
│ cmd=14800, data=ReqStartTrack) │
│ ─────────────────────────────────────► │
│ │
│ WsPacket(type=2, cmd=15200, │
│ data=NotifyProto{...}) │
│ ◄───────────────────────────────────── │
│ (spontaneous notification) │
```
## Protocol Version
| Field | Value | Description |
|-------|-------|-------------|
| `WS_MAJOR_VERSION_NUMBER` | 2 | Current major version |
| `WS_MINOR_VERSION_NUMBER` | 3 | Current minor version |

65
04_base_messages.md Normal file
View File

@ -0,0 +1,65 @@
# Base Messages (BaseProto)
## WsPacket — WebSocket Envelope
Every WebSocket message uses this envelope.
| Field | # | Type | Description |
|-------|---|------|-------------|
| `majorVersion` | 1 | int32 | Protocol major version (constant = 2) |
| `minorVersion` | 2 | int32 | Protocol minor version (constant = 3) |
| `deviceId` | 3 | int32 | Target device ID (0=Unknown, 1=DWARF_2, 2=DWARF_3, 4=DWARF_mini, 5=DWARF_4, 6=DWARF_DRAGON) |
| `moduleId` | 4 | int32 | Module ID (0-18, see architecture) |
| `cmd` | 5 | int32 | Command ID (see WsCmd index) |
| `type` | 6 | int32 | Message type: 0=request, 1=response, 2=notification, 3=reply |
| `data` | 7 | bytes | Protobuf-encoded payload for the specific module/command |
| `clientId` | 8 | string | App client identifier |
## CommonParam — Generic Motor Parameters
Used by motor control and movement commands.
| Field | # | Type | Description |
|-------|---|------|-------------|
| `hasAuto` | 1 | bool | Auto mode available |
| `autoMode` | 2 | int32 | Auto mode (0=off, 1=on) |
| `id` | 3 | int32 | Parameter ID |
| `modeIndex` | 4 | int32 | Mode index |
| `index` | 5 | int32 | Current index |
| `continueValue` | 6 | double | Continuation value |
## ComResponse — Standard Response
| Field | # | Type | Description |
|-------|---|------|-------------|
| `code` | 1 | int32 | Status code (0=success, >0=error) |
## ComResWithDouble — Response with Numeric Value
| Field | # | Type | Description |
|-------|---|------|-------------|
| `value` | 1 | double | Response value |
| `code` | 2 | int32 | Status code |
## ComResWithString — Response with String
| Field | # | Type | Description |
|-------|---|------|-------------|
| `str` | 1 | string | Response string |
| `code` | 2 | int32 | Status code |
## Version Enums
### WsMajorVersion
| Value | Name |
|-------|------|
| 0 | WS_MAJOR_VERSION_UNKNOWN |
| 2 | WS_MAJOR_VERSION_NUMBER |
### WsMinorVersion
| Value | Name |
|-------|------|
| 0 | WS_MINOR_VERSION_UNKNOWN |
| 3 | WS_MINOR_VERSION_NUMBER |

228
05_ble_messages.md Normal file
View File

@ -0,0 +1,228 @@
# BLE Messages (BleProto)
All BLE messages are serialized as `BleProto` protobuf, wrapped in the BLE packet format described in [02_ble_protocol.md](02_ble_protocol.md).
## Authentication & Configuration
### ReqGetconfig — Get Device Configuration (cmd=1)
Authenticate and retrieve device WiFi/IP info.
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code: 1 = GetWiFiConfig |
| `blePsd` | 2 | string | BLE password (default: "DWARF_12345678") |
| `clientId` | 3 | string | Client identifier |
### ResGetconfig — Configuration Response
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code |
| `code` | 2 | int32 | Status code (0=success) |
| `state` | 3 | int32 | Device state |
| `wifiMode` | 4 | int32 | WiFi mode (0=off, 1=AP, 2=STA) |
| `apMode` | 5 | int32 | AP mode |
| `autoStart` | 6 | int32 | Auto-start flag |
| `apCountryList` | 7 | int32 | AP country list |
| `ssid` | 8 | string | Current SSID |
| `psd` | 9 | string | WiFi password |
| `ip` | 10 | string | Device IP (for WebSocket) |
| `apCountry` | 11 | string | AP country code |
### ReqGetsysteminfo — Get System Info (cmd=7)
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code: 7 = GetDeviceInfo |
| `clientId` | 2 | string | Client identifier |
### ResGetsysteminfo — System Info Response
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code |
| `code` | 2 | int32 | Status code |
| `protocolVersion` | 3 | int32 | Protocol version |
| `macAddress` | 5 | string | MAC address |
| `device` | 4 | string | Device name |
| `dwarfOtaVersion` | 6 | string | OTA firmware version |
## WiFi Configuration
### ReqSta — Configure Station Mode (cmd=3)
Connect the device to an existing WiFi network.
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code: 3 = SetSTAMode |
| `autoStart` | 2 | int32 | Auto-start flag |
| `blePsd` | 3 | string | BLE password |
| `ssid` | 4 | string | Target SSID |
| `psd` | 5 | string | Target WiFi password |
| `clientId` | 6 | string | Client identifier |
### ResSta — Station Mode Response
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code |
| `code` | 2 | int32 | Status code |
| `ssid` | 3 | string | Connected SSID |
| `psd` | 4 | string | Password |
| `ip` | 5 | string | Obtained IP (for WebSocket) |
### ReqAp — Configure Access Point Mode (cmd=2)
Configure the device as a WiFi hotspot.
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code: 2 = SetApMode |
| `wifiType` | 2 | int32 | WiFi type |
| `autoStart` | 3 | int32 | Auto-start flag |
| `countryList` | 4 | int32 | Country list |
| `country` | 5 | string | Country code |
| `blePsd` | 6 | string | BLE password |
| `clientId` | 7 | string | Client identifier |
| `forceRestart` | 8 | bool | Force restart |
### ResAp — Access Point Response
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code |
| `code` | 2 | int32 | Status code |
| `mode` | 3 | int32 | Mode |
| `ssid` | 4 | string | AP SSID |
| `psd` | 5 | string | AP password |
## Utility Commands
### ReqSetblewifi — Set BLE/WiFi Name & Password (cmd=4)
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code: 4 = SetNamePwd |
| `mode` | 2 | int32 | Mode (0/1) |
| `blePsd` | 3 | string | BLE password |
| `value` | 4 | string | New value |
| `clientId` | 5 | string | Client identifier |
### ReqReset — Factory Reset (cmd=5)
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code: 5 = Reset |
| `clientId` | 2 | string | Client identifier |
### ResReset — Reset Response
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code |
| `code` | 2 | int32 | Status code |
### ReqGetwifilist — Scan WiFi Networks (cmd=6)
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code: 6 = GetWiFiList |
| `clientId` | 2 | string | Client identifier |
### ReqCheckFile — OTA File Check
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code |
| `filePath` | 2 | string | File path |
| `md5` | 3 | string | MD5 checksum |
### ResCheckFile — OTA Check Response
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code |
| `code` | 2 | int32 | Status code |
## Keepalive: DwarfPing / DwarfEcho
### DwarfPing — Heartbeat from App
| Field | # | Type | Description |
|-------|---|------|-------------|
| `vocaltype` | 1 | int32 | Type: 1=VT_PING |
| `timestamp` | 2 | int64 | Unix timestamp |
| `magic` | 3 | bytes | Session magic bytes |
| `vocals` | 4 | repeated DwarfPing | Nested pings |
| `mutes` | 5 | repeated NifAP | AP info list |
### DwarfEcho — Heartbeat Response from Device
| Field | # | Type | Description |
|-------|---|------|-------------|
| `vocaltype` | 1 | int32 | Type: 2=VT_ECHO |
| `timestamp` | 2 | int64 | Unix timestamp |
| `magic` | 3 | bytes | Session magic bytes |
| `tsPing` | 4 | int64 | Echo of ping timestamp |
| `macAddress` | 5 | bytes | Device MAC address |
| `model` | 6 | BleProto | Device model info |
| `sn` | 7 | string | Serial number |
| `name` | 8 | string | Device name |
| `psw` | 9 | string | Password |
| `fwVersion` | 10 | string | Firmware version |
| `wsScheme` | 11 | string | WebSocket scheme ("ws") |
| `session` | 12 | int32 | Session ID |
| `ap` | 13 | BleProto | AP info |
| `sta` | 14 | BleProto | STA info |
## Network Info Messages
### NifAP — Access Point Info
| Field | # | Type | Description |
|-------|---|------|-------------|
| `ifname` | 1 | string | Interface name |
| `mode` | 2 | int32 | AP mode |
| `countryCode` | 3 | string | Country code |
| `ssid` | 4 | string | SSID |
| `sec` | 5 | string | Security type |
| `psw` | 6 | string | Password |
| `ipv4` | 7 | bytes | IPv4 address |
| `ipv6` | 8 | bytes | IPv6 address |
### NifSTA — Station Info
| Field | # | Type | Description |
|-------|---|------|-------------|
| `ifname` | 1 | string | Interface name |
| `ssid` | 2 | string | Connected SSID |
| `psw` | 3 | string | Password |
| `rssi` | 4 | int32 | Signal strength |
| `ipv4` | 5 | bytes | IPv4 address |
| `ipv6` | 6 | bytes | IPv6 address |
## Common Messages
### ResCommon — Generic Response
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code |
| `code` | 2 | int32 | Status code |
### ResReceiveDataError — Receive Error
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cmd` | 1 | int32 | Command code |
| `code` | 2 | int32 | Error code |
### VocalType — Enum
| Value | Name | Description |
|-------|------|-------------|
| 0 | VT_UNKNOWN | Unknown |
| 1 | VT_PING | Ping (app → device) |
| 2 | VT_ECHO | Echo (device → app) |

150
06_camera_commands.md Normal file
View File

@ -0,0 +1,150 @@
# Camera Commands (CameraProto)
Module **CAMERA_TELE** (ID=1) and **CAMERA_WIDE** (ID=2) share the same message types but use different command ID ranges.
## Camera Types
| CameraType | camId | Description |
|------------|-------|-------------|
| Tele | 0 | Telescope camera (primary) |
| Wide | 1 | Wide-angle camera |
| General | 15 | Generic camera |
## TELE Commands (Module 1, base 10000)
| ID | Command | Description |
|----|---------|-------------|
| 10000 | OPEN_CAMERA | Open camera |
| 10001 | CLOSE_CAMERA | Close camera |
| 10002 | PHOTOGRAPH | Take photo |
| 10003 | BURST | Start burst capture |
| 10004 | STOP_BURST | Stop burst |
| 10005 | START_RECORD | Start video recording |
| 10006 | STOP_RECORD | Stop recording |
| 10007 | SET_EXP_MODE | Set exposure mode |
| 10008 | GET_EXP_MODE | Get exposure mode |
| 10009 | SET_EXP | Set exposure value |
| 10010 | GET_EXP | Get exposure value |
| 10011 | SET_GAIN_MODE | Set gain mode |
| 10012 | GET_GAIN_MODE | Get gain mode |
| 10013 | SET_GAIN | Set gain value |
| 10014 | GET_GAIN | Get gain value |
| 10015 | SET_BRIGHTNESS | Set brightness |
| 10016 | GET_BRIGHTNESS | Get brightness |
| 10017 | SET_CONTRAST | Set contrast |
| 10018 | GET_CONTRAST | Get contrast |
| 10019 | SET_SATURATION | Set saturation |
| 10020 | GET_SATURATION | Get saturation |
| 10021 | SET_HUE | Set hue |
| 10022 | GET_HUE | Get hue |
| 10023 | SET_SHARPNESS | Set sharpness |
| 10024 | GET_SHARPNESS | Get sharpness |
| 10025 | SET_WB_MODE | Set white balance mode |
| 10026 | GET_WB_MODE | Get white balance mode |
| 10027 | SET_WB_SCENE | Set WB scene |
| 10028 | GET_WB_SCENE | Get WB scene |
| 10029 | SET_WB_CT | Set WB color temperature |
| 10030 | GET_WB_CT | Get WB color temperature |
| 10031 | SET_IRCUT | Set IR-cut filter |
| 10032 | GET_IRCUT | Get IR-cut filter |
| 10033 | START_TIMELAPSE_PHOTO | Start timelapse |
| 10034 | STOP_TIMELAPSE_PHOTO | Stop timelapse |
| 10035 | SET_ALL_PARAMS | Set all parameters |
| 10036 | GET_ALL_PARAMS | Get all parameters |
| 10037 | SET_FEATURE_PARAM | Set feature parameter |
| 10038 | GET_ALL_FEATURE_PARAMS | Get all feature parameters |
| 10039 | GET_SYSTEM_WORKING_STATE | Get system working state |
| 10040 | SET_JPG_QUALITY | Set JPG quality |
| 10041 | PHOTO_RAW | Take RAW photo |
| 10042 | SET_RTSP_BITRATE_TYPE | Set RTSP bitrate |
| 10043 | DISABLE_ALL_ISP_PROCESSING | Disable all ISP |
| 10044 | ENABLE_ALL_ISP_PROCESSING | Enable all ISP |
| 10045 | SET_ISP_MODULE_STATE | Set ISP module state |
| 10046 | GET_ISP_MODULE_STATE | Get ISP module state |
| 10047 | SWITCH_RESOLUTION | Switch resolution |
| 10048 | SWITCH_FRAMERATE | Switch framerate |
| 10049 | SWITCH_CROP_RATIO | Switch crop ratio |
| 10050 | SET_PREVIEW_QUALITY | Set preview quality |
## WIDE Commands (Module 2, base 12000)
| ID | Command | Description |
|----|---------|-------------|
| 12000 | OPEN_CAMERA | Open camera |
| 12001 | CLOSE_CAMERA | Close camera |
| 12002 | SET_EXP_MODE | Set exposure mode |
| 12003 | GET_EXP_MODE | Get exposure mode |
| 12004 | SET_EXP | Set exposure value |
| 12005 | GET_EXP | Get exposure value |
| 12006 | SET_GAIN | Set gain value |
| 12007 | GET_GAIN | Get gain value |
| 12008 | SET_BRIGHTNESS | Set brightness |
| 12009 | GET_BRIGHTNESS | Get brightness |
| 12010 | SET_CONTRAST | Set contrast |
| 12011 | GET_CONTRAST | Get contrast |
| 12012 | SET_SATURATION | Set saturation |
| 12013 | GET_SATURATION | Get saturation |
| 12014 | SET_HUE | Set hue |
| 12015 | GET_HUE | Get hue |
| 12016 | SET_SHARPNESS | Set sharpness |
| 12017 | GET_SHARPNESS | Get sharpness |
| 12018 | SET_WB_MODE | Set white balance mode |
| 12019 | GET_WB_MODE | Get white balance mode |
| 12020 | SET_WB_CT | Set WB color temperature |
| 12021 | GET_WB_CT | Get WB color temperature |
| 12022 | PHOTOGRAPH | Take photo |
| 12023 | BURST | Start burst |
| 12024 | STOP_BURST | Stop burst |
| 12025 | START_TIMELAPSE_PHOTO | Start timelapse |
| 12026 | STOP_TIMELAPSE_PHOTO | Stop timelapse |
| 12027 | GET_ALL_PARAMS | Get all parameters |
| 12028 | SET_ALL_PARAMS | Set all parameters |
| 12029 | PHOTO_RAW | Take RAW photo |
| 12030 | START_RECORD | Start recording |
| 12031 | STOP_RECORD | Stop recording |
| 12032 | SET_RTSP_BITRATE_TYPE | Set RTSP bitrate |
| 12035 | SET_WB_SCENE | Set WB scene |
| 12036 | SET_PREVIEW_QUALITY | Set preview quality |
> **Note**: WIDE has gaps at 12033-12034 (not assigned).
## Key Message Definitions
### ReqOpenCamera
| Field | # | Type | Description |
|-------|---|------|-------------|
| `binning` | 1 | bool | Enable binning mode |
| `rtspEncodeType` | 2 | int32 | RTSP encoding type |
### ReqSetAllParams / ReqGetAllParams
| Field | # | Type | Description |
|-------|---|------|-------------|
| `expMode` | 1 | int32 | Exposure mode |
| `expIndex` | 2 | int32 | Exposure index |
| `gainMode` | 3 | int32 | Gain mode |
| `gainIndex` | 4 | int32 | Gain index |
| `ircutValue` | 5 | int32 | IR-cut value |
| `wbMode` | 6 | int32 | White balance mode |
| `wbIndexType` | 7 | int32 | WB index type |
| `wbIndex` | 8 | int32 | WB index |
| `brightness` | 9 | int32 | Brightness |
| `contrast` | 10 | int32 | Contrast |
| `hue` | 11 | int32 | Hue |
| `saturation` | 12 | int32 | Saturation |
| `sharpness` | 13 | int32 | Sharpness |
| `jpgQuality` | 14 | int32 | JPG quality |
### IspModuleState
| Field | # | Type | Description |
|-------|---|------|-------------|
| `moduleId` | 1 | int32 | ISP module ID |
| `state` | 2 | bool | Module state (on/off) |
### ReqBurstPhoto
| Field | # | Type | Description |
|-------|---|------|-------------|
| `count` | 1 | int32 | Number of burst frames |

186
07_astro_commands.md Normal file
View File

@ -0,0 +1,186 @@
# Astro Commands (AstroProto)
Module **ASTRO** (ID=3), base command ID = 11000.
## Goto (Pointing)
### ReqGotoDSO
| Field | # | Type | Description |
|-------|---|------|-------------|
| `ra` | 1 | double | Right ascension (degrees) |
| `dec` | 2 | double | Declination (degrees) |
| `targetName` | 3 | string | Target name |
| `gotoOnly` | 4 | bool | Goto only (no tracking) |
### ReqGotoSolarSystem
| Field | # | Type | Description |
|-------|---|------|-------------|
| `index` | 1 | int32 | Planet index |
| `lon` | 2 | double | Longitude |
| `lat` | 3 | double | Latitude |
| `targetName` | 4 | string | Target name |
| `forceStart` | 5 | bool | Force start |
### ReqOneClickGotoDSO
| Field | # | Type | Description |
|-------|---|------|-------------|
| `ra` | 1 | double | Right ascension |
| `dec` | 2 | double | Declination |
| `targetName` | 3 | string | Target name |
| `lon` | 4 | double | Longitude |
| `lat` | 5 | double | Latitude |
| `shootingMode` | 6 | int32 | Shooting mode |
| `gotoOnly` | 7 | bool | Goto only |
### ReqOneClickGotoSolarSystem
| Field | # | Type | Description |
|-------|---|------|-------------|
| `index` | 1 | int32 | Planet index |
| `lon` | 2 | double | Longitude |
| `lat` | 3 | double | Latitude |
| `targetName` | 4 | string | Target name |
| `forceStart` | 5 | bool | Force start |
| `shootingMode` | 6 | int32 | Shooting mode |
## Live Stacking
### ReqCaptureRawLiveStacking
| Field | # | Type | Description |
|-------|---|------|-------------|
| `irIndex` | 1 | int32 | IR index |
| `forceStart` | 2 | bool | Force start |
### ReqCaptureWideRawLiveStacking
| Field | # | Type | Description |
|-------|---|------|-------------|
| `forceStart` | 1 | bool | Force start |
### No-field commands: ReqFastStopCaptureRawLiveStacking, ReqStopCaptureRawLiveStacking, ReqFastStopCaptureWideRawLiveStacking, ReqStopCaptureWideRawLiveStacking
## Dark Frames & Calibration
### ReqCaptureDarkFrame
| Field | # | Type | Description |
|-------|---|------|-------------|
| `reshoot` | 1 | int32 | Reshoot flag |
### ReqCaptureDarkFrameWithParam
| Field | # | Type | Description |
|-------|---|------|-------------|
| `expIndex` | 1 | int32 | Exposure index |
| `gainIndex` | 2 | int32 | Gain index |
| `binIndex` | 3 | int32 | Binning index |
| `capSize` | 4 | int32 | Capture size |
### ReqDelDarkFrame
| Field | # | Type | Description |
|-------|---|------|-------------|
| `expIndex` | 1 | int32 | Exposure index |
| `gainIndex` | 2 | int32 | Gain index |
| `binIndex` | 3 | int32 | Binning index |
| `tempValue` | 4 | int32 | Temperature value |
### ReqCaptureCaliFrame
| Field | # | Type | Description |
|-------|---|------|-------------|
| `expIndex` | 1 | int32 | Exposure index |
| `gain` | 2 | int32 | Gain |
| `resolution` | 3 | int32 | Resolution |
| `capSize` | 4 | int32 | Capture size |
| `cameraType` | 5 | int32 | Camera type |
| `caliFrameType` | 6 | int32 | Calibration frame type |
| `filterType` | 7 | int32 | Filter type |
| `sceneType` | 8 | int32 | Scene type |
## EQ Solving & Other
### ReqStartEqSolving, ReqStopEqSolving, ReqStartSkyTargetFinder, ReqStopSkyTargetFinder — No fields
### ReqStartAiEnhance, ReqStartCalibration, ReqStartRepostprocess
| Field | # | Type | Description |
|-------|---|------|-------------|
| `resultDir` | 1 | string | Result directory |
### ReqIsImageStackable
| Field | # | Type | Description |
|-------|---|------|-------------|
| `srcDirs` | 1 | repeated string | Source directories |
### ReqGetAstroShootingTime
| Field | # | Type | Description |
|-------|---|------|-------------|
| `expIndex` | 1 | int32 | Exposure index |
| `horizontalScale` | 2 | int32 | Horizontal scale |
| `verticalScale` | 3 | int32 | Vertical scale |
| `rotation` | 4 | int32 | Rotation |
| `camId` | 5 | int32 | Camera ID |
| `shootingMode` | 6 | int32 | Shooting mode |
### No-field commands: ReqStartMosaic, ReqGoLive, ReqOneClickShooting
## Command IDs (Module ASTRO, base 11000)
| ID | Command |
|----|---------|
| 11000 | START_CALIBRATION |
| 11001 | STOP_CALIBRATION |
| 11002 | START_GOTO_DSO |
| 11003 | START_GOTO_SOLAR_SYSTEM |
| 11004 | STOP_GOTO |
| 11005 | START_CAPTURE_RAW_LIVE_STACKING |
| 11006 | STOP_CAPTURE_RAW_LIVE_STACKING |
| 11007 | START_CAPTURE_RAW_DARK |
| 11008 | STOP_CAPTURE_RAW_DARK |
| 11009 | CHECK_GOT_DARK |
| 11010 | GO_LIVE |
| 11011 | START_TRACK_SPECIAL_TARGET |
| 11012 | STOP_TRACK_SPECIAL_TARGET |
| 11013 | START_ONE_CLICK_GOTO_DSO |
| 11014 | START_ONE_CLICK_GOTO_SOLAR_SYSTEM |
| 11015 | STOP_ONE_CLICK_GOTO |
| 11016 | START_WIDE_CAPTURE_LIVE_STACKING |
| 11017 | STOP_WIDE_CAPTURE_LIVE_STACKING |
| 11018 | START_EQ_SOLVING |
| 11019 | STOP_EQ_SOLVING |
| 11020 | WIDE_GO_LIVE |
| 11021 | START_CAPTURE_RAW_DARK_WITH_PARAM |
| 11022 | STOP_CAPTURE_RAW_DARK_WITH_PARAM |
| 11023 | GET_DARK_FRAME_LIST |
| 11024 | DEL_DARK_FRAME_LIST |
| 11025 | START_CAPTURE_WIDE_RAW_DARK_WITH_PARAM |
| 11026 | STOP_CAPTURE_WIDE_RAW_DARK_WITH_PARAM |
| 11027 | GET_WIDE_DARK_FRAME_LIST |
| 11028 | DEL_WIDE_DARK_FRAME_LIST |
| 11029 | START_AI_ENHANCE |
| 11030 | STOP_AI_ENHANCE |
| 11031 | START_TELE_MOSAIC |
| 11032 | CHECK_IF_RESTACKABLE |
| 11033 | START_MAKE_FITS_THUMB |
| 11034 | STOP_MAKE_FITS_THUMB |
| 11035 | START_RESTACKED |
| 11036 | STOP_RESTACKED |
| 11037 | FAST_STOP_CAPTURE_RAW_LIVE_STACKING |
| 11038 | FAST_STOP_WIDE_CAPTURE_LIVE_STACKING |
| 11039 | GET_ASTRO_SHOOTING_TIME |
| 11040 | GET_QUICK_SET_LIST |
| 11041 | SET_QUICK_SET |
| 11042 | START_ONE_CLICK_SHOOTING |
| 11043 | GET_CALI_FRAME_LIST |
| 11044 | DEL_CALI_FRAME_LIST |
| 11045 | START_CAPTURE_CALI_FRAME |
| 11046 | STOP_CAPTURE_CALI_FRAME |
| 11047 | START_SKY_TARGET_FINDER |
| 11048 | STOP_SKY_TARGET_FINDER |

View File

@ -0,0 +1,237 @@
# Motor, Focus & Track Commands
## MotorControlProto — Module MOTOR (ID=6, base 14000)
### ReqMotorRun — Run Motor
| Field | # | Type | Description |
|-------|---|------|-------------|
| `id` | 1 | int32 | Motor ID |
| `speed` | 2 | int32 | Speed |
| `direction` | 3 | int32 | Direction |
| `speedRamping` | 4 | bool | Speed ramping enabled |
| `resolutionLevel` | 5 | int32 | Resolution level |
### ReqMotorStop — Stop Motor
| Field | # | Type | Description |
|-------|---|------|-------------|
| `id` | 1 | int32 | Motor ID |
### ReqMotorRunTo — Move to Position
| Field | # | Type | Description |
|-------|---|------|-------------|
| `id` | 1 | int32 | Motor ID |
| `endPosition` | 2 | double | Target position |
| `speed` | 3 | int32 | Speed |
| `speedRamping` | 4 | bool | Speed ramping |
| `resolutionLevel` | 5 | int32 | Resolution level |
### ReqMotorRunInPulse — Pulse Mode
| Field | # | Type | Description |
|-------|---|------|-------------|
| `id` | 1 | int32 | Motor ID |
| `frequency` | 2 | int32 | Frequency |
| `direction` | 3 | int32 | Direction |
| `speedRamping` | 4 | bool | Speed ramping |
| `resolution` | 5 | int32 | Resolution |
| `pulse` | 6 | int32 | Pulse count |
| `mode` | 7 | int32 | Mode |
### ReqMotorChangeSpeed — Change Speed
| Field | # | Type | Description |
|-------|---|------|-------------|
| `id` | 1 | int32 | Motor ID |
| `speed` | 2 | int32 | New speed |
### ReqMotorChangeDirection — Change Direction
| Field | # | Type | Description |
|-------|---|------|-------------|
| `id` | 1 | int32 | Motor ID |
| `direction` | 2 | int32 | New direction |
### ReqMotorReset — Reset Motor
| Field | # | Type | Description |
|-------|---|------|-------------|
| `id` | 1 | int32 | Motor ID |
| `direction` | 2 | int32 | Reset direction |
### ReqMotorGetPosition — Get Position
| Field | # | Type | Description |
|-------|---|------|-------------|
| `id` | 1 | int32 | Motor ID |
### ReqMotorServiceJoystick — Joystick Control
| Field | # | Type | Description |
|-------|---|------|-------------|
| `vectorAngle` | 1 | int32 | Joystick angle |
| `vectorLength` | 2 | int32 | Joystick magnitude |
### ReqMotorServiceJoystickFixedAngle — Fixed-Angle Joystick
| Field | # | Type | Description |
|-------|---|------|-------------|
| `vectorAngle` | 1 | int32 | Angle |
| `vectorLength` | 2 | int32 | Magnitude |
### ReqMotorServiceJoystickStop — Stop Joystick (no fields)
### ReqDualCameraLinkage — Dual Camera Linkage
| Field | # | Type | Description |
|-------|---|------|-------------|
| `x` | 1 | int32 | X position |
| `y` | 2 | int32 | Y position |
### Responses
- **ResMotor**: `id` (int32, #1) + `code` (int32, #2)
- **ResMotorPosition**: `id` (int32, #1) + `code` (int32, #2) + `position` (double, #3)
### Command IDs
| ID | Command |
|----|---------|
| 14000 | STEP_MOTOR_RUN |
| 14002 | STEP_MOTOR_STOP |
| 14006 | STEP_MOTOR_SERVICE_JOYSTICK |
| 14007 | STEP_MOTOR_SERVICE_JOYSTICK_FIXED_ANGLE |
| 14008 | STEP_MOTOR_SERVICE_JOYSTICK_STOP |
| 14009 | STEP_MOTOR_SERVICE_DUAL_CAMERA_LINKAGE |
> **Note**: IDs 14001, 14003-14005 are not assigned.
---
## FocusProto — Module FOCUS (ID=8, base 15000)
### ReqAstroAutoFocus — Astro Autofocus
| Field | # | Type | Description |
|-------|---|------|-------------|
| `mode` | 1 | int32 | Focus mode |
### ReqStopAstroAutoFocus — No fields
### ReqNormalAutoFocus — Normal Autofocus
| Field | # | Type | Description |
|-------|---|------|-------------|
| `mode` | 1 | int32 | Focus mode |
| `centerX` | 2 | int32 | Focus center X |
| `centerY` | 3 | int32 | Focus center Y |
### ReqManualSingleStepFocus — Step Focus
| Field | # | Type | Description |
|-------|---|------|-------------|
| `direction` | 1 | int32 | Direction |
### ReqManualContinuFocus — Continuous Focus
| Field | # | Type | Description |
|-------|---|------|-------------|
| `direction` | 1 | int32 | Direction |
### ReqStopManualContinuFocus — No fields
### ReqGetUserInfinityPos — No fields
### ReqSetUserInfinityPos
| Field | # | Type | Description |
|-------|---|------|-------------|
| `pos` | 1 | int32 | Infinity position |
### ResUserInfinityPos
| Field | # | Type | Description |
|-------|---|------|-------------|
| `code` | 1 | int32 | Status code |
| `pos` | 2 | int32 | Position |
### Command IDs
| ID | Command |
|----|---------|
| 15000 | FOCUS_AUTO_FOCUS |
| 15001 | FOCUS_MANUAL_SINGLE_STEP_FOCUS |
| 15002 | FOCUS_START_MANUAL_CONTINU_FOCUS |
| 15003 | FOCUS_STOP_MANUAL_CONTINU_FOCUS |
| 15004 | FOCUS_START_ASTRO_AUTO_FOCUS |
| 15005 | FOCUS_STOP_ASTRO_AUTO_FOCUS |
| 15011 | FOCUS_GET_USER_INFINITY_POS |
| 15012 | FOCUS_SET_USER_INFINITY_POS |
> **Note**: IDs 15006-15010 are not assigned.
---
## TrackProto — Module TRACK (ID=7, base 14800)
### ReqStartTrack — Start Tracking
| Field | # | Type | Description |
|-------|---|------|-------------|
| `x` | 1 | int32 | X position |
| `y` | 2 | int32 | Y position |
| `w` | 3 | int32 | Width |
| `h` | 4 | int32 | Height |
| `camId` | 5 | int32 | Camera ID |
### ReqStartTrackClick — Click Tracking
| Field | # | Type | Description |
|-------|---|------|-------------|
| `x` | 1 | int32 | X position |
| `y` | 2 | int32 | Y position |
| `camId` | 3 | int32 | Camera ID |
### ReqStopTrack, ReqContinueTrack — No fields
### ReqMOTTrackOne — MOT Track One Target
| Field | # | Type | Description |
|-------|---|------|-------------|
| `id` | 1 | int32 | Target ID |
### ReqStartSentryMode — Start Sentry
| Field | # | Type | Description |
|-------|---|------|-------------|
| `type` | 1 | int32 | Sentry type |
### ReqStopSentryMode — No fields
### ReqUFOAutoHandMode — UFO Auto/Manual Mode
| Field | # | Type | Description |
|-------|---|------|-------------|
| `mode` | 1 | int32 | Mode (auto/manual) |
### Command IDs
| ID | Command |
|----|---------|
| 14800 | TRACK_START_TRACK |
| 14801 | TRACK_STOP_TRACK |
| 14802 | SENTRY_MODE_START |
| 14803 | SENTRY_MODE_STOP |
| 14804 | MOT_START |
| 14805 | MOT_TRACK_ONE |
| 14806 | UFOTRACK_MODE_START |
| 14807 | UFOTRACK_MODE_STOP |
| 14808 | MOT_WIDE_TRACK_ONE |
| 14809 | SWITCH_MAIN_PREVIEW |
| 14810 | UFO_HAND_AOTO_MODE |
| 14811 | SENTRY_SCENE_SELECT |
| 14812 | TRACK_START_CLICK |
> **Note**: `CMD_UFO_HAND_AOTO_MODE` — the "AOTO" spelling is as-is in the source code (typo for "AUTO").

44
09_device_rgb_commands.md Normal file
View File

@ -0,0 +1,44 @@
# Device & RGB Commands
## DeviceProto — Module DEVICE (ID=18, base 17000)
### ReqLensDefog — Lens Defogging
| Field | # | Type | Description |
|-------|---|------|-------------|
| `state` | 1 | int32 | State (0=off, 1=on) |
### ReqAutoCooling — Auto Cooling
| Field | # | Type | Description |
|-------|---|------|-------------|
| `state` | 1 | int32 | State (0=off, 1=on) |
### ReqAutoShutdown — Auto Shutdown
| Field | # | Type | Description |
|-------|---|------|-------------|
| `state` | 1 | int32 | State (0=off, 1=on) |
### Command IDs
| ID | Command |
|----|---------|
| 17000 | DEVICE_LENS_DEFOG |
| 17001 | DEVICE_AUTO_COOLING |
| 17002 | DEVICE_AUTO_SHUTDOWN |
---
## RGBProto — Module RGB_POWER (ID=5, base 13500)
All RGB_POWER commands have no fields (empty messages).
| ID | Command | Description |
|----|---------|-------------|
| 13500 | OPEN_RGB | Turn on RGB LED |
| 13501 | CLOSE_RGB | Turn off RGB LED |
| 13502 | POWER_DOWN | Power off device |
| 13503 | POWERIND_ON | Turn on power indicator |
| 13504 | POWERIND_OFF | Turn off power indicator |
| 13505 | REBOOT | Reboot device |

View File

@ -0,0 +1,207 @@
# System, Param, ITips & VoiceAssistant Commands
## SystemProto — Module SYSTEM (ID=4, base 13000)
### ReqSetTime
| Field | # | Type | Description |
|-------|---|------|-------------|
| `timestamp` | 1 | int64 | Unix timestamp |
| `timezoneOffset` | 2 | double | Timezone offset (hours) |
### ReqSetTimezone
| Field | # | Type | Description |
|-------|---|------|-------------|
| `timezone` | 1 | string | Timezone (e.g. "Europe/Paris") |
### ReqSetMtpMode / ReqSetCpuMode
| Field | # | Type | Description |
|-------|---|------|-------------|
| `mode` | 1 | int32 | Mode value |
### ReqsetMasterLock
| Field | # | Type | Description |
|-------|---|------|-------------|
| `lock` | 1 | bool | Lock state |
### ReqSetLocation
| Field | # | Type | Description |
|-------|---|------|-------------|
| `latitude` | 1 | double | Latitude |
| `longitude` | 2 | double | Longitude |
| `altitude` | 3 | double | Altitude |
| `countryRegion` | 4 | string | Country/region |
| `province` | 5 | string | Province |
| `city` | 6 | string | City |
| `district` | 7 | string | District |
| `enable` | 8 | bool | Enabled |
### ReqGetDeviceActivateInfo / ReqDeviceActivateWriteFile / ReqDeviceActivateSuccessfull / ReqDisableDeviceActivate
| Field | # | Type | Description |
|-------|---|------|-------------|
| `issuer` | 1 | int32 | (GetDeviceActivateInfo only) |
| `requestParam` | 1 | string | (others) |
### Command IDs
| ID | Command |
|----|---------|
| 13000 | SET_TIME |
| 13001 | SET_TIME_ZONE |
| 13002 | SET_MTP_MODE |
| 13003 | SET_CPU_MODE |
| 13004 | SET_MASTER |
| 13005 | GET_DEVICE_ACTIVATE_INFO |
| 13006 | DEVICE_ACTIVATE_WRITE_FILE |
| 13007 | DEVICE_ACTIVATE_NOTIFY_ACTIVATE_SUCCESSFULL |
| 13008 | FACTORY_TEST_UN_ACTIVATE |
| 13009 | SET_LOW_TEMP_PROTECTION_MODE |
| 13010 | SET_LOCATION |
---
## ParamProto — Module PARAM (ID=15, base 16700)
### ReqSetAutoParam
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cameraType` | 1 | int32 | Camera type |
| `shootingTech` | 2 | int32 | Shooting technique |
| `isAuto` | 3 | bool | Auto mode |
### ReqSetExposure / ReqSetGain / ReqSetWb
| Field | # | Type | Description |
|-------|---|------|-------------|
| `paramId` | 1 | int64 | Parameter ID |
| `mode` | 2 | int32 | Mode |
| `value` | 3 | int32 | Value |
### ReqSetGeneralBoolParams
| Field | # | Type | Description |
|-------|---|------|-------------|
| `paramId` | 1 | int64 | Parameter ID |
| `value` | 2 | bool | Boolean value |
### ReqSetGeneralIntParam
| Field | # | Type | Description |
|-------|---|------|-------------|
| `paramId` | 1 | int64 | Parameter ID |
| `value` | 2 | int32 | Integer value |
### ReqSetGeneralFloatParam
| Field | # | Type | Description |
|-------|---|------|-------------|
| `paramId` | 1 | int64 | Parameter ID |
| `value` | 2 | float | Float value |
### ResSetAutoParam
| Field | # | Type | Description |
|-------|---|------|-------------|
| `shootingMode` | 1 | int32 | Shooting mode |
| `cameraType` | 2 | int32 | Camera type |
| `shootingTech` | 3 | int32 | Technique |
| `isAuto` | 4 | bool | Auto enabled |
| `updateAll` | 5 | bool | Update all |
| `code` | 6 | int32 | Status code |
### Command IDs
| ID | Command |
|----|---------|
| 16700 | PARAM_SET_EXPOSURE |
| 16701 | PARAM_SET_GAIN |
| 16702 | PARAM_SET_WB |
| 16703 | PARAM_SET_GENERAL_BOOL_PARAMS |
| 16704 | PARAM_SET_GENERAL_INT_PARAM |
| 16705 | PARAM_SET_GENERAL_FLOAT_PARAM |
| 16706 | PARAM_SET_AUTO_PARAMS |
---
## ITipsProto — Module ITIPS (ID=11, base 15700)
### ReqITipsGet
| Field | # | Type | Description |
|-------|---|------|-------------|
| `mode` | 1 | int32 | Mode |
### ResITipsGet
| Field | # | Type | Description |
|-------|---|------|-------------|
| `mode` | 1 | int32 | Mode |
| `itipsCode` | 2 | string | Tip code |
| `code` | 3 | int32 | Status code |
### Command IDs
| ID | Command |
|----|---------|
| 15700 | ITIPS_GET |
---
## VoiceAssistantProto — Module VOICE_ASSISTANT (ID=16, base 16800)
### ReqVoiceCommand
| Field | # | Type | Description |
|-------|---|------|-------------|
| `commandType` | 1 | int32 | Voice command type (see enum) |
| `shootingMode` | 2 | int32 | Shooting mode |
| `params` | 14 | oneof | Specific parameters |
### VoiceCommandType Enum
| Value | Name | Description |
|-------|------|-------------|
| 0 | VOICE_CMD_UNKNOWN | Unknown |
| 1 | VOICE_CMD_TAKE_PHOTO | Take photo |
| 2 | VOICE_CMD_START_RECORD | Start recording |
| 3 | VOICE_CMD_STOP_RECORD | Stop recording |
| 4 | VOICE_CMD_START_BURST | Start burst |
| 5 | VOICE_CMD_STOP_BURST | Stop burst |
| 6 | VOICE_CMD_START_TIMELAPSE | Start timelapse |
| 7 | VOICE_CMD_STOP_TIMELAPSE | Stop timelapse |
| 8 | VOICE_CMD_START_ASTRO | Start astro |
| 9 | VOICE_CMD_STOP_ASTRO | Stop astro |
| 10 | VOICE_CMD_GOTO_TARGET | Goto target |
| 11 | VOICE_CMD_AUTO_FOCUS | Autofocus |
| 12 | VOICE_CMD_STOP_FOCUS | Stop focus |
| 13 | VOICE_CMD_START_SENTRY | Start sentry |
| 14 | VOICE_CMD_STOP_SENTRY | Stop sentry |
| 15 | VOICE_CMD_CALIBRATION | Calibrate |
| 16 | VOICE_CMD_MOVE | Move |
| 17 | VOICE_CMD_GET_STATUS | Get status |
| 18 | VOICE_CMD_STOP_ALL | Stop all |
### Voice Parameter Messages
- **VoiceGotoParams**: `targetName`, `ra`, `dec`, `index`, `lon`, `lat`, `shootingMode`
- **VoiceAstroParams**: `targetName`, `ra`, `dec`, `index`, `lon`, `lat`, `autoGoto`, `forceStart`
- **VoiceBurstParams**: `cameraType`, `count`
- **VoicePhotoParams**: `cameraType`
- **VoiceRecordParams**: `cameraType`, `durationSeconds`
- **VoiceTimelapseParams**: `cameraType`, `intervalSeconds`, `durationSeconds`
- **VoiceFocusParams**: `isInfinity`
- **VoiceCalibrationParams**: `lon`, `lat`
- **VoiceMoveParams**: `azimuthAngle`, `altitudeAngle`, `speed`
- **VoiceSentryParams**: `type`
### Command IDs
| ID | Command |
|----|---------|
| 16800 | VOICE_ASSISTANT_TASK |

View File

@ -0,0 +1,220 @@
# TaskCenter, Notify, Panorama & Schedule Commands
## TaskCenterProto — Module TASK_CENTER (ID=14, base 16400)
### ReqStartTask
| Field | # | Type | Description |
|-------|---|------|-------------|
| `clientParams` | 1 | ClientParams | Client parameters |
### ClientParams
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cameraType` | 1 | int32 | Camera type |
| `shootingMode` | 2 | int32 | Shooting mode |
| `shootingTech` | 3 | int32 | Shooting technique |
### ReqStopTask — No fields
### ReqEnterCamera — No fields
### ReqSwitchShootingMode / ReqSwitchShootingTech
| Field | # | Type | Description |
|-------|---|------|-------------|
| `cameraType` | 1 | int32 | Camera type |
| `shootingMode` | 2 | int32 | Mode/technique |
### ReqGetDeviceStateInfo — No fields
### Responses
- **DeviceStateInfo**: state, progress, etc.
- **TaskState**: task state info
- **TaskAttr**: task attributes
### Command IDs
| ID | Command |
|----|---------|
| 16400 | GLOBAL_TASK_MANAGER_START_TASK |
| 16401 | GLOBAL_TASK_MANAGER_STOP_TASK |
| 16402 | GLOBAL_TASK_MANAGER_SWITCH_SHOOTING_MODE |
| 16403 | GLOBAL_TASK_MANAGER_SWITCH_SHOOTING_TECH |
| 16404 | GLOBAL_TASK_MANAGER_ENTER_CAMERA |
| 16405 | GLOBAL_TASK_GET_DEVICE_STATE_INFO |
| 16406 | GLOBAL_VOICE_ASSISTANT_TASK |
---
## NotifyProto — Module NOTIFY (ID=9, base 15200)
NotifyProto contains ~104 notification command types sent from device to app (type=2 in WsPacket). These are **asynchronous notifications** — the app registers handlers for specific cmd IDs.
### Notification Categories
| Category | Example Commands |
|----------|-----------------|
| Device State | AUTO_COOLING (15202), AUTO_SHUTDOWN (15203), LENS_DEFOG (15301), BATTERY_INFO, CHARGING_STATE, CPU_MODE (15227) |
| Camera | TELE_SET_PARAM (15213), WIDE_SET_PARAM (15214), BURST_PROGRESS (15218/15220), CMOS_TEMPERATURE (15292) |
| Astro | ASTRO_CALIBRATION (15210), ASTRO_GOTO (15211), ASTRO_TRACKING (15212), EQ_SOLVING (15239), CAPTURE_RAW_STATE (15206/15208) |
| Focus | FOCUS_POSITION (15257), ASTRO_AUTO_FOCUS_STATE (15278), NORMAL_AUTO_FOCUS_STATE (15279), AREA_AUTO_FOCUS_STATE (15281) |
| Motor/Track | TRACK_RESULT (15225), SENTRY_MODE_STATE (15231), UFO_MODE_STATE (15240) |
| Panorama | PANORAMA_PROGRESS (15219), PANORAMA_UPLOAD (15244-15246), PANORAMA_COMPRESS (15293/15294), PANO_FRAMING (15297-15299) |
| General Params | GENERAL_BOOL_PARAM (15266), GENERAL_INT_PARAM (15264), GENERAL_FLOAT_PARAM (15265) |
| Dark/Calib | STATE_CAPTURE_RAW_DARK (15206), STATE_CAPTURE_CALI_FRAME (15290), PROGRESS_CAPTURE_CALI_FRAME (15291) |
| Device Attitude | DEVICE_ATTITUDE (15295), SKY_TARGET_FINDER_STATE (15296) |
### Complete Notify Command List
| ID | Command |
|----|---------|
| 15200 | NOTIFY_TELE_WIDE_PICTURE_MATCHING |
| 15201 | NOTIFY_ELE |
| 15202 | NOTIFY_CHARGE |
| 15203 | NOTIFY_SDCARD_INFO |
| 15204 | NOTIFY_TELE_RECORD_TIME |
| 15205 | NOTIFY_TELE_TIMELAPSE_OUT_TIME |
| 15206 | NOTIFY_STATE_CAPTURE_RAW_DARK |
| 15207 | NOTIFY_PROGRASS_CAPTURE_RAW_DARK |
| 15208 | NOTIFY_STATE_CAPTURE_RAW_LIVE_STACKING |
| 15209 | NOTIFY_PROGRASS_CAPTURE_RAW_LIVE_STACKING |
| 15210 | NOTIFY_STATE_ASTRO_CALIBRATION |
| 15211 | NOTIFY_STATE_ASTRO_GOTO |
| 15212 | NOTIFY_STATE_ASTRO_TRACKING |
| 15213 | NOTIFY_TELE_SET_PARAM |
| 15214 | NOTIFY_WIDE_SET_PARAM |
| 15215 | NOTIFY_TELE_FUNCTION_STATE |
| 15216 | NOTIFY_WIDE_FUNCTION_STATE |
| 15217 | NOTIFY_SET_FEATURE_PARAM |
| 15218 | NOTIFY_TELE_BURST_PROGRESS |
| 15219 | NOTIFY_PANORAMA_PROGRESS |
| 15220 | NOTIFY_WIDE_BURST_PROGRESS |
| 15221 | NOTIFY_RGB_STATE |
| 15222 | NOTIFY_POWER_IND_STATE |
| 15223 | NOTIFY_WS_HOST_SLAVE_MODE |
| 15224 | NOTIFY_MTP_STATE |
| 15225 | NOTIFY_TRACK_RESULT |
| 15226 | NOTIFY_WIDE_TIMELAPSE_OUT_TIME |
| 15227 | NOTIFY_CPU_MODE |
| 15228 | NOTIFY_STATE_ASTRO_TRACKING_SPECIAL |
| 15229 | NOTIFY_POWER_OFF |
| 15230 | NOTIFY_ALBUM_UPDATE |
| 15231 | NOTIFY_SENTRY_MODE_STATE |
| 15232 | NOTIFY_SENTRY_MODE_TRACK_RESULT |
| 15233 | NOTIFY_STATE_ASTRO_ONE_CLICK_GOTO |
| 15234 | NOTIFY_STREAM_TYPE |
| 15235 | NOTIFY_WIDE_RECORD_TIME |
| 15236 | NOTIFY_STATE_WIDE_CAPTURE_RAW_LIVE_STACKING |
| 15237 | NOTIFY_PROGRASS_WIDE_CAPTURE_RAW_LIVE_STACKING |
| 15238 | NOTIFY_MULTI_TRACK_RESULT |
| 15239 | NOTIFY_EQ_SOLVING_STATE |
| 15240 | NOTIFY_UFO_MODE_STATE |
| 15241 | NOTIFY_TELE_LONG_EXP_PROGRESS |
| 15242 | NOTIFY_WIDE_LONG_EXP_PROGRESS |
| 15243 | NOTIFY_TEMPERATURE |
| 15244 | NOTIFY_PANORAMA_UPLOAD_COMPRESS_PROGRESS |
| 15245 | NOTIFY_PANORAMA_UPLOAD_UPLOAD_PROGRESS |
| 15246 | NOTIFY_PANORAMA_UPLOAD_COMPLETE |
| 15247 | NOTIFY_STATE_CAPTURE_WIDE_RAW_DARK |
| 15248 | NOTIFY_SHOOTING_SCHEDULE_RESULT_AND_STATE |
| 15249 | NOTIFY_SHOOTING_TASK_STATE |
| 15250 | NOTIFY_SKY_SEACHER_STATE |
| 15251 | NOTIFY_WIDE_MULTI_TRACK_RESULT |
| 15252 | NOTIFY_WIDE_TRACK_RESULT |
| 15253 | NOTIFY_STATE_AI_ENHANCE |
| 15254 | NOTIFY_PROGRESS_AI_ENHANCE |
| 15255 | NOTIFY_WAIT_SHOOTING_PROGRESS |
| 15256 | NOTIFY_CALIBRATION_RESULT |
| 15257 | NOTIFY_FOCUS_POSITION |
| 15258 | NOTIFY_UFO_AUTO_HAND_MODE |
| 15259 | NOTIFY_CURRENT_PANORAMA_UPLOAD_STATE |
| 15260 | NOTIFY_LOW_TEMP_PROTECTION_MODE |
| 15261 | NOTIFY_EXCLUSIVE_SYSTEM_IO_TASK_STATE |
| 15262 | NOTIFY_BODY_STATUS |
| 15263 | NOTIFY_PROGRESS_CAPTURE_MOSAIC |
| 15264 | NOTIFY_GENERAL_INT_PARAM |
| 15265 | NOTIFY_GENERAL_FLOAT_PARAM |
| 15266 | NOTIFY_GENERAL_BOOL_PARAM |
| 15267 | NOTIFY_SWITCH_SHOOTING_MODE |
| 15268 | NOTIFY_TELE_SWITCH_CROP_RATIO |
| 15269 | NOTIFY_TELE_SHOOTING_TECH_STATE |
| 15270 | NOTIFY_WB |
| 15271 | NOTIFY_WIDE_SHOOTING_TECH_STATE |
| 15272 | NOTIFY_RESOLUTION_PARAM |
| 15273 | NOTIFY_PHOTO_STATE |
| 15274 | NOTIFY_BURST_STATE |
| 15275 | NOTIFY_RECORD_STATE |
| 15276 | NOTIFY_TIMELAPSE_STATE |
| 15277 | NOTIFY_PANORAMA_STATE |
| 15278 | NOTIFY_ASTRO_AUTO_FOCUS_STATE |
| 15279 | NOTIFY_NORMAL_AUTO_FOCUS_STATE |
| 15280 | NOTIFY_ASTRO_AUTO_FOCUS_FAST_STATE |
| 15281 | NOTIFY_AREA_AUTO_FOCUS_STATE |
| 15282 | NOTIFY_DUAL_CAMERA_LINKAGE_STATE |
| 15283 | NOTIFY_RESOLUTION_FPS_STATE |
| 15284 | NOTIFY_NORMAL_TRACK_STATE |
| 15285 | NOTIFY_BURST_PROGRESS |
| 15286 | NOTIFY_RECORD_TIME |
| 15287 | NOTIFY_TIMELAPSE_OUT_TIME |
| 15288 | NOTIFY_LONG_EXP_PROGRESS |
| 15289 | NOTIFY_SENTRY_MOTOR_STATE |
| 15290 | NOTIFY_STATE_CAPTURE_CALI_FRAME |
| 15291 | NOTIFY_PROGRESS_CAPTURE_CALI_FRAME |
| 15292 | NOTIFY_CMOS_TEMPERATURE |
| 15293 | NOTIFY_PANORAMA_COMPRESS_PROGRESS |
| 15294 | NOTIFY_PANORAMA_COMPRESS_COMPLETE |
| 15295 | NOTIFY_DEVICE_ATTITUDE |
| 15296 | NOTIFY_SKY_TARGET_FINDER_STATE |
| 15297 | NOTIFY_PANO_FRAMING_RECT_UPDATE |
| 15298 | NOTIFY_PANO_FRAMING_THUMBNAIL_UPDATE |
| 15299 | NOTIFY_PANO_FRAMING_STATE |
| 15300 | NOTIFY_WIDE_FOCUS_POSITION |
| 15301 | NOTIFY_LENS_DEFOG_STATE |
| 15302 | NOTIFY_AUTO_COOLING_STATE |
| 15303 | NOTIFY_AUTO_SHUTDOWN_STATE |
---
## PanoramaProto — Module PANORAMA (ID=10, base 15500)
### Command IDs
| ID | Command |
|----|---------|
| 15500 | PANORAMA_START_GRID |
| 15501 | PANORAMA_STOP |
| 15503 | PANORAMA_START_STITCH_UPLOAD |
| 15504 | PANORAMA_STOP_STITCH_UPLOAD |
| 15505 | PANORAMA_GET_CURRENT_UPLOAD_STATE |
| 15506 | PANORAMA_GET_UPLOAD_PREDICT |
| 15507 | PANORAMA_START_COMPRESS |
| 15508 | PANORAMA_STOP_COMPRESS |
| 15509 | PANORAMA_START_FRAMING |
| 15510 | PANORAMA_STOP_FRAMING |
| 15511 | PANORAMA_RESET_FRAMING |
| 15512 | PANORAMA_UPDATE_FRAMING_RECT |
| 15513 | PANORAMA_STOP_FRAMEING_AND_START_GRID |
> **Note**: ID 15502 is not assigned. `PANORAMA_STOP` is 15501 (not "START_FRAMEING" as previously documented).
---
## ScheduleProto — Module SHOOTING_SCHEDULE (ID=13, base 16100)
### Command IDs
| ID | Command |
|----|---------|
| 16100 | SYNC_SHOOTING_SCHEDULE |
| 16101 | CANCEL_SHOOTING_SCHEDULE |
| 16102 | GET_ALL_SHOOTING_SCHEDULE |
| 16103 | GET_SHOOTING_SCHEDULE_BY_ID |
| 16105 | REPLACE_SHOOTING_SCHEDULE |
| 16106 | UNLOCK_SHOOTING_SCHEDULE |
| 16107 | LOCK_SHOOTING_SCHEDULE |
| 16108 | DELETE_SHOOTING_SCHEDULE |
> **Note**: ID 16104 is not assigned.

345
12_command_index.md Normal file
View File

@ -0,0 +1,345 @@
# Complete WsCmd Command Index
All ~300 command IDs from `WsCmd.smali`, organized by module.
## Module Summary
| ID | Module | Base | Range |
|----|--------|------|-------|
| 0 | NONE | — | — |
| 1 | CAMERA_TELE | 10000 | 10000-10050 |
| 2 | CAMERA_WIDE | 12000 | 12000-12036 |
| 3 | ASTRO | 11000 | 11000-11048 |
| 4 | SYSTEM | 13000 | 13000-13010 |
| 5 | RGB_POWER | 13500 | 13500-13505 |
| 6 | MOTOR | 14000 | 14000-14009 |
| 7 | TRACK | 14800 | 14800-14812 |
| 8 | FOCUS | 15000 | 15000-15012 |
| 9 | NOTIFY | 15200 | 15200-15303 |
| 10 | PANORAMA | 15500 | 15500-15513 |
| 11 | ITIPS | 15700 | 15700 |
| 12 | FACTORY_TEST | 15900 | (no commands) |
| 13 | SHOOTING_SCHEDULE | 16100 | 16100-16108 |
| 14 | TASK_CENTER | 16400 | 16400-16406 |
| 15 | PARAM | 16700 | 16700-16706 |
| 16 | VOICE_ASSISTANT | 16800 | 16800 |
| 17 | CAMERA_GUIDE | 16900 | (no commands) |
| 18 | DEVICE | 17000 | 17000-17002 |
---
## CAMERA_TELE (Module 1, base 10000)
| ID | Command |
|----|---------|
| 10000 | CMD_CAMERA_TELE_OPEN_CAMERA |
| 10001 | CMD_CAMERA_TELE_CLOSE_CAMERA |
| 10002 | CMD_CAMERA_TELE_PHOTOGRAPH |
| 10003 | CMD_CAMERA_TELE_BURST |
| 10004 | CMD_CAMERA_TELE_STOP_BURST |
| 10005 | CMD_CAMERA_TELE_START_RECORD |
| 10006 | CMD_CAMERA_TELE_STOP_RECORD |
| 10007 | CMD_CAMERA_TELE_SET_EXP_MODE |
| 10008 | CMD_CAMERA_TELE_GET_EXP_MODE |
| 10009 | CMD_CAMERA_TELE_SET_EXP |
| 10010 | CMD_CAMERA_TELE_GET_EXP |
| 10011 | CMD_CAMERA_TELE_SET_GAIN_MODE |
| 10012 | CMD_CAMERA_TELE_GET_GAIN_MODE |
| 10013 | CMD_CAMERA_TELE_SET_GAIN |
| 10014 | CMD_CAMERA_TELE_GET_GAIN |
| 10015 | CMD_CAMERA_TELE_SET_BRIGHTNESS |
| 10016 | CMD_CAMERA_TELE_GET_BRIGHTNESS |
| 10017 | CMD_CAMERA_TELE_SET_CONTRAST |
| 10018 | CMD_CAMERA_TELE_GET_CONTRAST |
| 10019 | CMD_CAMERA_TELE_SET_SATURATION |
| 10020 | CMD_CAMERA_TELE_GET_SATURATION |
| 10021 | CMD_CAMERA_TELE_SET_HUE |
| 10022 | CMD_CAMERA_TELE_GET_HUE |
| 10023 | CMD_CAMERA_TELE_SET_SHARPNESS |
| 10024 | CMD_CAMERA_TELE_GET_SHARPNESS |
| 10025 | CMD_CAMERA_TELE_SET_WB_MODE |
| 10026 | CMD_CAMERA_TELE_GET_WB_MODE |
| 10027 | CMD_CAMERA_TELE_SET_WB_SCENE |
| 10028 | CMD_CAMERA_TELE_GET_WB_SCENE |
| 10029 | CMD_CAMERA_TELE_SET_WB_CT |
| 10030 | CMD_CAMERA_TELE_GET_WB_CT |
| 10031 | CMD_CAMERA_TELE_SET_IRCUT |
| 10032 | CMD_CAMERA_TELE_GET_IRCUT |
| 10033 | CMD_CAMERA_TELE_START_TIMELAPSE_PHOTO |
| 10034 | CMD_CAMERA_TELE_STOP_TIMELAPSE_PHOTO |
| 10035 | CMD_CAMERA_TELE_SET_ALL_PARAMS |
| 10036 | CMD_CAMERA_TELE_GET_ALL_PARAMS |
| 10037 | CMD_CAMERA_TELE_SET_FEATURE_PARAM |
| 10038 | CMD_CAMERA_TELE_GET_ALL_FEATURE_PARAMS |
| 10039 | CMD_CAMERA_TELE_GET_SYSTEM_WORKING_STATE |
| 10040 | CMD_CAMERA_TELE_SET_JPG_QUALITY |
| 10041 | CMD_CAMERA_TELE_PHOTO_RAW |
| 10042 | CMD_CAMERA_TELE_SET_RTSP_BITRATE_TYPE |
| 10043 | CMD_CAMERA_TELE_DISABLE_ALL_ISP_PROCESSING |
| 10044 | CMD_CAMERA_TELE_ENABLE_ALL_ISP_PROCESSING |
| 10045 | CMD_CAMERA_TELE_SET_ISP_MODULE_STATE |
| 10046 | CMD_CAMERA_TELE_GET_ISP_MODULE_STATE |
| 10047 | CMD_CAMERA_TELE_SWITCH_RESOLUTION |
| 10048 | CMD_CAMERA_TELE_SWITCH_FRAMERATE |
| 10049 | CMD_CAMERA_TELE_SWITCH_CROP_RATIO |
| 10050 | CMD_CAMERA_TELE_SET_PREVIEW_QUALITY |
## CAMERA_WIDE (Module 2, base 12000)
| ID | Command |
|----|---------|
| 12000 | CMD_CAMERA_WIDE_OPEN_CAMERA |
| 12001 | CMD_CAMERA_WIDE_CLOSE_CAMERA |
| 12002 | CMD_CAMERA_WIDE_SET_EXP_MODE |
| 12003 | CMD_CAMERA_WIDE_GET_EXP_MODE |
| 12004 | CMD_CAMERA_WIDE_SET_EXP |
| 12005 | CMD_CAMERA_WIDE_GET_EXP |
| 12006 | CMD_CAMERA_WIDE_SET_GAIN |
| 12007 | CMD_CAMERA_WIDE_GET_GAIN |
| 12008 | CMD_CAMERA_WIDE_SET_BRIGHTNESS |
| 12009 | CMD_CAMERA_WIDE_GET_BRIGHTNESS |
| 12010 | CMD_CAMERA_WIDE_SET_CONTRAST |
| 12011 | CMD_CAMERA_WIDE_GET_CONTRAST |
| 12012 | CMD_CAMERA_WIDE_SET_SATURATION |
| 12013 | CMD_CAMERA_WIDE_GET_SATURATION |
| 12014 | CMD_CAMERA_WIDE_SET_HUE |
| 12015 | CMD_CAMERA_WIDE_GET_HUE |
| 12016 | CMD_CAMERA_WIDE_SET_SHARPNESS |
| 12017 | CMD_CAMERA_WIDE_GET_SHARPNESS |
| 12018 | CMD_CAMERA_WIDE_SET_WB_MODE |
| 12019 | CMD_CAMERA_WIDE_GET_WB_MODE |
| 12020 | CMD_CAMERA_WIDE_SET_WB_CT |
| 12021 | CMD_CAMERA_WIDE_GET_WB_CT |
| 12022 | CMD_CAMERA_WIDE_PHOTOGRAPH |
| 12023 | CMD_CAMERA_WIDE_BURST |
| 12024 | CMD_CAMERA_WIDE_STOP_BURST |
| 12025 | CMD_CAMERA_WIDE_START_TIMELAPSE_PHOTO |
| 12026 | CMD_CAMERA_WIDE_STOP_TIMELAPSE_PHOTO |
| 12027 | CMD_CAMERA_WIDE_GET_ALL_PARAMS |
| 12028 | CMD_CAMERA_WIDE_SET_ALL_PARAMS |
| 12029 | CMD_CAMERA_WIDE_PHOTO_RAW |
| 12030 | CMD_CAMERA_WIDE_START_RECORD |
| 12031 | CMD_CAMERA_WIDE_STOP_RECORD |
| 12032 | CMD_CAMERA_WIDE_SET_RTSP_BITRATE_TYPE |
| 12035 | CMD_CAMERA_WIDE_SET_WB_SCENE |
| 12036 | CMD_CAMERA_WIDE_SET_PREVIEW_QUALITY |
> **Note**: IDs 12033-12034 are not assigned.
## ASTRO (Module 3, base 11000)
| ID | Command |
|----|---------|
| 11000 | CMD_ASTRO_START_CALIBRATION |
| 11001 | CMD_ASTRO_STOP_CALIBRATION |
| 11002 | CMD_ASTRO_START_GOTO_DSO |
| 11003 | CMD_ASTRO_START_GOTO_SOLAR_SYSTEM |
| 11004 | CMD_ASTRO_STOP_GOTO |
| 11005 | CMD_ASTRO_START_CAPTURE_RAW_LIVE_STACKING |
| 11006 | CMD_ASTRO_STOP_CAPTURE_RAW_LIVE_STACKING |
| 11007 | CMD_ASTRO_START_CAPTURE_RAW_DARK |
| 11008 | CMD_ASTRO_STOP_CAPTURE_RAW_DARK |
| 11009 | CMD_ASTRO_CHECK_GOT_DARK |
| 11010 | CMD_ASTRO_GO_LIVE |
| 11011 | CMD_ASTRO_START_TRACK_SPECIAL_TARGET |
| 11012 | CMD_ASTRO_STOP_TRACK_SPECIAL_TARGET |
| 11013 | CMD_ASTRO_START_ONE_CLICK_GOTO_DSO |
| 11014 | CMD_ASTRO_START_ONE_CLICK_GOTO_SOLAR_SYSTEM |
| 11015 | CMD_ASTRO_STOP_ONE_CLICK_GOTO |
| 11016 | CMD_ASTRO_START_WIDE_CAPTURE_LIVE_STACKING |
| 11017 | CMD_ASTRO_STOP_WIDE_CAPTURE_LIVE_STACKING |
| 11018 | CMD_ASTRO_START_EQ_SOLVING |
| 11019 | CMD_ASTRO_STOP_EQ_SOLVING |
| 11020 | CMD_ASTRO_WIDE_GO_LIVE |
| 11021 | CMD_ASTRO_START_CAPTURE_RAW_DARK_WITH_PARAM |
| 11022 | CMD_ASTRO_STOP_CAPTURE_RAW_DARK_WITH_PARAM |
| 11023 | CMD_ASTRO_GET_DARK_FRAME_LIST |
| 11024 | CMD_ASTRO_DEL_DARK_FRAME_LIST |
| 11025 | CMD_ASTRO_START_CAPTURE_WIDE_RAW_DARK_WITH_PARAM |
| 11026 | CMD_ASTRO_STOP_CAPTURE_WIDE_RAW_DARK_WITH_PARAM |
| 11027 | CMD_ASTRO_GET_WIDE_DARK_FRAME_LIST |
| 11028 | CMD_ASTRO_DEL_WIDE_DARK_FRAME_LIST |
| 11029 | CMD_ASTRO_START_AI_ENHANCE |
| 11030 | CMD_ASTRO_STOP_AI_ENHANCE |
| 11031 | CMD_ASTRO_START_TELE_MOSAIC |
| 11032 | CMD_ASTRO_CHECK_IF_RESTACKABLE |
| 11033 | CMD_ASTRO_START_MAKE_FITS_THUMB |
| 11034 | CMD_ASTRO_STOP_MAKE_FITS_THUMB |
| 11035 | CMD_ASTRO_START_RESTACKED |
| 11036 | CMD_ASTRO_STOP_RESTACKED |
| 11037 | CMD_ASTRO_FAST_STOP_CAPTURE_RAW_LIVE_STACKING |
| 11038 | CMD_ASTRO_FAST_STOP_WIDE_CAPTURE_LIVE_STACKING |
| 11039 | CMD_ASTRO_GET_ASTRO_SHOOTING_TIME |
| 11040 | CMD_ASTRO_GET_QUICK_SET_LIST |
| 11041 | CMD_ASTRO_SET_QUICK_SET |
| 11042 | CMD_ASTRO_START_ONE_CLICK_SHOOTING |
| 11043 | CMD_ASTRO_GET_CALI_FRAME_LIST |
| 11044 | CMD_ASTRO_DEL_CALI_FRAME_LIST |
| 11045 | CMD_ASTRO_START_CAPTURE_CALI_FRAME |
| 11046 | CMD_ASTRO_STOP_CAPTURE_CALI_FRAME |
| 11047 | CMD_ASTRO_START_SKY_TARGET_FINDER |
| 11048 | CMD_ASTRO_STOP_SKY_TARGET_FINDER |
## SYSTEM (Module 4, base 13000)
| ID | Command |
|----|---------|
| 13000 | CMD_SYSTEM_SET_TIME |
| 13001 | CMD_SYSTEM_SET_TIME_ZONE |
| 13002 | CMD_SYSTEM_SET_MTP_MODE |
| 13003 | CMD_SYSTEM_SET_CPU_MODE |
| 13004 | CMD_SYSTEM_SET_MASTER |
| 13005 | CMD_SYSTEM_GET_DEVICE_ACTIVATE_INFO |
| 13006 | CMD_SYSTEM_DEVICE_ACTIVATE_WRITE_FILE |
| 13007 | CMD_SYSTEM_DEVICE_ACTIVATE_NOTIFY_ACTIVATE_SUCCESSFULL |
| 13008 | CMD_SYSTEM_FACTORY_TEST_UN_ACTIVATE |
| 13009 | CMD_SYSTEM_SET_LOW_TEMP_PROTECTION_MODE |
| 13010 | CMD_SYSTEM_SET_LOCATION |
## RGB_POWER (Module 5, base 13500)
| ID | Command |
|----|---------|
| 13500 | CMD_RGB_POWER_OPEN_RGB |
| 13501 | CMD_RGB_POWER_CLOSE_RGB |
| 13502 | CMD_RGB_POWER_POWER_DOWN |
| 13503 | CMD_RGB_POWER_POWERIND_ON |
| 13504 | CMD_RGB_POWER_POWERIND_OFF |
| 13505 | CMD_RGB_POWER_REBOOT |
## MOTOR (Module 6, base 14000)
| ID | Command |
|----|---------|
| 14000 | CMD_STEP_MOTOR_RUN |
| 14002 | CMD_STEP_MOTOR_STOP |
| 14006 | CMD_STEP_MOTOR_SERVICE_JOYSTICK |
| 14007 | CMD_STEP_MOTOR_SERVICE_JOYSTICK_FIXED_ANGLE |
| 14008 | CMD_STEP_MOTOR_SERVICE_JOYSTICK_STOP |
| 14009 | CMD_STEP_MOTOR_SERVICE_DUAL_CAMERA_LINKAGE |
> **Note**: IDs 14001, 14003-14005 are not assigned.
## TRACK (Module 7, base 14800)
| ID | Command |
|----|---------|
| 14800 | CMD_TRACK_START_TRACK |
| 14801 | CMD_TRACK_STOP_TRACK |
| 14802 | CMD_SENTRY_MODE_START |
| 14803 | CMD_SENTRY_MODE_STOP |
| 14804 | CMD_MOT_START |
| 14805 | CMD_MOT_TRACK_ONE |
| 14806 | CMD_UFOTRACK_MODE_START |
| 14807 | CMD_UFOTRACK_MODE_STOP |
| 14808 | CMD_MOT_WIDE_TRACK_ONE |
| 14809 | CMD_SWITCH_MAIN_PREVIEW |
| 14810 | CMD_UFO_HAND_AOTO_MODE |
| 14811 | CMD_SENTRY_SCENE_SELECT |
| 14812 | CMD_TRACK_START_CLICK |
## FOCUS (Module 8, base 15000)
| ID | Command |
|----|---------|
| 15000 | CMD_FOCUS_AUTO_FOCUS |
| 15001 | CMD_FOCUS_MANUAL_SINGLE_STEP_FOCUS |
| 15002 | CMD_FOCUS_START_MANUAL_CONTINU_FOCUS |
| 15003 | CMD_FOCUS_STOP_MANUAL_CONTINU_FOCUS |
| 15004 | CMD_FOCUS_START_ASTRO_AUTO_FOCUS |
| 15005 | CMD_FOCUS_STOP_ASTRO_AUTO_FOCUS |
| 15011 | CMD_FOCUS_GET_USER_INFINITY_POS |
| 15012 | CMD_FOCUS_SET_USER_INFINITY_POS |
> **Note**: IDs 15006-15010 are not assigned.
## NOTIFY (Module 9, base 15200)
See [11_task_notify_panorama_schedule_commands.md](11_task_notify_panorama_schedule_commands.md) for the full 104-command list (15200-15303).
## PANORAMA (Module 10, base 15500)
| ID | Command |
|----|---------|
| 15500 | CMD_PANORAMA_START_GRID |
| 15501 | CMD_PANORAMA_STOP |
| 15503 | CMD_PANORAMA_START_STITCH_UPLOAD |
| 15504 | CMD_PANORAMA_STOP_STITCH_UPLOAD |
| 15505 | CMD_PANORAMA_GET_CURRENT_UPLOAD_STATE |
| 15506 | CMD_PANORAMA_GET_UPLOAD_PREDICT |
| 15507 | CMD_PANORAMA_START_COMPRESS |
| 15508 | CMD_PANORAMA_STOP_COMPRESS |
| 15509 | CMD_PANORAMA_START_FRAMING |
| 15510 | CMD_PANORAMA_STOP_FRAMING |
| 15511 | CMD_PANORAMA_RESET_FRAMING |
| 15512 | CMD_PANORAMA_UPDATE_FRAMING_RECT |
| 15513 | CMD_PANORAMA_STOP_FRAMEING_AND_START_GRID |
> **Note**: ID 15502 is not assigned.
## ITIPS (Module 11, base 15700)
| ID | Command |
|----|---------|
| 15700 | CMD_ITIPS_GET |
## FACTORY_TEST (Module 12, base 15900)
No commands defined in WsCmd. The SYSTEM command `CMD_SYSTEM_FACTORY_TEST_UN_ACTIVATE` (13008) handles factory test activation.
## SHOOTING_SCHEDULE (Module 13, base 16100)
| ID | Command |
|----|---------|
| 16100 | CMD_SYNC_SHOOTING_SCHEDULE |
| 16101 | CMD_CANCEL_SHOOTING_SCHEDULE |
| 16102 | CMD_GET_ALL_SHOOTING_SCHEDULE |
| 16103 | CMD_GET_SHOOTING_SCHEDULE_BY_ID |
| 16105 | CMD_REPLACE_SHOOTING_SCHEDULE |
| 16106 | CMD_UNLOCK_SHOOTING_SCHEDULE |
| 16107 | CMD_LOCK_SHOOTING_SCHEDULE |
| 16108 | CMD_DELETE_SHOOTING_SCHEDULE |
> **Note**: ID 16104 is not assigned.
## TASK_CENTER (Module 14, base 16400)
| ID | Command |
|----|---------|
| 16400 | CMD_GLOBAL_TASK_MANAGER_START_TASK |
| 16401 | CMD_GLOBAL_TASK_MANAGER_STOP_TASK |
| 16402 | CMD_GLOBAL_TASK_MANAGER_SWITCH_SHOOTING_MODE |
| 16403 | CMD_GLOBAL_TASK_MANAGER_SWITCH_SHOOTING_TECH |
| 16404 | CMD_GLOBAL_TASK_MANAGER_ENTER_CAMERA |
| 16405 | CMD_GLOBAL_TASK_GET_DEVICE_STATE_INFO |
| 16406 | CMD_GLOBAL_VOICE_ASSISTANT_TASK |
## PARAM (Module 15, base 16700)
| ID | Command |
|----|---------|
| 16700 | CMD_PARAM_SET_EXPOSURE |
| 16701 | CMD_PARAM_SET_GAIN |
| 16702 | CMD_PARAM_SET_WB |
| 16703 | CMD_PARAM_SET_GENERAL_BOOL_PARAMS |
| 16704 | CMD_PARAM_SET_GENERAL_INT_PARAM |
| 16705 | CMD_PARAM_SET_GENERAL_FLOAT_PARAM |
| 16706 | CMD_PARAM_SET_AUTO_PARAMS |
## VOICE_ASSISTANT (Module 16, base 16800)
| ID | Command |
|----|---------|
| 16800 | CMD_VOICE_ASSISTANT_TASK |
## CAMERA_GUIDE (Module 17, base 16900)
No commands defined in WsCmd. The module exists for routing but has no specific commands.
## DEVICE (Module 18, base 17000)
| ID | Command |
|----|---------|
| 17000 | CMD_DEVICE_LENS_DEFOG |
| 17001 | CMD_DEVICE_AUTO_COOLING |
| 17002 | CMD_DEVICE_AUTO_SHUTDOWN |

209
13_connection_flow.md Normal file
View File

@ -0,0 +1,209 @@
# Connection Flow
## Complete Connection Sequence
```
Step 1: BLE Discovery Step 4: WebSocket Step 6: Commands
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ SCAN for │ │ Connect to │ │ Send WsPacket│
│ "DWARF*" │ │ ws://IP:9900 │ │ (moduleId+cmd)│
│ devices │ │ ?client_id= │ │ │
│ via BleManager│ │ <clientId> │ │ Receive │
└──────┬───────┘ └──────┬───────┘ │ WsPacket │
│ │ │ (response/ │
Step 2: GATT Connect Step 5: Keepalive │ notification)│
┌──────────────┐ ┌──────────────┐ └──────────────┘
│ Connect to │ │ DwarfPing → │
│ Service DAF2 │ │ ← DwarfEcho │
│ (UUID DAF2) │ │ (periodic) │
└──────┬───────┘ └──────────────┘
Step 3: Auth
┌──────────────┐
│ Write │
│ ReqGetconfig │
│ on DAF3 │
│ → Receive │
│ ResGetconfig │
│ on DAF4 │
└──────────────┘
```
## Step 1-3: BLE Phase
### Pseudocode: BLE Authentication
```python
# 1. Scan for DWARF devices
devices = ble_scan(filter_name="DWARF*")
# 2. Connect to GATT service
gatt = ble_connect(device, service_uuid="0000DAF2-0000-1000-8000-00805f9b34fb")
# 3. Authenticate
auth_request = BleProto.ReqGetconfig(
cmd=1, # GetWiFiConfig
blePsd="DWARF_12345678", # default password
clientId="my-app-client-id"
)
ble_packet = build_ble_packet(cmd=1, data=auth_request.SerializeToString())
ble_write(characteristic=DAF3, data=ble_packet)
# 4. Receive response
response_data = ble_notify(characteristic=DAF4)
response_packet = parse_ble_packet(response_data)
config = BleProto.ResGetconfig()
config.ParseFromString(response_packet.dataPayload)
device_ip = config.ip # e.g., "192.168.88.1"
```
### Pseudocode: WiFi Configuration (STA mode)
```python
# Configure device to connect to local WiFi
sta_request = BleProto.ReqSta(
cmd=3, # SetSTAMode
autoStart=1,
blePsd="DWARF_12345678",
ssid="MyHomeWiFi",
psd="home_password",
clientId="my-app-client-id"
)
ble_packet = build_ble_packet(cmd=3, data=sta_request.SerializeToString())
ble_write(characteristic=DAF5, data=ble_packet)
# Receive STA response
sta_data = ble_notify(characteristic=DAF6)
sta_packet = parse_ble_packet(sta_data)
sta_response = BleProto.ResSta()
sta_response.ParseFromString(sta_packet.dataPayload)
device_ip = sta_response.ip # IP for WebSocket
```
## Step 4: WebSocket Phase
### Pseudocode: WebSocket Connection
```python
import websocket
import protobuf
# Connect to device WebSocket
ws = websocket.connect(f"ws://{device_ip}:9900/?client_id={client_id}")
# Start keepalive thread
def keepalive():
while connected:
ping = BleProto.DwarfPing(
vocaltype=1, # VT_PING
timestamp=current_time_ms(),
magic=session_magic_bytes
)
packet = WsPacket(
majorVersion=2,
minorVersion=3,
deviceId=device_id,
moduleId=0, # NONE
cmd=0,
type=0, # request
data=ping.SerializeToString(),
clientId=client_id
)
ws.send(packet.SerializeToString())
sleep(5) # 5-second interval
```
### Pseudocode: Send Command
```python
def send_command(ws, device_id, module_id, cmd, payload_bytes):
"""Send a command via WebSocket."""
packet = WsPacket(
majorVersion=2,
minorVersion=3,
deviceId=device_id,
moduleId=module_id,
cmd=cmd,
type=0, # request
data=payload_bytes,
clientId=client_id
)
ws.send(packet.SerializeToString())
# Example: Start tracking
track_req = TrackProto.ReqStartTrack(x=500, y=300, w=100, h=100, camId=0)
send_command(ws, device_id=4, module_id=7, cmd=14800,
payload_bytes=track_req.SerializeToString())
# Example: Open tele camera
camera_req = CameraProto.ReqOpenCamera(binning=False, rtspEncodeType=0)
send_command(ws, device_id=4, module_id=1, cmd=10000,
payload_bytes=camera_req.SerializeToString())
```
## BLE Packet Binary Format
```
Byte Field Size Description
---- ----------------- ---- -----------
0 magic 1 0xAA (constant)
1 protocolVersion 1 Protocol version (typically 1)
2 cmdInstruction 1 BLE command (0-7)
3 packageSequence 1 Current packet number (0-based)
4 totalPackages 1 Total packets for this message
5-6 extendedProtocol 2 Extended protocol (big-endian, usually 0)
7-8 validDataLength 2 Length of protobuf payload (big-endian)
9..N dataPayload N Protobuf-encoded BleProto message
N+1..N+2 crc 2 CRC-16/MODBUS (poly=0x8005, init=0xFFFF, reflected)
N+3 endMarker 1 0x0D (constant)
Total = validDataLength + 12 bytes
```
### CRC-16/MODBUS Parameters
- Polynomial: 0x8005 (reflected: 0xA001)
- Initial value: 0xFFFF
- Reflect input: Yes
- Reflect output: Yes
- XOR out: 0x0000
- Computed over: header (9 bytes) + payload (N bytes), **excluding** CRC and end marker
## WsPacket Binary Format
```
Field Proto# Type Description
-------------- ------ ---- -----------
majorVersion 1 int32 Always 2
minorVersion 2 int32 Always 3
deviceId 3 int32 Target device (0-6, see DeviceType)
moduleId 4 int32 Module (0-18, see module table)
cmd 5 int32 Command ID (see WsCmd index)
type 6 int32 0=request, 1=response, 2=notification, 3=reply
data 7 bytes Protobuf-encoded module-specific payload
clientId 8 string App client identifier
```
Serialized using standard protobuf proto3 encoding.
## Device Models
| Model | deviceId | Codename | Max Name | Special |
|-------|----------|----------|----------|---------|
| Unknown | 0 | — | — | — |
| DWARF 2 | 1 | — | 21 | — |
| DWARF 3 | 2 | — | 19 | — |
| *(gap)* | 3 | — | — | *unused* |
| DWARF mini | 4 | Bilbo | 15 | No Panorama Create, `indexBilbo.html` |
| DWARF 4 | 5 | — | 19 | — |
| DWARF DRAGON | 6 | — | — | — |
## Ports & Endpoints
| Service | URL/Port | Note |
|---------|----------|------|
| WebSocket | `ws://<ip>:9900/?client_id=<id>` | Primary control channel |
| WebSocket (alt) | Ports 4409 (0x1139), 4410 (0x113A) | Secondary ports |
| Firebase | `dwarflab-a7062.appspot.com` | Cloud backend |
| S3 | `dwarf-bucket-02-1251529954` | OTA storage |