Reverse-engineer DWARF II telescope API and build open-source Go client

Complete reverse-engineering of the DWARFLAB Android app (v3.4.0) protocol
and implementation of a working CLI tool to control DWARF II telescopes.

Analysis (from APK decompilation with jadx):
- Extracted 17 protobuf definitions (382 messages) from embedded descriptors
- Mapped all 323 WebSocket command IDs across 16 modules
- Documented the full protocol: BLE discovery, WebSocket control (port 9900),
  RTSP preview, WsPacket envelope (proto v2.3)
- Documented the Android UI structure (screens, navigation, shooting modes)
- Key discovery: telescope responds with type=3 (reply), not type=1 (response),
  and several commands are fire-and-forget (RGB, camera open/close)

dwarfctl Go client:
- Protobuf bindings generated from extracted .proto files (397 messages)
- WebSocket transport layer with request-response matching and notification fan-out
- Typed API covering cameras, motors, astrophotography, focus, tracking, system, power
- Cobra CLI with 30+ subcommands and --debug traffic logging
- 57 unit tests (transport round-trip, command routing, proto encoding)
- Validated on real hardware: state, photo, motor slew (all directions/speeds),
  focus, RGB, time/location sync all confirmed working

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
This commit is contained in:
Jacquin Antoine
2026-07-12 15:18:56 +02:00
commit 814a836c5a
54 changed files with 35973 additions and 0 deletions

323
analysis/API_REFERENCE.md Normal file
View File

@ -0,0 +1,323 @@
# DWARFLAB Telescope — API Reference (reverse-engineered)
Reverse-engineered from `DWARFLAB.apk` v3.4.0 (build 629), package `com.convergence.dwarflab`.
This document describes the protocol used by the official Android app to talk to
DWARF II (and the in-development "Bilbo"/DWARF III) smart telescopes.
> Goal: enable an open-source client implementation. All command IDs, the wire
> envelope, and the inner protobuf payloads were recovered from the APK; nothing
> here is guessed.
---
## 1. Architecture at a glance
```
┌─────────────┐ BLE (GATT) ┌───────────┐
│ Phone app │ ───────────────▶ │ Telescope │ 1. discovery + Wi-Fi creds exchange
│ │ ◀── DwarfEcho ── │ │ (DwarfPing / DwarfEcho, see ble.proto)
└──────┬──────┘ └─────┬─────┘
│ joins telescope Wi-Fi │
│ (AP mode, or shared STA) │
│ │
│ WebSocket (binary) │ RTSP (TCP)
│ ws://<ip>:9900/?client_id=.. │ rtsp://<ip>/<cam>/stream0
▼ ▼
┌───────────────────────────┐ ┌──────────────┐
│ Control plane │ │ Live preview │
│ WsPacket (protobuf) │ │ ijkplayer / │
│ 323 commands, 17 modules │ │ ExoPlayer │
└───────────────────────────┘ └──────────────┘
```
Two distinct data planes:
| Plane | Transport | Port | Encoding | Purpose |
|-------|-----------|------|----------|---------|
| **Control** | WebSocket (binary frames) | **9900** | protobuf `WsPacket` envelope | All telescope commands & status |
| **Preview** | RTSP over TCP | 554 (std) | H.264/H.265 | Live camera viewfinder |
| **Discovery** | BLE GATT | — | protobuf (`ble.proto`) | Find telescope, get IP/SSID/PSK |
There is also a **cloud relay**: `https://app.dwarflabapp.com/app/uls/connect?d=…`
("ULS") used for remote access when the phone is not on the telescope's Wi-Fi.
Local LAN control (the focus of an OSS client) needs only BLE + WebSocket + RTSP.
---
## 2. Connection flow
### 2.1 Discovery & credentials (BLE)
The telescope advertises over BLE. The app sends a `DwarfPing` / `ReqGetconfig`
and receives a **`DwarfEcho`** (`ble.proto`) containing everything needed to
connect over IP:
```proto
message DwarfEcho {
VocalType vocaltype = 1;
uint64 timestamp = 2;
bytes magic = 3;
uint64 ts_ping = 4;
bytes mac_address = 5;
StationModel model = 6; // telescope family + revision
string sn = 7; // serial number
string name = 8; // advertised name
string psw = 9; // device password
string fw_version = 10;
string ws_scheme = 11; // "ws" or "wss"
uint32 session = 12;
NifAP ap = 13; // AP network (ifname/ssid/psw/ipv4/ipv6)
NifSTA sta = 14; // STA network (ifname/ssid/psw/rssi/ipv4/ipv6)
}
```
`ble_psd` (BLE password) + `client_id` authenticate the BLE requests
(`ReqGetconfig`, `ReqSta`, `ReqAp`, `ReqSetblewifi`). Responses carry the
**`ip`** field (`ResGetconfig.ip` / `ResSta.ip`) that the app feeds into the
WebSocket URL.
### 2.2 WebSocket control channel
Once the phone is on the telescope's network:
```
ws://<telescope_ip>:9900/?client_id=<client_id>
```
- Plain `ws://` by default; `wss://` if `ws_scheme == "wss"`.
- `client_id` is a client-generated identifier (`y32…m58158c()`).
- Source: `v55.java` field `f43155b` / method `m55420t(ip)`.
- **device_id** field in the envelope selects which telescope (multi-device),
defaults to `1` for the first/only connected scope.
### 2.3 RTSP preview
```
rtsp://<telescope_ip>/<stream_selector>/stream0
```
- `<stream_selector>` comes from `StreamTypeAnn` (`com.convergence.dwarflab.data.bean.camera`).
- Player options force `rtsp_transport = tcp` (see `RtspPlayerView.java:195`).
- Two cameras exist: **Tele** (main/long-focus) and **Wide** (wide-angle/guide).
---
## 3. Wire format — `WsPacket` envelope
Every WebSocket binary frame is **one serialized `WsPacket`** (`base.proto`):
```proto
message WsPacket {
uint32 major_version = 1; // = 2 (WS_MAJOR_VERSION_NUMBER)
uint32 minor_version = 2; // = 3 (WS_MINOR_VERSION_NUMBER) → protocol v2.3
uint32 device_id = 3; // telescope index, default 1
uint32 module_id = 4; // derived from cmd (see §4)
uint32 cmd = 5; // operation id (1000017099)
uint32 type = 6; // 0=request 1=response 2=notification 3=reply
bytes data = 7; // inner protobuf message, serialized
string client_id = 8; // same client_id as the WS URL
}
```
Confirmed build code (`e49.java`, `C9312a.m36361a`):
```java
WsPacket.newBuilder()
.setMajorVersion(2)
.setMinorVersion(3)
.setDeviceId(connectedDeviceId != null ? connectedDeviceId : 1)
.setModuleId(wsCmd.getModuleId().ordinal()) // derived from cmd range
.setCmd(wsCmd.getCmd())
.setType(wsCmd.getMessageType().ordinal()) // request=0
.setData(ByteString.copyFrom(innerProto.toByteArray()))
.setClientId(clientId)
.build();
```
`type` enum (`WsMessageType`): `request=0`, `response=1`, `notification=2`, `reply=3`.
### 3.1 Request/response matching
Responses are matched by **`cmd`**. The app registers a pending continuation
keyed by the expected response `cmd`; an incoming `WsPacket` whose `cmd` matches
is parsed (`WsRequestHandle.mo7785d``BaseProto.WsPacket.parseFrom`, then the
inner `data` is parsed into the expected proto class).
For most commands the **response uses the same `cmd`** as the request
(`WsMessageReq.getResponseCmd()` defaults to `getCmd()`, see `d49.m35708a`).
**IMPORTANT — discovered via live testing (not in the APK code):**
The telescope uses **`type=3` (REPLY)** for direct responses, not `type=1`
(RESPONSE). Additionally, not all commands get a reply:
| Response model | Commands (tested) | Implementation |
|---------------|-------------------|----------------|
| **type=3 reply (same cmd)** | photo (10002), photo wide (12022), focus auto (15000), focus step (15001), state (16405), sync-time (13000), set-location (13010) | request-response with timeout |
| **notification only (type=2)** | RGB on/off (13500/13501), camera open/close (10000/10001), camera params GET (10036) | fire-and-forget; verify via `state` |
| **fire-and-forget native** | motor slew (14006), motor stop (14002) | no ack expected |
Commands that only produce notifications still execute successfully — the
state change is visible in `GetDeviceState` (e.g. `rgb_state:{}` after RGB off).
### 3.2 Notifications
The telescope pushes `WsPacket` frames with `type=2` (notification) and `cmd` in
the **1520015303** range (`CMD_NOTIFY_*`). An OSS client must listen for these
to reflect state changes (track results, burst/record progress, temperatures,
calibration state, SD-card info, power, etc.). See `Notify.proto` (81 messages)
and `CMD_TABLE.md` (NOTIFY module).
---
## 4. Command routing
`module_id` is **not** stored per-command — it is derived from `cmd` by range
checks in `WsCmd.getModuleId()`:
| cmd range | module_id (ordinal) | module | proto file |
|-----------|---------------------|--------|------------|
| 1000010499 | 1 | CAMERA_TELE | `Camera.proto` |
| 1100011499 | 3 | ASTRO | `Astro.proto` |
| 1200012499 | 2 | CAMERA_WIDE | `Camera.proto` |
| 1300013299 | 4 | SYSTEM | `System.proto` |
| 1350013799 | 5 | RGB_POWER | (RGB led / power) |
| 1400014499 | 6 | MOTOR | `MotorControl.proto` |
| 1480014899 | 7 | TRACK | `Track.proto` |
| 1500015199 | 8 | FOCUS | `Focus.proto` |
| 1520015499 | 9 | NOTIFY | `Notify.proto` |
| 1550015599 | 10 | PANORAMA | `Panorama.proto` |
| 1570015799 | 11 | ITIPS | `ITips.proto` |
| 1610016399 | 13 | SHOOTING_SCHEDULE | `Schedule.proto` |
| 1640016599 | 14 | TASK_CENTER | `TaskCenter.proto` |
| 1670016799 | 15 | PARAM | `Param.proto` |
| 1680016899 | 16 | VOICE_ASSISTANT | `VoiceAssistant.proto` |
| 1700017099 | 18 | DEVICE | `Device.proto` |
**Full table of all 323 commands → see [`CMD_TABLE.md`](CMD_TABLE.md).**
The mapping from command → inner protobuf message type lives in the
`data/websocket/<module>/` handlers (`*WsResponseHandle.java`) and the
`data/bean/p021ws/request/` request classes. To find the payload type for a
given cmd, grep the request package.
---
## 5. Proto definitions
Regenerated cleanly from the embedded `FileDescriptorProto` descriptors in the
APK — **17 files, 382 messages**. Located in `analysis/protos/`:
| File | msgs | Covers |
|------|------|--------|
| `Base.proto` | 6 | WsPacket envelope, ComResponse, CommonParam |
| `Camera.proto` | 55 | Both cameras: exp/gain/WB/ISP/RAW/record/burst/resolution |
| `Astro.proto` | 67 | Calibration, GOTO (DSO/solar), live-stacking, darks, EQ solving, AI enhance, mosaic, sky-finder |
| `MotorControl.proto` | 14 | RA/DEC motors: run/stop/runTo/joystick/reset/positions |
| `Track.proto` | 9 | Tracking, sentry mode, MOT, UFO (multi-object track) |
| `Focus.proto` | 9 | Auto-focus (normal + astro), manual continuous, user infinity |
| `Panorama.proto` | 18 | Grid/stitch/framing/upload/compress |
| `Notify.proto` | 81 | All async server-push events |
| `Schedule.proto` | 20 | Shooting plan sync/cancel/lock |
| `TaskCenter.proto` | 26 | Global task manager, state info, mode/tech switch |
| `System.proto` | 14 | Time/timezone, location, MTP, CPU mode, activation, low-temp protection |
| `Param.proto` | 8 | Generic param set (exposure/gain/WB/int/float/bool/auto) |
| `Device.proto` | 3 | Lens defog, auto-cooling, auto-shutdown |
| `Ble.proto` | 25 | BLE handshake (DwarfPing/DwarfEcho/config/AP/STA/wifi-scan) |
| `VoiceAssistant.proto` | 16 | On-device voice assistant tasking |
| `RGB.proto` | 6 | RGB LED ring / power indicator |
| `ITips.proto` | 5 | Tips content |
To regenerate: `python3 analysis/extract_protos.py <jadx proto dir> <out dir>`
---
## 6. Worked example — take a photo with the Tele camera
1. **(once)** BLE: connect, get `DwarfEcho` → extract `sta.ipv4`/`ap.ipv4`,
`psw`, join Wi-Fi.
2. Open WebSocket `ws://<ip>:9900/?client_id=droid-oss-001`.
3. Open the Tele camera: send `WsPacket{cmd=10000, data=ReqOpenCamera}`,
wait for `ComResponse{code=0}`.
4. Set exposure (optional): `cmd=10009` with `ReqSetExp{…}`.
5. Photograph: `cmd=10002` (`CMD_CAMERA_TELE_PHOTOGRAPH`).
6. Watch notifications `15273` (PHOTO_STATE) / `15274` (BURST_STATE) for result.
Common response type is `ComResponse{ int32 code = 1; }``code==0` means OK.
---
## 7. Parameter value maps (assets)
The APK ships ready-made enum maps that constrain valid values:
- **`assets/params_range.json`** — exposure index ↔ `"1/N"` label (0…full
mapping, e.g. index 0 = "1/10000", step 3).
- **`assets/shoot_plan_config.json`** — per-device capability matrix. Defines
DWARF II (id=1, fw 2.1.6): two cameras (`Tele` id=0, `Wide` implicit),
their FoV (`fvWidth/fvHeight`), preview size (1280×720), and every supported
param with `min/max/step/defaultValue/valueType` + Gear vs Continue modes.
This file is the authoritative source for **what values each camera accepts**.
- **`assets/astronomy_data.db`** — SQLite of celestial objects (GOTO targets).
- **`assets/www/modules/eq/`** — Three.js 3D equatorial-alignment helper
(polar-alignment UI). "Bilbo" = next-gen model codename (DWARF III).
---
## 8. Multi-device & activation notes
- `device_id` in `WsPacket` selects the active telescope when several are on the
same network; default `1`.
- Some telescopes are **factory-activated** via `CMD_SYSTEM_*` (1300513008):
`ReqGetDeviceActivateInfo`, `ReqDeviceActivateWriteFile`, activation-notify,
factory-test un-activate. An OSS client should generally leave activation
alone.
- `CMD_SYSTEM_SET_MASTER` (13004) toggles master/slave mode
(`ReqsetMasterLock{bool lock}`).
- MTP mode (`CMD_SYSTEM_SET_MTP_MODE`, 13002) switches the telescope between
Mass-Storage (mount SD card over USB) and normal modes.
---
## 9. Suggested open-source client architecture
```
dwarf-oss/
├── proto/ ← copy analysis/protos/*.proto here
├── ble/ ← BLE scanner + DwarfPing/DwarfEcho handshake (ble.proto)
├── transport/
│ ├── ws_client.py ← ws://<ip>:9900/?client_id=…, send/recv WsPacket
│ ├── envelope.py ← WsPacket build/parse (Base.proto)
│ └── dispatcher.py ← cmd → pending-request matching, NOTIFY fan-out
├── rtsp/ ← GStreamer/ffmpeg/PyAV pull of rtsp://<ip>/<cam>/stream0
├── modules/
│ ├── camera.py ← cmds 10000/12000 (Tele/Wide)
│ ├── motor.py ← cmds 14000 (point/slew)
│ ├── astro.py ← cmds 11000 (calib/goto/stacking/darks)
│ ├── focus.py ← cmds 15000
│ ├── track.py ← cmds 14800
│ └── task.py ← cmds 16400 (one-click shooting)
└── cli.py ← `dwarf photo`, `dwarf goto M31`, `dwarf slew 1.2 0`
```
Key implementation tips:
- Send `major_version=2, minor_version=3` always.
- Reuse one persistent WebSocket; don't reconnect per command.
- Maintain a registry of `cmd → asyncio.Future` for request/response; a single
inbound dispatcher handles both responses and notifications.
- Start with `CMD_GLOBAL_TASK_GET_DEVICE_STATE_INFO` (16405) after connect to
snapshot the current state, then rely on NOTIFY pushes.
- For live view, a separate RTSP consumer is simpler than multiplexing over the
WebSocket.
---
## 10. Tooling used / how to reproduce
```
tools/jadx/bin/jadx -d extracted/jadx DWARFLAB.apk # decompile
python3 analysis/extract_protos.py extracted/.../proto analysis/protos
# WsCmd / WsModuleId / WsMessageType enums → analysis/CMD_TABLE.md
```
Key source locations inside `extracted/jadx/sources/`:
- `com/convergence/dwarflab/proto/` — 17 `*Proto.java` (descriptors).
- `com/convergence/dwarflab/data/bean/p021ws/WsCmd.java` — all command ids.
- `…/WsModuleId.java`, `…/WsMessageType.java` — enums.
- `…/request/WsMessageReq.java` — request interface (`d49.java` = sender).
- `com/convergence/dwarflab/data/websocket/<module>/` — per-module handlers.
- `p000/e49.java` — WsPacket builder (`C9312a.m36361a`).
- `p000/v55.java` — WebSocket connection manager (URL/port 9900).
- `p000/b49.java` — OkHttp WebSocket wrapper.

330
analysis/CMD_TABLE.md Normal file
View File

@ -0,0 +1,330 @@
# DWARFLAB Command Routing Table
Auto-extracted from `WsCmd.java` + `WsModuleId.java`. `module_id` is derived from `cmd` by range.
Total: **323 commands** across **16 modules**.
| cmd | module | name |
|-----|--------|------|
| 10000 | CAMERA_TELE | CMD_CAMERA_TELE_OPEN_CAMERA |
| 10001 | CAMERA_TELE | CMD_CAMERA_TELE_CLOSE_CAMERA |
| 10002 | CAMERA_TELE | CMD_CAMERA_TELE_PHOTOGRAPH |
| 10003 | CAMERA_TELE | CMD_CAMERA_TELE_BURST |
| 10004 | CAMERA_TELE | CMD_CAMERA_TELE_STOP_BURST |
| 10005 | CAMERA_TELE | CMD_CAMERA_TELE_START_RECORD |
| 10006 | CAMERA_TELE | CMD_CAMERA_TELE_STOP_RECORD |
| 10007 | CAMERA_TELE | CMD_CAMERA_TELE_SET_EXP_MODE |
| 10008 | CAMERA_TELE | CMD_CAMERA_TELE_GET_EXP_MODE |
| 10009 | CAMERA_TELE | CMD_CAMERA_TELE_SET_EXP |
| 10010 | CAMERA_TELE | CMD_CAMERA_TELE_GET_EXP |
| 10011 | CAMERA_TELE | CMD_CAMERA_TELE_SET_GAIN_MODE |
| 10012 | CAMERA_TELE | CMD_CAMERA_TELE_GET_GAIN_MODE |
| 10013 | CAMERA_TELE | CMD_CAMERA_TELE_SET_GAIN |
| 10014 | CAMERA_TELE | CMD_CAMERA_TELE_GET_GAIN |
| 10015 | CAMERA_TELE | CMD_CAMERA_TELE_SET_BRIGHTNESS |
| 10016 | CAMERA_TELE | CMD_CAMERA_TELE_GET_BRIGHTNESS |
| 10017 | CAMERA_TELE | CMD_CAMERA_TELE_SET_CONTRAST |
| 10018 | CAMERA_TELE | CMD_CAMERA_TELE_GET_CONTRAST |
| 10019 | CAMERA_TELE | CMD_CAMERA_TELE_SET_SATURATION |
| 10020 | CAMERA_TELE | CMD_CAMERA_TELE_GET_SATURATION |
| 10021 | CAMERA_TELE | CMD_CAMERA_TELE_SET_HUE |
| 10022 | CAMERA_TELE | CMD_CAMERA_TELE_GET_HUE |
| 10023 | CAMERA_TELE | CMD_CAMERA_TELE_SET_SHARPNESS |
| 10024 | CAMERA_TELE | CMD_CAMERA_TELE_GET_SHARPNESS |
| 10025 | CAMERA_TELE | CMD_CAMERA_TELE_SET_WB_MODE |
| 10026 | CAMERA_TELE | CMD_CAMERA_TELE_GET_WB_MODE |
| 10027 | CAMERA_TELE | CMD_CAMERA_TELE_SET_WB_SCENE |
| 10028 | CAMERA_TELE | CMD_CAMERA_TELE_GET_WB_SCENE |
| 10029 | CAMERA_TELE | CMD_CAMERA_TELE_SET_WB_CT |
| 10030 | CAMERA_TELE | CMD_CAMERA_TELE_GET_WB_CT |
| 10031 | CAMERA_TELE | CMD_CAMERA_TELE_SET_IRCUT |
| 10032 | CAMERA_TELE | CMD_CAMERA_TELE_GET_IRCUT |
| 10033 | CAMERA_TELE | CMD_CAMERA_TELE_START_TIMELAPSE_PHOTO |
| 10034 | CAMERA_TELE | CMD_CAMERA_TELE_STOP_TIMELAPSE_PHOTO |
| 10035 | CAMERA_TELE | CMD_CAMERA_TELE_SET_ALL_PARAMS |
| 10036 | CAMERA_TELE | CMD_CAMERA_TELE_GET_ALL_PARAMS |
| 10037 | CAMERA_TELE | CMD_CAMERA_TELE_SET_FEATURE_PARAM |
| 10038 | CAMERA_TELE | CMD_CAMERA_TELE_GET_ALL_FEATURE_PARAMS |
| 10039 | CAMERA_TELE | CMD_CAMERA_TELE_GET_SYSTEM_WORKING_STATE |
| 10040 | CAMERA_TELE | CMD_CAMERA_TELE_SET_JPG_QUALITY |
| 10041 | CAMERA_TELE | CMD_CAMERA_TELE_PHOTO_RAW |
| 10042 | CAMERA_TELE | CMD_CAMERA_TELE_SET_RTSP_BITRATE_TYPE |
| 10043 | CAMERA_TELE | CMD_CAMERA_TELE_DISABLE_ALL_ISP_PROCESSING |
| 10044 | CAMERA_TELE | CMD_CAMERA_TELE_ENABLE_ALL_ISP_PROCESSING |
| 10045 | CAMERA_TELE | CMD_CAMERA_TELE_SET_ISP_MODULE_STATE |
| 10046 | CAMERA_TELE | CMD_CAMERA_TELE_GET_ISP_MODULE_STATE |
| 10047 | CAMERA_TELE | CMD_CAMERA_TELE_SWITCH_RESOLUTION |
| 10048 | CAMERA_TELE | CMD_CAMERA_TELE_SWITCH_FRAMERATE |
| 10049 | CAMERA_TELE | CMD_CAMERA_TELE_SWITCH_CROP_RATIO |
| 10050 | CAMERA_TELE | CMD_CAMERA_TELE_SET_PREVIEW_QUALITY |
| 11000 | ASTRO | CMD_ASTRO_START_CALIBRATION |
| 11001 | ASTRO | CMD_ASTRO_STOP_CALIBRATION |
| 11002 | ASTRO | CMD_ASTRO_START_GOTO_DSO |
| 11003 | ASTRO | CMD_ASTRO_START_GOTO_SOLAR_SYSTEM |
| 11004 | ASTRO | CMD_ASTRO_STOP_GOTO |
| 11005 | ASTRO | CMD_ASTRO_START_CAPTURE_RAW_LIVE_STACKING |
| 11006 | ASTRO | CMD_ASTRO_STOP_CAPTURE_RAW_LIVE_STACKING |
| 11007 | ASTRO | CMD_ASTRO_START_CAPTURE_RAW_DARK |
| 11008 | ASTRO | CMD_ASTRO_STOP_CAPTURE_RAW_DARK |
| 11009 | ASTRO | CMD_ASTRO_CHECK_GOT_DARK |
| 11010 | ASTRO | CMD_ASTRO_GO_LIVE |
| 11011 | ASTRO | CMD_ASTRO_START_TRACK_SPECIAL_TARGET |
| 11012 | ASTRO | CMD_ASTRO_STOP_TRACK_SPECIAL_TARGET |
| 11013 | ASTRO | CMD_ASTRO_START_ONE_CLICK_GOTO_DSO |
| 11014 | ASTRO | CMD_ASTRO_START_ONE_CLICK_GOTO_SOLAR_SYSTEM |
| 11015 | ASTRO | CMD_ASTRO_STOP_ONE_CLICK_GOTO |
| 11016 | ASTRO | CMD_ASTRO_START_WIDE_CAPTURE_LIVE_STACKING |
| 11017 | ASTRO | CMD_ASTRO_STOP_WIDE_CAPTURE_LIVE_STACKING |
| 11018 | ASTRO | CMD_ASTRO_START_EQ_SOLVING |
| 11019 | ASTRO | CMD_ASTRO_STOP_EQ_SOLVING |
| 11020 | ASTRO | CMD_ASTRO_WIDE_GO_LIVE |
| 11021 | ASTRO | CMD_ASTRO_START_CAPTURE_RAW_DARK_WITH_PARAM |
| 11022 | ASTRO | CMD_ASTRO_STOP_CAPTURE_RAW_DARK_WITH_PARAM |
| 11023 | ASTRO | CMD_ASTRO_GET_DARK_FRAME_LIST |
| 11024 | ASTRO | CMD_ASTRO_DEL_DARK_FRAME_LIST |
| 11025 | ASTRO | CMD_ASTRO_START_CAPTURE_WIDE_RAW_DARK_WITH_PARAM |
| 11026 | ASTRO | CMD_ASTRO_STOP_CAPTURE_WIDE_RAW_DARK_WITH_PARAM |
| 11027 | ASTRO | CMD_ASTRO_GET_WIDE_DARK_FRAME_LIST |
| 11028 | ASTRO | CMD_ASTRO_DEL_WIDE_DARK_FRAME_LIST |
| 11029 | ASTRO | CMD_ASTRO_START_AI_ENHANCE |
| 11030 | ASTRO | CMD_ASTRO_STOP_AI_ENHANCE |
| 11031 | ASTRO | CMD_ASTRO_START_TELE_MOSAIC |
| 11032 | ASTRO | CMD_ASTRO_CHECK_IF_RESTACKABLE |
| 11033 | ASTRO | CMD_ASTRO_START_MAKE_FITS_THUMB |
| 11034 | ASTRO | CMD_ASTRO_STOP_MAKE_FITS_THUMB |
| 11035 | ASTRO | CMD_ASTRO_START_RESTACKED |
| 11036 | ASTRO | CMD_ASTRO_STOP_RESTACKED |
| 11037 | ASTRO | CMD_ASTRO_FAST_STOP_CAPTURE_RAW_LIVE_STACKING |
| 11038 | ASTRO | CMD_ASTRO_FAST_STOP_WIDE_CAPTURE_LIVE_STACKING |
| 11039 | ASTRO | CMD_ASTRO_GET_ASTRO_SHOOTING_TIME |
| 11040 | ASTRO | CMD_ASTRO_GET_QUICK_SET_LIST |
| 11041 | ASTRO | CMD_ASTRO_SET_QUICK_SET |
| 11042 | ASTRO | CMD_ASTRO_START_ONE_CLICK_SHOOTING |
| 11043 | ASTRO | CMD_ASTRO_GET_CALI_FRAME_LIST |
| 11044 | ASTRO | CMD_ASTRO_DEL_CALI_FRAME_LIST |
| 11045 | ASTRO | CMD_ASTRO_START_CAPTURE_CALI_FRAME |
| 11046 | ASTRO | CMD_ASTRO_STOP_CAPTURE_CALI_FRAME |
| 11047 | ASTRO | CMD_ASTRO_START_SKY_TARGET_FINDER |
| 11048 | ASTRO | CMD_ASTRO_STOP_SKY_TARGET_FINDER |
| 12000 | CAMERA_WIDE | CMD_CAMERA_WIDE_OPEN_CAMERA |
| 12001 | CAMERA_WIDE | CMD_CAMERA_WIDE_CLOSE_CAMERA |
| 12002 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_EXP_MODE |
| 12003 | CAMERA_WIDE | CMD_CAMERA_WIDE_GET_EXP_MODE |
| 12004 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_EXP |
| 12005 | CAMERA_WIDE | CMD_CAMERA_WIDE_GET_EXP |
| 12006 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_GAIN |
| 12007 | CAMERA_WIDE | CMD_CAMERA_WIDE_GET_GAIN |
| 12008 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_BRIGHTNESS |
| 12009 | CAMERA_WIDE | CMD_CAMERA_WIDE_GET_BRIGHTNESS |
| 12010 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_CONTRAST |
| 12011 | CAMERA_WIDE | CMD_CAMERA_WIDE_GET_CONTRAST |
| 12012 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_SATURATION |
| 12013 | CAMERA_WIDE | CMD_CAMERA_WIDE_GET_SATURATION |
| 12014 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_HUE |
| 12015 | CAMERA_WIDE | CMD_CAMERA_WIDE_GET_HUE |
| 12016 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_SHARPNESS |
| 12017 | CAMERA_WIDE | CMD_CAMERA_WIDE_GET_SHARPNESS |
| 12018 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_WB_MODE |
| 12019 | CAMERA_WIDE | CMD_CAMERA_WIDE_GET_WB_MODE |
| 12020 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_WB_CT |
| 12021 | CAMERA_WIDE | CMD_CAMERA_WIDE_GET_WB_CT |
| 12022 | CAMERA_WIDE | CMD_CAMERA_WIDE_PHOTOGRAPH |
| 12023 | CAMERA_WIDE | CMD_CAMERA_WIDE_BURST |
| 12024 | CAMERA_WIDE | CMD_CAMERA_WIDE_STOP_BURST |
| 12025 | CAMERA_WIDE | CMD_CAMERA_WIDE_START_TIMELAPSE_PHOTO |
| 12026 | CAMERA_WIDE | CMD_CAMERA_WIDE_STOP_TIMELAPSE_PHOTO |
| 12027 | CAMERA_WIDE | CMD_CAMERA_WIDE_GET_ALL_PARAMS |
| 12028 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_ALL_PARAMS |
| 12029 | CAMERA_WIDE | CMD_CAMERA_WIDE_PHOTO_RAW |
| 12030 | CAMERA_WIDE | CMD_CAMERA_WIDE_START_RECORD |
| 12031 | CAMERA_WIDE | CMD_CAMERA_WIDE_STOP_RECORD |
| 12032 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_RTSP_BITRATE_TYPE |
| 12035 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_WB_SCENE |
| 12036 | CAMERA_WIDE | CMD_CAMERA_WIDE_SET_PREVIEW_QUALITY |
| 13000 | SYSTEM | CMD_SYSTEM_SET_TIME |
| 13001 | SYSTEM | CMD_SYSTEM_SET_TIME_ZONE |
| 13002 | SYSTEM | CMD_SYSTEM_SET_MTP_MODE |
| 13003 | SYSTEM | CMD_SYSTEM_SET_CPU_MODE |
| 13004 | SYSTEM | CMD_SYSTEM_SET_MASTER |
| 13005 | SYSTEM | CMD_SYSTEM_GET_DEVICE_ACTIVATE_INFO |
| 13006 | SYSTEM | CMD_SYSTEM_DEVICE_ACTIVATE_WRITE_FILE |
| 13007 | SYSTEM | CMD_SYSTEM_DEVICE_ACTIVATE_NOTIFY_ACTIVATE_SUCCESSFULL |
| 13008 | SYSTEM | CMD_SYSTEM_FACTORY_TEST_UN_ACTIVATE |
| 13009 | SYSTEM | CMD_SYSTEM_SET_LOW_TEMP_PROTECTION_MODE |
| 13010 | SYSTEM | CMD_SYSTEM_SET_LOCATION |
| 13500 | RGB_POWER | CMD_RGB_POWER_OPEN_RGB |
| 13501 | RGB_POWER | CMD_RGB_POWER_CLOSE_RGB |
| 13502 | RGB_POWER | CMD_RGB_POWER_POWER_DOWN |
| 13503 | RGB_POWER | CMD_RGB_POWER_POWERIND_ON |
| 13504 | RGB_POWER | CMD_RGB_POWER_POWERIND_OFF |
| 13505 | RGB_POWER | CMD_RGB_POWER_REBOOT |
| 14000 | MOTOR | CMD_STEP_MOTOR_RUN |
| 14002 | MOTOR | CMD_STEP_MOTOR_STOP |
| 14006 | MOTOR | CMD_STEP_MOTOR_SERVICE_JOYSTICK |
| 14007 | MOTOR | CMD_STEP_MOTOR_SERVICE_JOYSTICK_FIXED_ANGLE |
| 14008 | MOTOR | CMD_STEP_MOTOR_SERVICE_JOYSTICK_STOP |
| 14009 | MOTOR | CMD_STEP_MOTOR_SERVICE_DUAL_CAMERA_LINKAGE |
| 14800 | TRACK | CMD_TRACK_START_TRACK |
| 14801 | TRACK | CMD_TRACK_STOP_TRACK |
| 14802 | TRACK | CMD_SENTRY_MODE_START |
| 14803 | TRACK | CMD_SENTRY_MODE_STOP |
| 14804 | TRACK | CMD_MOT_START |
| 14805 | TRACK | CMD_MOT_TRACK_ONE |
| 14806 | TRACK | CMD_UFOTRACK_MODE_START |
| 14807 | TRACK | CMD_UFOTRACK_MODE_STOP |
| 14808 | TRACK | CMD_MOT_WIDE_TRACK_ONE |
| 14809 | TRACK | CMD_SWITCH_MAIN_PREVIEW |
| 14810 | TRACK | CMD_UFO_HAND_AOTO_MODE |
| 14811 | TRACK | CMD_SENTRY_SCENE_SELECT |
| 14812 | TRACK | CMD_TRACK_START_CLICK |
| 15000 | FOCUS | CMD_FOCUS_AUTO_FOCUS |
| 15001 | FOCUS | CMD_FOCUS_MANUAL_SINGLE_STEP_FOCUS |
| 15002 | FOCUS | CMD_FOCUS_START_MANUAL_CONTINU_FOCUS |
| 15003 | FOCUS | CMD_FOCUS_STOP_MANUAL_CONTINU_FOCUS |
| 15004 | FOCUS | CMD_FOCUS_START_ASTRO_AUTO_FOCUS |
| 15005 | FOCUS | CMD_FOCUS_STOP_ASTRO_AUTO_FOCUS |
| 15011 | FOCUS | CMD_FOCUS_GET_USER_INFINITY_POS |
| 15012 | FOCUS | CMD_FOCUS_SET_USER_INFINITY_POS |
| 15200 | NOTIFY | CMD_NOTIFY_TELE_WIDE_PICTURE_MATCHING |
| 15201 | NOTIFY | CMD_NOTIFY_ELE |
| 15202 | NOTIFY | CMD_NOTIFY_CHARGE |
| 15203 | NOTIFY | CMD_NOTIFY_SDCARD_INFO |
| 15204 | NOTIFY | CMD_NOTIFY_TELE_RECORD_TIME |
| 15205 | NOTIFY | CMD_NOTIFY_TELE_TIMELAPSE_OUT_TIME |
| 15206 | NOTIFY | CMD_NOTIFY_STATE_CAPTURE_RAW_DARK |
| 15207 | NOTIFY | CMD_NOTIFY_PROGRASS_CAPTURE_RAW_DARK |
| 15208 | NOTIFY | CMD_NOTIFY_STATE_CAPTURE_RAW_LIVE_STACKING |
| 15209 | NOTIFY | CMD_NOTIFY_PROGRASS_CAPTURE_RAW_LIVE_STACKING |
| 15210 | NOTIFY | CMD_NOTIFY_STATE_ASTRO_CALIBRATION |
| 15211 | NOTIFY | CMD_NOTIFY_STATE_ASTRO_GOTO |
| 15212 | NOTIFY | CMD_NOTIFY_STATE_ASTRO_TRACKING |
| 15213 | NOTIFY | CMD_NOTIFY_TELE_SET_PARAM |
| 15214 | NOTIFY | CMD_NOTIFY_WIDE_SET_PARAM |
| 15215 | NOTIFY | CMD_NOTIFY_TELE_FUNCTION_STATE |
| 15216 | NOTIFY | CMD_NOTIFY_WIDE_FUNCTION_STATE |
| 15217 | NOTIFY | CMD_NOTIFY_SET_FEATURE_PARAM |
| 15218 | NOTIFY | CMD_NOTIFY_TELE_BURST_PROGRESS |
| 15219 | NOTIFY | CMD_NOTIFY_PANORAMA_PROGRESS |
| 15220 | NOTIFY | CMD_NOTIFY_WIDE_BURST_PROGRESS |
| 15221 | NOTIFY | CMD_NOTIFY_RGB_STATE |
| 15222 | NOTIFY | CMD_NOTIFY_POWER_IND_STATE |
| 15223 | NOTIFY | CMD_NOTIFY_WS_HOST_SLAVE_MODE |
| 15224 | NOTIFY | CMD_NOTIFY_MTP_STATE |
| 15225 | NOTIFY | CMD_NOTIFY_TRACK_RESULT |
| 15226 | NOTIFY | CMD_NOTIFY_WIDE_TIMELAPSE_OUT_TIME |
| 15227 | NOTIFY | CMD_NOTIFY_CPU_MODE |
| 15228 | NOTIFY | CMD_NOTIFY_STATE_ASTRO_TRACKING_SPECIAL |
| 15229 | NOTIFY | CMD_NOTIFY_POWER_OFF |
| 15230 | NOTIFY | CMD_NOTIFY_ALBUM_UPDATE |
| 15231 | NOTIFY | CMD_NOTIFY_SENTRY_MODE_STATE |
| 15232 | NOTIFY | CMD_NOTIFY_SENTRY_MODE_TRACK_RESULT |
| 15233 | NOTIFY | CMD_NOTIFY_STATE_ASTRO_ONE_CLICK_GOTO |
| 15234 | NOTIFY | CMD_NOTIFY_STREAM_TYPE |
| 15235 | NOTIFY | CMD_NOTIFY_WIDE_RECORD_TIME |
| 15236 | NOTIFY | CMD_NOTIFY_STATE_WIDE_CAPTURE_RAW_LIVE_STACKING |
| 15237 | NOTIFY | CMD_NOTIFY_PROGRASS_WIDE_CAPTURE_RAW_LIVE_STACKING |
| 15238 | NOTIFY | CMD_NOTIFY_MULTI_TRACK_RESULT |
| 15239 | NOTIFY | CMD_NOTIFY_EQ_SOLVING_STATE |
| 15240 | NOTIFY | CMD_NOTIFY_UFO_MODE_STATE |
| 15241 | NOTIFY | CMD_NOTIFY_TELE_LONG_EXP_PROGRESS |
| 15242 | NOTIFY | CMD_NOTIFY_WIDE_LONG_EXP_PROGRESS |
| 15243 | NOTIFY | CMD_NOTIFY_TEMPERATURE |
| 15244 | NOTIFY | CMD_NOTIFY_PANORAMA_UPLOAD_COMPRESS_PROGRESS |
| 15245 | NOTIFY | CMD_NOTIFY_PANORAMA_UPLOAD_COMPLETE |
| 15245 | NOTIFY | CMD_NOTIFY_PANORAMA_UPLOAD_UPLOAD_PROGRESS |
| 15247 | NOTIFY | CMD_NOTIFY_STATE_CAPTURE_WIDE_RAW_DARK |
| 15248 | NOTIFY | CMD_NOTIFY_SHOOTING_SCHEDULE_RESULT_AND_STATE |
| 15249 | NOTIFY | CMD_NOTIFY_SHOOTING_TASK_STATE |
| 15250 | NOTIFY | CMD_NOTIFY_SKY_SEACHER_STATE |
| 15251 | NOTIFY | CMD_NOTIFY_WIDE_MULTI_TRACK_RESULT |
| 15252 | NOTIFY | CMD_NOTIFY_WIDE_TRACK_RESULT |
| 15253 | NOTIFY | CMD_NOTIFY_STATE_AI_ENHANCE |
| 15254 | NOTIFY | CMD_NOTIFY_PROGRESS_AI_ENHANCE |
| 15255 | NOTIFY | CMD_NOTIFY_WAIT_SHOOTING_PROGRESS |
| 15256 | NOTIFY | CMD_NOTIFY_CALIBRATION_RESULT |
| 15257 | NOTIFY | CMD_NOTIFY_FOCUS_POSITION |
| 15258 | NOTIFY | CMD_NOTIFY_UFO_AUTO_HAND_MODE |
| 15259 | NOTIFY | CMD_NOTIFY_CURRENT_PANORAMA_UPLOAD_STATE |
| 15260 | NOTIFY | CMD_NOTIFY_LOW_TEMP_PROTECTION_MODE |
| 15261 | NOTIFY | CMD_NOTIFY_EXCLUSIVE_SYSTEM_IO_TASK_STATE |
| 15262 | NOTIFY | CMD_NOTIFY_BODY_STATUS |
| 15263 | NOTIFY | CMD_NOTIFY_PROGRESS_CAPTURE_MOSAIC |
| 15264 | NOTIFY | CMD_NOTIFY_GENERAL_INT_PARAM |
| 15265 | NOTIFY | CMD_NOTIFY_GENERAL_FLOAT_PARAM |
| 15266 | NOTIFY | CMD_NOTIFY_GENERAL_BOOL_PARAM |
| 15267 | NOTIFY | CMD_NOTIFY_SWITCH_SHOOTING_MODE |
| 15268 | NOTIFY | CMD_NOTIFY_TELE_SWITCH_CROP_RATIO |
| 15269 | NOTIFY | CMD_NOTIFY_TELE_SHOOTING_TECH_STATE |
| 15270 | NOTIFY | CMD_NOTIFY_WB |
| 15271 | NOTIFY | CMD_NOTIFY_WIDE_SHOOTING_TECH_STATE |
| 15272 | NOTIFY | CMD_NOTIFY_RESOLUTION_PARAM |
| 15273 | NOTIFY | CMD_NOTIFY_PHOTO_STATE |
| 15274 | NOTIFY | CMD_NOTIFY_BURST_STATE |
| 15275 | NOTIFY | CMD_NOTIFY_RECORD_STATE |
| 15276 | NOTIFY | CMD_NOTIFY_TIMELAPSE_STATE |
| 15277 | NOTIFY | CMD_NOTIFY_PANORAMA_STATE |
| 15278 | NOTIFY | CMD_NOTIFY_ASTRO_AUTO_FOCUS_STATE |
| 15279 | NOTIFY | CMD_NOTIFY_NORMAL_AUTO_FOCUS_STATE |
| 15280 | NOTIFY | CMD_NOTIFY_ASTRO_AUTO_FOCUS_FAST_STATE |
| 15281 | NOTIFY | CMD_NOTIFY_AREA_AUTO_FOCUS_STATE |
| 15282 | NOTIFY | CMD_NOTIFY_DUAL_CAMERA_LINKAGE_STATE |
| 15283 | NOTIFY | CMD_NOTIFY_RESOLUTION_FPS_STATE |
| 15284 | NOTIFY | CMD_NOTIFY_NORMAL_TRACK_STATE |
| 15285 | NOTIFY | CMD_NOTIFY_BURST_PROGRESS |
| 15286 | NOTIFY | CMD_NOTIFY_RECORD_TIME |
| 15287 | NOTIFY | CMD_NOTIFY_TIMELAPSE_OUT_TIME |
| 15288 | NOTIFY | CMD_NOTIFY_LONG_EXP_PROGRESS |
| 15289 | NOTIFY | CMD_NOTIFY_SENTRY_MOTOR_STATE |
| 15290 | NOTIFY | CMD_NOTIFY_STATE_CAPTURE_CALI_FRAME |
| 15291 | NOTIFY | CMD_NOTIFY_PROGRESS_CAPTURE_CALI_FRAME |
| 15292 | NOTIFY | CMD_NOTIFY_CMOS_TEMPERATURE |
| 15293 | NOTIFY | CMD_NOTIFY_PANORAMA_COMPRESS_PROGRESS |
| 15294 | NOTIFY | CMD_NOTIFY_PANORAMA_COMPRESS_COMPLETE |
| 15295 | NOTIFY | CMD_NOTIFY_DEVICE_ATTITUDE |
| 15296 | NOTIFY | CMD_NOTIFY_SKY_TARGET_FINDER_STATE |
| 15297 | NOTIFY | CMD_NOTIFY_PANO_FRAMING_RECT_UPDATE |
| 15298 | NOTIFY | CMD_NOTIFY_PANO_FRAMING_THUMBNAIL_UPDATE |
| 15299 | NOTIFY | CMD_NOTIFY_PANO_FRAMING_STATE |
| 15300 | NOTIFY | CMD_NOTIFY_WIDE_FOCUS_POSITION |
| 15301 | NOTIFY | CMD_NOTIFY_LENS_DEFOG_STATE |
| 15302 | NOTIFY | CMD_NOTIFY_AUTO_COOLING_STATE |
| 15303 | NOTIFY | CMD_NOTIFY_AUTO_SHUTDOWN_STATE |
| 15500 | PANORAMA | CMD_PANORAMA_START_GRID |
| 15501 | PANORAMA | CMD_PANORAMA_STOP |
| 15503 | PANORAMA | CMD_PANORAMA_START_STITCH_UPLOAD |
| 15504 | PANORAMA | CMD_PANORAMA_STOP_STITCH_UPLOAD |
| 15505 | PANORAMA | CMD_PANORAMA_GET_CURRENT_UPLOAD_STATE |
| 15506 | PANORAMA | CMD_PANORAMA_GET_UPLOAD_PREDICT |
| 15507 | PANORAMA | CMD_PANORAMA_START_COMPRESS |
| 15508 | PANORAMA | CMD_PANORAMA_STOP_COMPRESS |
| 15509 | PANORAMA | CMD_PANORAMA_START_FRAMING |
| 15510 | PANORAMA | CMD_PANORAMA_STOP_FRAMING |
| 15511 | PANORAMA | CMD_PANORAMA_RESET_FRAMING |
| 15512 | PANORAMA | CMD_PANORAMA_UPDATE_FRAMING_RECT |
| 15513 | PANORAMA | CMD_PANORAMA_STOP_FRAMEING_AND_START_GRID |
| 15700 | ITIPS | CMD_ITIPS_GET |
| 16100 | SHOOTING_SCHEDULE | CMD_SYNC_SHOOTING_SCHEDULE |
| 16101 | SHOOTING_SCHEDULE | CMD_CANCEL_SHOOTING_SCHEDULE |
| 16102 | SHOOTING_SCHEDULE | CMD_GET_ALL_SHOOTING_SCHEDULE |
| 16103 | SHOOTING_SCHEDULE | CMD_GET_SHOOTING_SCHEDULE_BY_ID |
| 16105 | SHOOTING_SCHEDULE | CMD_REPLACE_SHOOTING_SCHEDULE |
| 16106 | SHOOTING_SCHEDULE | CMD_UNLOCK_SHOOTING_SCHEDULE |
| 16107 | SHOOTING_SCHEDULE | CMD_LOCK_SHOOTING_SCHEDULE |
| 16108 | SHOOTING_SCHEDULE | CMD_DELETE_SHOOTING_SCHEDULE |
| 16400 | TASK_CENTER | CMD_GLOBAL_TASK_MANAGER_START_TASK |
| 16401 | TASK_CENTER | CMD_GLOBAL_TASK_MANAGER_STOP_TASK |
| 16402 | TASK_CENTER | CMD_GLOBAL_TASK_MANAGER_SWITCH_SHOOTING_MODE |
| 16403 | TASK_CENTER | CMD_GLOBAL_TASK_MANAGER_SWITCH_SHOOTING_TECH |
| 16404 | TASK_CENTER | CMD_GLOBAL_TASK_MANAGER_ENTER_CAMERA |
| 16405 | TASK_CENTER | CMD_GLOBAL_TASK_GET_DEVICE_STATE_INFO |
| 16406 | TASK_CENTER | CMD_GLOBAL_VOICE_ASSISTANT_TASK |
| 16700 | PARAM | CMD_PARAM_SET_EXPOSURE |
| 16701 | PARAM | CMD_PARAM_SET_GAIN |
| 16702 | PARAM | CMD_PARAM_SET_WB |
| 16703 | PARAM | CMD_PARAM_SET_GENERAL_INT_PARAM |
| 16704 | PARAM | CMD_PARAM_SET_GENERAL_FLOAT_PARAM |
| 16705 | PARAM | CMD_PARAM_SET_GENERAL_BOOL_PARAM |
| 16706 | PARAM | CMD_PARAM_SET_AUTO_PARAMS |
| 16800 | VOICE_ASSISTANT | CMD_VOICE_ASSISTANT_TASK |
| 17000 | DEVICE | CMD_DEVICE_LENS_DEFOG |
| 17001 | DEVICE | CMD_DEVICE_AUTO_COOLING |
| 17002 | DEVICE | CMD_DEVICE_AUTO_SHUTDOWN |

502
analysis/UI_REFERENCE.md Normal file
View File

@ -0,0 +1,502 @@
# DWARFLAB App — UI / UX Reference (reverse-engineered)
Reverse-engineered from `DWARFLAB.apk` v3.4.0 (`com.convergence.dwarflab`). This
document describes the **user interface, screen hierarchy, navigation, and
interactions** so the app can be reimplemented in another language/framework.
Focus: **Splash → Home → Connection → Capture (main shooter) → Settings**.
(Atlas/Sky-Atlas and Album/Gallery screens are documented separately.)
---
## 1. App structure & navigation model
The app uses **Jetpack Navigation** (single-activity `MainActivity` + a
`NavHostFragment`) with a **`BottomNavigationView`** of 4 tabs, plus several
full-screen Activities launched outside the nav graph.
### 1.1 Entry / launch flow
```
SplashActivity (launcher, branding + init)
└─▶ MainActivity (NavHost + BottomNavigationView, 4 tabs)
├─ Tab 1: Home → HomeFragment
├─ Tab 2: Atlas → AtlasActivity (separate)
├─ Tab 3: Album → AlbumFragment / AlbumActivity
└─ Tab 4: Settings → SettingsFragment
```
- `mobile_navigation.xml` is the main nav graph; `startDestination =
navigation_device` (Home).
- `HeartbeatEntryActivity` is a transparent launcher alias used to keep a
foreground service alive (the BLE/Wi-Fi heartbeat to the scope).
- Tab labels (from `bottom_nav_menu.xml` + strings `home_3/4/5`, `camera_astro_69`):
| tab | id | label (en) | icon |
|-----|----|-----------|------|
| 1 | `navigation_device` | **Home** | `icon_function_tabbar_home` |
| 2 | `navigation_atlas` | **Atlas** | `icon_function_tabbar_atlas` |
| 3 | `navigation_album` | **Album** | `icon_function_tabbar_album` |
| 4 | `navigation_settings` | **Settings** | `icon_function_tabbar_settings` |
The bottom bar can be hidden (`MainActivity.isShowBottomNav`) when entering
full-screen sub-flows (device connect, OTA, capture).
### 1.2 Activities (beyond the nav graph)
| Activity | Purpose |
|----------|---------|
| `SplashActivity` | Cold-start splash, version checks, routing to connect vs. main |
| `MainActivity` | Hosts the 4 tabs + NavHost |
| `CaptureActivity` | **The shooting screen** (9199 lines — the heart of the app) |
| `AtlasActivity` | Sky atlas / star map / GoTo target selection |
| `AlbumActivity` | Gallery of captured photos/videos/FITS |
| `LocationActivity` | Map to set observing location |
| `CaliFrameActivity` | Calibration-frame capture/management |
| `HelperActivity` | In-app help / guide center |
| `WebActivity` / `NavActivity` | Embedded web views (privacy, OSS notice, help docs) |
| `NfcWriteActivity` | NFC tag update (device name change) |
| `MosaicGuideActivity`, `SkyLightTipActivity`, `StarSearchActivity` | Atlas sub-screens |
---
## 2. Splash & first-run
`SplashActivity` → decides between:
- **Not connected**: routes to `HomeFragment` which shows a *device-discovery /
connect* CTA when no scope is paired.
- **App upgrade available**: shows `AppUpdateDialog` (force-update path uses
`FirmwareForceUpdateDialog`).
- **System notice**: `AppNotice` banner.
`MainActivity` also handles: app-upgrade dialogs, product-activation dialog
(`ProductActivateDialog`), not-enough-storage dialog, and an activation-error
dialog. Activation is gated behind internet access (strings `settings_25``45`).
---
## 3. Home tab (`HomeFragment`) — `fragment_home.xml`
The dashboard / device hub. Two visual states:
### 3.1 Disconnected state
- Title bar: device-name placeholder + a **"Guide"** button (`home_16`,
top-right, primary pill).
- Centered illustration + **"Connect"** call-to-action → navigates to
`DeviceSearchFragment` (BLE scan).
- `view_bg_home_disconnected` background shown.
### 3.2 Connected state
Top bar becomes a **device selector dropdown** (`tv_title` with
`drawableEnd icon_action_arrow_down`): tapping opens device switcher.
Below: device status card, then action entries.
Navigation actions declared on `navigation_device` (HomeFragment):
| Action | Destination | Meaning |
|--------|-------------|---------|
| `action_deviceFragment_to_deviceSearchFragment` | Device Search | Add/switch device |
| `action_homeFragment_to_locationFragment` | Location | Set GPS/observing site |
| `action_homeFragment_to_ScheduleFragment` | Schedule | Shooting plans list |
| `action_homeFragment_to_upgradeFragment` | OTA Upgrade | Firmware update |
| `action_homeFragment_to_scheduleDetailFragment` | Schedule Detail | Edit a plan |
| `action_homeFragment_to_helperFragment` | Helper | In-app guide |
| `action_homeFragment_to_webFragment` | Web | Embedded web content |
| `action_home_to_taskListFragment` | Task List | Task/creation jobs (`createType` arg) |
| `action_home_to_astroFitsFragment` | Astro FITS | View a FITS file (`filePath`) |
| `action_home_to_caliFrameListFragment` | Cali-Frame List | Manage calibration frames (`caliFrameType`, `cameraType`) |
So **Home is a launcher** into: connect, location, schedule, OTA, tasks,
cali-frames, help. The actual *shooting* is entered by tapping the connected
device card → launches `CaptureActivity`.
---
## 4. Device connection flow
A multi-step wizard (mostly bottom-sheet dialogs) living under
`navigation_device_connect` and friends.
```
DeviceSearchFragment (BLE scan, lists nearby scopes)
├─▶ DeviceConnectFragment (dialog) — enter device password
│ ├─ success → DeviceConnectSuccessFragment
│ ├─ wrong pwd → DeviceConnectPwdErrorAgainFragment
│ └─ upgrade needed → UpgradeReminderFragment → OTAUpgradeFragment
├─▶ WiFiListFragment (STA mode: scan Wi-Fi for the scope)
│ └─▶ StaInfoFragment (enter Wi-Fi password) → DeviceConnectFragment
├─▶ DeviceConnectManualFragment (manual IP entry)
├─▶ DeviceStaPwdFragment / DeviceStaConnectFailedFragment
└─▶ DeviceResetTutorialFragment / DeviceConnectFailedFragment
```
Key strings reveal the model:
- **Connection modes** (`settings_connection_1421`):
- **Auto (Recommended)** — auto-choose AP vs STA.
- **STA mode** — phone & scope join the same home Wi-Fi (scope gets internet).
- **AP mode** — connect directly to the DWARF hotspot (outdoor/no-Wi-Fi).
- **Wi-Fi Compatible Mode** + **Enable 2.4GHz** toggles for region/legacy fixes.
- **Region** setting (`settings_connection_10`) — country code for Wi-Fi regs.
- **Activate Wi-Fi at Startup** — auto-enable hotspot on boot.
- Device password screen distinguishes **default password** vs custom
(`isDefaultPwd` arg → `DevicePasswordFragment`).
`DeviceSearchFragment` args: `type` (0 = first connect, 1 = add another),
`deviceName` (nullable, for reconnect). Result carries a `DeviceInfo`
(`com.convergence.dwarflab.net.discovery.DeviceInfo`) containing BLE-resolved
IP/SSID/PSK (see API_REFERENCE §2.1 for the BLE `DwarfEcho` payload).
---
## 5. Capture screen (`CaptureActivity`) — the shooter
This is the most complex screen (~9200 lines). Landscape-oriented camera
viewfinder with overlaid controls. Layout: `activity_capture.xml`.
### 5.1 Layout regions
```
┌──────────────────────────────────────────────────────────────┐
│ [ TechniqueBar (top-right) ] [ Sky-finder actions (top-right) ] │
│ │
│ ┌────────────────────────────┐ ┌──────────┐ │
│ │ │ │ Wide PIP │ ← wide-angle │
│ │ MAIN PREVIEW (RTSP) │ │ preview │ inset (top-L) │
│ │ Tele camera │ └──────────┘ │
│ │ (RtspPlayerView) │ │
│ │ + TrackBoxView overlay │ [ RGB container (right) ] │
│ │ + PreviewBorderView │ │
│ │ + ShootingProgressView │ │
│ └────────────────────────────┘ │
│ │
│ ┌─Left─┐ ┌─Joystick─┐ ┌──Right panel──┐ │
│ │panel │ │ (polar │ │ Focus │ │
│ │ │ │ D-pad) │ │ ┌───────────┐ │ │
│ │ ✕back│ │ │ │ │ CAPTURE │ │ │
│ │ PIP │ └──────────┘ │ │ BUTTON │ │ │
│ │ more │ │ └───────────┘ │ │
│ │ ? │ [ ParameterIndicatorBar ] │ Parameter │ │
│ │ album│ [ DeviceIndicatorBar ] └───────────────┘ │
│ │ clear│ │
│ └──────┘ [ GoTo composition pill ] [ ZoomLensPanel ] │
│ │
│ (overlays: FocusProgress, StopProgress, CaptureStatus, │
│ FullscreenProgress, CaliFrameProgress, PanoComposition) │
└──────────────────────────────────────────────────────────────┘
```
### 5.2 Left control panel (`view_capture_left_control_panel.xml`, 48dp wide)
Vertical icon stack, top→bottom:
| id | icon | action |
|----|------|--------|
| `iv_photography_cancel` | arrow-left | **Back** (exit capture) |
| `iv_photography_pip` | pip icon | **Toggle PIP** (picture-in-picture wide inset) |
| `iv_photography_more_feature_set` | (dynamic) | **More settings** (opens `CamMoreFeatureSetDialog`) |
| `iv_photography_guide` | question-circle | **Guide/help** (hidden by default) |
| `iv_open_album` | album icon | **Open Album** (jump to gallery) |
| `ivClearAll` | clear-all | **Clear** (reset selection/overlay) |
### 5.3 Right control panel (`view_capture_right_panel.xml`, 84dp wide)
Vertical stack:
| id | label | icon | action |
|----|-------|------|--------|
| `btn_focus_view_capture_right_panel` | **Focus** (`camera_general_2`) | `icon_function_main_focus` | Open focus controls (AF, manual, astro-AF) |
| `item_main_capture_button_view` | — (76dp circular) | dynamic | **Main shutter** (see §5.5) |
| `btn_parameter_view_capture_right_panel` | **Parameter** (`camera_astro_222`) | `icon_function_general_parameter` | Open `CamParameterSetDialog` (exposure/gain/WB/ISP) |
`ZoomLensPanel` sits just left of the right panel (zoom/crop-ratio control).
### 5.4 TechniqueBar (top-right) — mode selector
A pill that shows the current **ShootingModeType** + **ShootingTech** and a
right-side action (`RightActionType`). Tapping opens
`ShootingModeSelectDialog` to pick a mode.
**`ShootingModeType`** (the "scene"/target class) — `ShootingModeType.java`:
| value | name | notes |
|-------|------|-------|
| 1 | `NORMAL` | generic |
| 2 | `DSO` | deep-sky object (needs calibration + EQ) |
| 3 | `SUN_MOON` | solar/lunar |
| 4 | `MILKY_WAY` | Milky Way wide-field |
| 5 | `STAR_TRAIL` | star-trail time accumulation |
| 6 | `AUTO_TRACKING` | generic object tracking |
| 7 | `PANORAMA` | panorama/grid capture |
| 8 | `SUN` | sun (ND filter warning!) |
| 9 | `MOON` | moon |
| 10 | `PLANET` | planetary |
| 0 | `UNKNOWN` | default |
Each mode carries flags: `isWidePreviewOnly`, `isWidePreviewSuggested`,
`isPipWindowBtnEnable`, `isHidePip`, `isViewRectangleVisible`,
`isAddQuickSet`, `cameraType` (Tele/Wide), `shootingTech`,
`isAstroFocus`, `isShowAutoFocusSwitch`, `isSunOrMoon`, `isLongTouchStop`,
`isSolarSystem`, `isShowZoomLens`, `isEnterAtlasVisible`, `isEnableCurves`,
`isAreaFocusEnable`. These drive which UI controls are visible.
**`ShootingTech`** (the capture technique) — `ShootingTech.java`:
| value | name | UI ring style |
|-------|------|---------------|
| 0 | `UNKNOWN` | — |
| 1 | `SINGLE_SHOT` | single photo |
| 2 | `STACKING` | live-stacking (astro) |
| 3 | `BURST` | burst |
| 4 | `VIDEO` | video record |
| 5 | `TIMELAPSE` | timelapse |
| 6 | `PANORAMA` | panorama/grid |
**`RightActionType`** (what the TechniqueBar's right button does):
`NORMAL, FOCUS, PARAMETER, TECHNOLOGY, TECHNOLOGY_SETTING, MODE, LongPressStop`.
### 5.5 Main capture button (`MainCaptureButtonView`)
A 76dp circular shutter whose appearance is driven by **`CaptureState`**
(`CaptureState.java`) and the current `ShootingModeType`/`ShootingTech`.
States include:
`None, PreparingAstronomyDarkFrame, RawDarkTaking, RawDarkStopping,
RawDarkStopped, RawTaking, RawStopping, GoLive, AIEnhance, AIEnhanceStopping,
PanoramaTaking, PanoramaStopping, RecordTaking, RecordStopping, …`
Behavior:
- **Tap** → start capture (photo/burst/stack/record depending on tech).
- **Long-press** → stop (`isLongPressTriggered`; shows `item_long_press_stop`
pill "Long Press to Stop" / `camera_general_153`, then "Stopping…").
- Ring/teeth animations reflect exposure countdown (`ShootingProgressView`)
and long-exposure progress (`NotifyProto.LongExpPhotoProgress`).
### 5.6 Joystick (`PolarDpadJoystickView`, 258dp)
Bottom-left polar D-pad for manual slewing. Sends
`CMD_STEP_MOTOR_SERVICE_JOYSTICK` (14006) with `vector_angle`/`vector_length`.
Has low/high speed indicators and four directional triangle overlays.
### 5.7 Overlays (z-ordered by elevation)
| Widget | elevation | purpose |
|--------|-----------|---------|
| `TrackBoxView` (tele + wide) | 4dp | tracking bounding-box overlay |
| `PreviewBorderView` | — | PIP border / crop frame |
| `ShootingProgressView` (main + minor) | 1dp | exposure countdown ring/text |
| `FocusProgressLayout` | 3dp | autofocus sweep overlay |
| `StopProgressLayout` | 3dp | stop-in-progress overlay |
| `CaptureStatusLayout` | 3dp | status HUD (bottom-center) |
| `FullscreenProgressLayout` | 4dp | full-screen progress (calibration, GoTo) |
| `CaliFrameProgressLayout` | 4dp | calibration-frame progress |
| `PanoCompositionLayout` | 30dp (top) | panorama composition canvas |
| `ParameterIndicatorBar` / `DeviceIndicatorBar` | 1dp | bottom status chips |
### 5.8 Sky-finder / Milky-Way action rows (top-right & bottom-center)
- `item_action_sky_finder`: calibration icon, AR-toggle, exit — for the
Sky-Target-Finder / AR overlay mode (`CMD_ASTRO_START_SKY_TARGET_FINDER`).
- `item_action_milky_way`: "Locate Milky Way" (`camera_astro_419`) +
"Confirm" (`camera_astro_412`) pills — Milky Way composition helper.
- `flGoComposition`: "GoTo" composition pill (`camera_pano_52`) for panorama
framing.
### 5.9 Key dialogs launched from Capture
| Dialog | Trigger | Purpose |
|--------|---------|---------|
| `ShootingModeSelectDialog` | TechniqueBar tap | Pick ShootingModeType |
| `CamModeSelectDialog` | mode button | Pick ShootingTech (photo/video/stack/…) |
| `CamParameterSetDialog` / `CamParamSetVM` | Parameter button | Exposure/Gain/WB/ISP per camera |
| `CamMoreFeatureSetDialog` | left "more" icon | Extra feature toggles |
| `PenalSetDialog` | panel button | Side-panel config |
| `StatusHUDDialog` | indicator bar | Detailed status overlay |
| `DarkSceneShootingDialog` | dark-frame flow | Dark-frame capture wizard |
| `CaliFramePrepareDialog` | cali-frame flow | Calibration-frame prep |
| `AtlasGotoDialog` | GoTo action | Confirm GoTo target |
| `AiEnhanceProgressDialog` | AI enhance | AI post-process progress |
| `ReservationCurveDialog` | curves | Tone/exposure curves editor |
| `SkyFinderNodeTargetsDialog` | sky finder | Pick target from AR nodes |
| `TrackSunHintDialog` | sun tracking | Sun-tracking safety hint |
| `BottomTipDialog` / `TipDialog` / `MessageDialog` | various | Tips & confirmations |
---
## 6. Settings tab (`SettingsFragment`) — `fragment_settings.xml`
A single `RecyclerView` whose rows are built programmatically in
`SettingsFragment.java` (grouped sections). Title: "Settings" (`settings_1`).
### 6.1 Top-level rows (from nav actions on `navigation_settings`)
| Row (string) | Destination fragment |
|--------------|----------------------|
| Profile / Login-Register | `ProfileFragment` / `LoginRegisterFragment` |
| **My Device** (`settings_2`) | `MyDeviceFragment` |
| **Connection Settings** (`settings_3`) | `ConnectionSettingsFragment` |
| **Advanced Settings** (`settings_4`) | `AdvancedFragment` |
| **Location** (`settings_5`) | `LocationFragment` |
| **General** (`settings_6`) | `GeneralFragment` |
| **Voice Assistant** | `VoiceAssistantFragment` |
| **Support** (`settings_7`) | `SupportFragment` |
| **About** (`settings_9`) | `AboutFragment` |
| Clear Cache (`settings_8`) | (action, no nav) |
### 6.2 My Device (`MyDeviceFragment`) sub-tree
- Device name → `DeviceNameFragment` (edit name; also triggers NFC update).
- Device password → `DevicePasswordFragment` (change pwd; `isDefaultPwd` flag)
→ `DeviceResetFragment` (factory reset).
- **NFC Update** (`settings_64`) → `NfcWriteActivity` — hold phone near ring light.
- **Activation info** → `ActivateInfoFragment` (status, time, warranty).
- **Storage** → `StorageFragment` (total/available size args).
- Firmware/OTA — reuses `OTAUpgradeFragment`.
### 6.3 Connection Settings (`ConnectionSettingsFragment`)
Toggles + radio (strings `settings_connection_129`):
- **Connection mode**: Auto / STA / AP (radio).
- **Activate Wi-Fi at Startup** (switch).
- **Enable 2.4GHz**, **Wi-Fi Compatible Mode** (switches).
- **Region** → `RegionSettingsFragment` (country code).
- Configure STA network → `WiFiListFragment` → `StaInfoFragment`/`StaInfoSetFragment`.
### 6.4 General (`GeneralFragment`) sub-tree
- **Language** → `LanguageSettingsFragment`.
- **Temperature unit** → `TemperatureUnitFragment`.
- **Appearance / Dark mode** → `AppearanceFragment`.
- **Image correction** → `ImageCorrectionFragment` → list (`ImageCorrectionListFragment`) → item (`ImageCorrectionListItemFragment`) + helper.
- **Floating window** → `FloatingWindowFragment`.
- **Calendar** (dialog) → `CalendarFragment`.
- **Auto-stop duration** → `AutoStopDurationFragment`.
- **Emotion / voice** → `EmotionFragment`, `EmotionScaleFragment`, `SpeechRateFragment`, `VoiceTypeFragment`, `VoiceNavigationModeFragment`.
- **Upload log / Log type** → `UploadLogFragment`, `LogTypeFragment`.
### 6.5 Advanced (`AdvancedFragment`)
Device-level toggles: master lock, MTP mode, CPU mode, low-temp protection,
lens defog, auto-cooling, auto-shutdown (the `CMD_SYSTEM_*` / `CMD_DEVICE_*`
commands). Shows `layout_advanced_settings_unavailable.xml` when the connected
device/firmware doesn't support an option.
### 6.6 Support / About
- **Support** (`settings_7`): FAQ/web links, contact `support@dwarflab.com`,
log upload.
- **About** (`settings_9`): app version, OSS notice
(`site.dwarflabapp.com/app-about/open-source-software-android`), privacy &
terms (en/zh).
---
## 7. OTA / firmware upgrade flow
```
UpgradeReminderFragment (dialog: "new firmware available")
└─▶ OTAUpgradeFragment (download + apply)
└─▶ WiFiConnectFragment (dialog, if scope needs Wi-Fi for download)
```
- Args: `ssid`, `psd`, `isStaMode` — the scope may need to join Wi-Fi to fetch
the firmware; the app drives this via BLE (`ReqSta`) then polls download
progress.
- Firmware download URL:
`https://dwarflab.com/pages/dwarflab-app-firmware-download`.
- `FirmwareForceUpdateDialog` blocks the app if firmware is too old for a
required feature (e.g. astrophotography — see `camera_astro_116`).
---
## 8. Schedule / shooting-plan flow
```
HomeFragment
└─▶ ScheduleFragment (list of plans)
├─▶ ScheduleDetailFragment (edit one plan; add targets, set params)
│ └─▶ ScheduleErrorReasonFragment (if sync fails) [args: reason]
└─▶ (sync/lock/unlock/delete via ScheduleProto cmds 1610016108)
```
- A plan = a timed shooting session with one or more targets, per-camera
params, and a date/time window (sunset→sunrise auto-calculated from Atlas).
- Plans can be **locked** (16107) so they reserve their time slot; unlocking
(16106) frees it.
- "Add to Schedule" (`camera_general_113`), "Date of Plan"
(`camera_general_114`), and the 12-hour-ahead sync limit
(`camera_general_118`) are key UX constraints.
---
## 9. Shared UI conventions & components
### 9.1 Custom widgets (`ui/widget/`)
| Widget | Path | Role |
|--------|------|------|
| `RtspPlayerView` | `media/` | RTSP preview (ijkplayer, TCP transport) |
| `PolarDpadJoystickView` | `widget/joystick/` | Polar slew D-pad |
| `TechniqueBar` | `widget/capture/` | Mode/tech selector pill |
| `MainCaptureButtonView` | `widget/capture/` | Circular shutter |
| `CaptureLeftControlPanel` / `CaptureRightControlPanel` | `widget/capture/` | Side control columns |
| `ZoomLensPanel` | `widget/capture/` | Zoom / crop-ratio |
| `ParameterIndicatorBar` / `DeviceIndicatorBar` | `widget/capture/` | Bottom status chips |
| `ShootingProgressView` | `widget/capture/` | Exposure countdown ring |
| `TrackBoxView` | `widget/camera/module/` | Tracking bbox overlay |
| `PreviewBorderView` | `widget/camera/module/` | PIP/crop border |
| `PanoPreviewGridLineView` | `widget/camera/module/` | Panorama grid |
| `TargetRectView` | `widget/camera/module/` | Target rectangle |
| `FocusProgressLayout` / `StopProgressLayout` | `widget/camera/module/` | Full-screen progress |
| `RGBContainerLayout` | `widget/camera/function/` | RGB ring-light control |
| `FullscreenProgressLayout` / `CaliFrameProgressLayout` / `PanoCompositionLayout` | `widget/capture/` | Full-screen overlays |
| `DWRangeSliderView` | `widget/atlas/` | Range slider (params) |
| `FitSystemView` | `widget/` | Status-bar inset helper |
### 9.2 Design tokens
- Material 3 color scheme: `dl_color_on_surface`, `dl_color_surface_container_low_dark`,
`dl_color_primary_dark`, `dl_color_mask_strong`, `dl_color_border_variant_dark`,
`dl_color_white_80`, `dl_color_transparent`…
- Spacing scale: `dl_gap_level_4/8/12/16/24/32` (4-pt grid), `dl_margin_level_3`,
`dl_padding_level_2`, `dl_radius_rounded`, `dl_radius_medium`.
- Typography styles: `title_large_emphasized`, `title_small_emphasized`,
`body_medium`, `body_medium_emphasized`, `body_small_emphasized`,
`label_medium`, `Photography_label_2`, `CamControlBtnStyle`.
- Transitions: `right_slide_enter/exit`, `left_slide_enter/exit` (push),
`dialog_bottom_enter/exit` (bottom-sheets).
### 9.3 Guide / onboarding overlays
`ui/guide/overlay/`: `BaseGuideDialogFragment`,
`GuideDialogFragment`, `ActivityGuideDialogFragment`,
`FullScreenOverlayDialogFragment` — coach-mark overlays with anchor points
(`ui/guide/anchor/`) used for first-run feature discovery.
---
## 10. Internationalization
- Default strings in `res/values/strings.xml`; localized variants exist
(Chinese `values-zh`, etc.). All user-visible text is keyed
(`camera_astro_N`, `camera_general_N`, `settings_N`, `home_N`,
`settings_connection_N`, `album_N`, `guide_N`…).
- Help docs link to language-specific URLs:
`https://help.dwarflab.com/en` vs `/zh`.
- Voice assistant has its own strings and supports emotion/speech-rate tuning.
---
## 11. Map: UI action → API command
| UI action | WS command(s) | Proto |
|-----------|---------------|-------|
| Tap shutter (photo) | 10002 / 12022 | `ReqPhotograph` |
| Burst start/stop | 10003 / 10004 | `…Burst` |
| Video record start/stop | 10005 / 10006 | `…Record` |
| Set exposure | 10009 / 12004 | `ReqSetExp` |
| Set gain | 10013 / 12006 | `ReqSetGain` |
| WB / brightness / contrast / saturation / hue / sharpness | 1001510024 | `ReqSetWB…` |
| Open/close camera | 10000/10001 (tele), 12000/12001 (wide) | — |
| Joystick slew | 14006 | `ReqMotorServiceJoystick` |
| GoTo target | 11002/11003/11013/11014 | `ReqStartGotoDSO`/`…SolarSystem` |
| Calibrate | 11000 | `ReqStartCalibration` |
| Live stacking | 11005/11006 | `Req…LiveStacking` |
| Dark frames | 11007/11021 | `Req…RawDark…` |
| Auto-focus | 15000 | `ReqAutoFocus` |
| Start track | 14800 | `ReqStartTrack` |
| Panorama grid | 15500/15501 | `Req…Grid` |
| AI enhance | 11029/11030 | `Req…AiEnhance` |
| EQ solving | 11018/11019 | `Req…EqSolving` |
| Power / reboot / RGB | 1350013505 | `RGB.proto` |
| Set time/location | 13000/13010 | `ReqSetTime`/`ReqSetLocation` |
| Sync schedule | 16100 | `Schedule.proto` |
Full command table: `CMD_TABLE.md`. Proto payloads: `analysis/protos/`.
---
## 12. Suggested reimplementation plan (cross-platform)
1. **Screens to build first** (MVP): Splash → Home (connect CTA) →
DeviceSearch (BLE) → DeviceConnect (password) → Capture (preview + shutter
+ params + joystick) → Settings (My Device + Connection).
2. **State model**: a single `DeviceStore` (connected? device_id, ip, cameras
on/off, current ShootingModeType/Tech, CaptureState, live params) fed by
the WebSocket NOTIFY stream (§API_REFERENCE §3.2). All UI reads from this.
3. **Capture screen** is the hard part — replicate the overlay z-order
(§5.7) and drive the capture button from `CaptureState`.
4. **Two preview surfaces** (Tele main + Wide PIP) each need an RTSP
consumer; toggle PIP via `CMD_SWITCH_MAIN_PREVIEW` (14809).
5. Keep the **mode-driven visibility** model: each `ShootingModeType` flag
(`isWidePreviewOnly`, `isAstroFocus`, `isShowZoomLens`…) controls which
controls render — don't hardcode per-screen logic.

150
analysis/extract_protos.py Normal file
View File

@ -0,0 +1,150 @@
#!/usr/bin/env python3
"""
Extract serialized FileDescriptorProto bytes from jadx-generated *Proto.java
files and regenerate clean .proto definitions using the real protobuf library.
"""
import re
import sys
import os
from google.protobuf import descriptor_pb2
# proto3 -> no "optional" label; proto2 prints labels.
TYPE_MAP = {
1: 'double', 2: 'float', 3: 'int64', 4: 'uint64', 5: 'int32',
6: 'fixed64', 7: 'fixed32', 8: 'bool', 9: 'string', 11: 'message',
12: 'bytes', 13: 'uint32', 14: 'enum', 15: 'sfixed32', 16: 'sfixed64',
17: 'sint32', 18: 'sint64',
}
def field_type_str(f):
if f.type_name:
return f.type_name.lstrip('.')
return TYPE_MAP.get(f.type, f'scalar{f.type}')
def render_field(f, syntax):
ty = field_type_str(f)
label = ''
if f.label == descriptor_pb2.FieldDescriptorProto.LABEL_REPEATED:
if f.options.packed:
label = 'packed repeated '
else:
label = 'repeated '
elif syntax == 'proto2' and f.label == descriptor_pb2.FieldDescriptorProto.LABEL_REQUIRED:
label = 'required '
elif syntax == 'proto2':
label = 'optional '
return f' {label}{ty} {f.name} = {f.number};'
def render_enum(e, indent):
lines = [f'{indent}enum {e.name} {{']
for v in e.value:
lines.append(f'{indent} {v.name} = {v.number};')
lines.append(f'{indent}}}')
return '\n'.join(lines)
def render_message(m, indent, syntax):
lines = [f'{indent}message {m.name} {{']
for oneof in m.oneof_decl:
lines.append(f'{indent} // oneof {oneof.name}')
for nested in m.enum_type:
lines.append(render_enum(nested, indent + ' '))
for nested in m.nested_type:
lines.append(render_message(nested, indent + ' ', syntax))
for f in m.field:
lines.append(render_field(f, syntax))
lines.append(f'{indent}}}')
return '\n'.join(lines)
def render_file(fd):
out = [f'// source: {fd.name}']
if fd.package:
out.append(f'package {fd.package};')
syntax = fd.syntax or 'proto3'
out.append(f'syntax = "{syntax}";')
if fd.dependency:
out.append('')
for dep in fd.dependency:
out.append(f'import "{dep}";')
out.append('')
for e in fd.enum_type:
out.append(render_enum(e, ''))
out.append('')
for m in fd.message_type:
out.append(render_message(m, '', syntax))
out.append('')
return '\n'.join(out)
DESC_RE = re.compile(
r'internalBuildGeneratedFileFrom\(new String\[\]\{(.*?)\}\s*,\s*new Descriptors',
re.DOTALL)
def decode_java_string_literal_body(lit):
"""Decode a Java string-literal body (between quotes) to raw bytes."""
out = bytearray()
i = 0; n = len(lit)
while i < n:
c = lit[i]
if c == '\\':
nxt = lit[i+1]
simple = {'n': 10, 'r': 13, 't': 9, '"': 34, "'": 39, '\\': 92, '0': 0, 'b': 8, 'f': 12}
if nxt in simple:
out.append(simple[nxt]); i += 2
elif nxt == 'u':
out += chr(int(lit[i+2:i+6], 16)).encode('latin-1', 'replace')
i += 6
else:
out.append(ord(nxt) & 0xff); i += 2
else:
out += c.encode('latin-1', 'replace'); i += 1
return bytes(out)
def extract_descriptor_bytes(java_path):
txt = open(java_path, encoding='utf-8', errors='replace').read()
m = DESC_RE.search(txt)
if not m:
return None
body = m.group(1)
lits = re.findall(r'"((?:[^"\\]|\\.)*)"', body)
# protobuf concatenates ALL adjacent string elements into ONE descriptor
combined = b''.join(decode_java_string_literal_body(l) for l in lits)
return combined if combined else None
def main():
proto_dir = sys.argv[1]
out_dir = sys.argv[2]
os.makedirs(out_dir, exist_ok=True)
total_msgs = 0
for fn in sorted(os.listdir(proto_dir)):
if not fn.endswith('Proto.java'):
continue
path = os.path.join(proto_dir, fn)
raw = extract_descriptor_bytes(path)
base = fn[:-5].replace('Proto', '')
if not raw:
print(f' [WARN] no descriptor in {fn}')
continue
try:
fd_set = descriptor_pb2.FileDescriptorSet()
fd = fd_set.file.add()
fd.MergeFromString(raw)
except Exception as ex:
# may be a FileDescriptorSet directly, or multiple
try:
fd_set.ParseFromString(raw)
if not fd_set.file:
raise
except Exception as ex2:
print(f' [ERR ] {fn}: {ex2}')
continue
out_path = os.path.join(out_dir, base + '.proto')
chunks = []
for one_fd in fd_set.file:
chunks.append(render_file(one_fd))
total_msgs += len(one_fd.message_type)
with open(out_path, 'w', encoding='utf-8') as f:
f.write('\n\n'.join(chunks) + '\n')
print(f' [OK] {fn} -> {base}.proto ({len(raw)} bytes, {len(fd_set.file)} file(s), {sum(len(x.message_type) for x in fd_set.file)} msgs)')
print(f'\nTotal messages recovered: {total_msgs}')
if __name__ == '__main__':
main()

368
analysis/protos/Astro.proto Normal file
View File

@ -0,0 +1,368 @@
// source: astro.proto
syntax = "proto3";
message ReqStartCalibration {
double lon = 1;
double lat = 2;
}
message ReqStopCalibration {
}
message ReqGotoDSO {
double ra = 1;
double dec = 2;
string target_name = 3;
bool goto_only = 4;
}
message ReqGotoSolarSystem {
int32 index = 1;
double lon = 2;
double lat = 3;
string target_name = 4;
bool force_start = 5;
}
message ResGotoSolarSystem {
int32 code = 1;
ReqGotoSolarSystem req = 2;
}
message ReqStopGoto {
}
message ReqCaptureRawLiveStacking {
int32 ir_index = 1;
bool force_start = 2;
}
message ReqStopCaptureRawLiveStacking {
}
message ReqFastStopCaptureRawLiveStacking {
}
message ReqCheckDarkFrame {
}
message ResCheckDarkFrame {
int32 progress = 1;
int32 code = 2;
}
message ReqCaptureDarkFrame {
int32 reshoot = 1;
}
message ReqStopCaptureDarkFrame {
}
message ReqCaptureDarkFrameWithParam {
int32 exp_index = 1;
int32 gain_index = 2;
int32 bin_index = 3;
int32 cap_size = 4;
}
message ReqStopCaptureDarkFrameWithParam {
}
message ReqGetDarkFrameList {
}
message ResGetDarkFrameInfo {
// oneof _temperature
int32 exp_index = 1;
int32 gain_index = 2;
int32 bin_index = 3;
string exp_name = 4;
string gain_name = 5;
string bin_name = 6;
int32 temperature = 7;
}
message ResGetDarkFrameInfoList {
int32 code = 1;
repeated ResGetDarkFrameInfo results = 2;
}
message ReqDelDarkFrame {
int32 exp_index = 1;
int32 gain_index = 2;
int32 bin_index = 3;
int32 temp_value = 4;
}
message ReqDelDarkFrameList {
repeated ReqDelDarkFrame dark_list = 1;
}
message ResDelDarkFrameList {
int32 code = 1;
}
message ReqGoLive {
}
message ReqTrackSpecialTarget {
int32 index = 1;
double lon = 2;
double lat = 3;
}
message ReqStopTrackSpecialTarget {
}
message ReqOneClickGotoDSO {
double ra = 1;
double dec = 2;
string target_name = 3;
double lon = 4;
double lat = 5;
int32 shooting_mode = 6;
bool goto_only = 7;
}
message ResOneClickGoto {
int32 step = 1;
int32 code = 2;
bool all_end = 3;
}
message ReqOneClickGotoSolarSystem {
int32 index = 1;
double lon = 2;
double lat = 3;
string target_name = 4;
int32 shooting_mode = 5;
bool force_start = 6;
}
message ResOneClickGotoSolarSystem {
int32 step = 1;
int32 code = 2;
bool all_end = 3;
ReqOneClickGotoSolarSystem req = 4;
}
message ReqStopOneClickGoto {
}
message ReqCaptureWideRawLiveStacking {
bool force_start = 1;
}
message ReqStopCaptureWideRawLiveStacking {
}
message ReqFastStopCaptureWideRawLiveStacking {
}
message ReqStartEqSolving {
double lon = 1;
double lat = 2;
}
message ResStartEqSolving {
double azi_err = 1;
double alt_err = 2;
int32 code = 3;
}
message ReqStopEqSolving {
}
message ReqStartAiEnhance {
}
message ReqStopAiEnhance {
}
message ReqStartMosaic {
int32 horizontal_scale = 1;
int32 vertical_scale = 2;
int32 rotation = 3;
int32 ir_index = 4;
bool force_start = 5;
}
message ReqStartMakeFitsThumb {
string src_dir = 1;
}
message ReqStopMakeFitsThumb {
}
message ResMakeFitsThumb {
int32 code = 1;
string src_dir = 2;
}
message MakeFitsThumbTaskParam {
string src_dir = 1;
}
message ReqIsImageStackable {
repeated string src_dirs = 1;
}
message ResIsImageStackable {
int32 code = 1;
repeated ResGetDarkFrameInfo need_dark_frame_info = 2;
}
message ReqStartRepostprocess {
repeated string src_dirs = 1;
}
message ReqStopRepostprocess {
}
message ResRepostprocess {
int32 code = 1;
string result_dir = 2;
}
message RepostprocessTaskParam {
string result_dir = 1;
}
message ReqGetAstroShootingTime {
int32 exp_index = 1;
int32 horizontal_scale = 2;
int32 vertical_scale = 3;
int32 rotation = 4;
int32 cam_id = 5;
int32 shooting_mode = 6;
}
message ResGetAstroShootingTime {
enum AstroMode {
NORMAL = 0;
MOSAIC = 1;
}
int32 code = 1;
int32 shooting_time = 2;
int32 cam_id = 3;
ResGetAstroShootingTime.AstroMode astro_mode = 4;
int32 shooting_mode = 5;
}
message ReqGetCaliFrameList {
int32 camera_type = 1;
int32 cali_frame_type = 2;
}
message CaliFrameInfo {
// oneof _filter_type
// oneof _info_id
// oneof _temp_value
string exp_name = 1;
int32 gain = 2;
int32 resolution = 3;
int32 camera_type = 4;
int32 progress = 5;
int32 cali_frame_type = 6;
int32 filter_type = 7;
int32 info_id = 8;
int32 temp_value = 9;
}
message ResGetCaliFrameList {
int32 code = 1;
repeated CaliFrameInfo list = 2;
int32 camera_type = 3;
int32 cali_frame_type = 4;
}
message ReqDelCaliFrameList {
repeated int32 info_ids = 1;
}
message ReqCaptureCaliFrame {
// oneof _filter_type
int32 exp_index = 1;
int32 gain = 2;
int32 resolution = 3;
int32 cap_size = 4;
int32 camera_type = 5;
int32 cali_frame_type = 6;
int32 filter_type = 7;
int32 scene_type = 8;
}
message ReqStopCaptureCaliFrame {
int32 camera_type = 1;
}
message CaptureCaliFrameTaskParam {
int32 camera_type = 1;
int32 cali_frame_type = 2;
}
message ReqGetQuickSetList {
int32 camera_type = 1;
}
message QuikSetInfo {
string exp_name = 1;
int32 exp_index = 2;
int32 gain = 3;
int32 resolution = 4;
int32 camera_type = 5;
string info_id = 6;
}
message ResGetQuikSetList {
int32 code = 1;
repeated QuikSetInfo quick_set_list = 2;
int32 camera_type = 3;
}
message ReqSetQuickSet {
string info_id = 1;
}
message ResSetQuickSet {
int32 code = 1;
string info_id = 2;
}
message ReqOneClickShooting {
}
message ResAstroShooting {
// oneof _exp_name
// oneof _gain
// oneof _resolution
// oneof _filter_type
// oneof _temp_threshold
int32 code = 1;
string exp_name = 2;
int32 gain = 3;
int32 resolution = 4;
int32 filter_type = 5;
int32 temp_threshold = 6;
}
message ReqStartSkyTargetFinder {
double lon = 1;
double lat = 2;
bool force_restart = 3;
int32 scene_type = 4;
}
message ResStartSkyTargetFinder {
int32 code = 1;
double zenith_azi = 2;
double zenith_alt = 3;
double center_azi = 4;
double center_alt = 5;
double center_roll = 6;
int32 scene_type = 7;
}
message ReqStopSkyTargetFinder {
}

View File

@ -0,0 +1,52 @@
// source: base.proto
syntax = "proto3";
enum WsMajorVersion {
WS_MAJOR_VERSION_UNKNOWN = 0;
WS_MAJOR_VERSION_NUMBER = 2;
}
enum WsMinorVersion {
WS_MINOR_VERSION_UNKNOWN = 0;
WS_MINOR_VERSION_NUMBER = 3;
}
message WsPacket {
uint32 major_version = 1;
uint32 minor_version = 2;
uint32 device_id = 3;
uint32 module_id = 4;
uint32 cmd = 5;
uint32 type = 6;
bytes data = 7;
string client_id = 8;
}
message ComResponse {
int32 code = 1;
}
message ComResWithInt {
int32 value = 1;
int32 code = 2;
}
message ComResWithDouble {
double value = 1;
int32 code = 2;
}
message ComResWithString {
string str = 1;
int32 code = 2;
}
message CommonParam {
bool hasAuto = 1;
int32 auto_mode = 2;
int32 id = 3;
int32 mode_index = 4;
int32 index = 5;
double continue_value = 6;
}

203
analysis/protos/Ble.proto Normal file
View File

@ -0,0 +1,203 @@
// source: ble.proto
syntax = "proto3";
enum VocalType {
VT_UNKNOWN = 0;
VT_PING = 1;
VT_ECHO = 2;
}
message ReqGetconfig {
int32 cmd = 1;
string ble_psd = 2;
string client_id = 3;
}
message ReqAp {
int32 cmd = 1;
int32 wifi_type = 2;
int32 auto_start = 3;
int32 country_list = 4;
string country = 5;
string ble_psd = 6;
string client_id = 7;
bool force_restart = 8;
}
message ReqSta {
int32 cmd = 1;
int32 auto_start = 2;
string ble_psd = 3;
string ssid = 4;
string psd = 5;
string client_id = 6;
}
message ReqSetblewifi {
int32 cmd = 1;
int32 mode = 2;
string ble_psd = 3;
string value = 4;
string client_id = 5;
}
message ReqReset {
int32 cmd = 1;
string client_id = 2;
}
message ReqGetwifilist {
int32 cmd = 1;
string client_id = 2;
}
message ReqGetsysteminfo {
int32 cmd = 1;
string client_id = 2;
}
message ReqCheckFile {
int32 cmd = 1;
string file_path = 2;
string md5 = 3;
}
message ResCommon {
int32 cmd = 1;
int32 code = 2;
}
message ResGetconfig {
int32 cmd = 1;
int32 code = 2;
int32 state = 3;
int32 wifi_mode = 4;
int32 ap_mode = 5;
int32 auto_start = 6;
int32 ap_country_list = 7;
string ssid = 8;
string psd = 9;
string ip = 10;
string ap_country = 11;
}
message ResAp {
int32 cmd = 1;
int32 code = 2;
int32 mode = 3;
string ssid = 4;
string psd = 5;
}
message ResSta {
int32 cmd = 1;
int32 code = 2;
string ssid = 3;
string psd = 4;
string ip = 5;
}
message ResSetblewifi {
int32 cmd = 1;
int32 code = 2;
int32 mode = 3;
string value = 4;
}
message ResReset {
int32 cmd = 1;
int32 code = 2;
}
message WifiInfo {
int32 signal_level = 1;
string ssid = 2;
string security_capability = 3;
}
message ResWifilist {
int32 cmd = 1;
int32 code = 2;
repeated string ssid = 4;
repeated WifiInfo wifi_info_list = 5;
}
message ResGetsysteminfo {
int32 cmd = 1;
int32 code = 2;
int32 protocol_version = 3;
string device = 4;
string mac_address = 5;
string dwarf_ota_version = 6;
}
message ResReceiveDataError {
int32 cmd = 1;
int32 code = 2;
}
message ResCheckFile {
int32 cmd = 1;
int32 code = 2;
}
message ComDwarfMsg {
VocalType vocaltype = 1;
}
message DwarfPing {
VocalType vocaltype = 1;
uint64 timestamp = 2;
bytes magic = 3;
repeated bytes vocals = 4;
repeated bytes mutes = 5;
}
message StationModel {
uint32 family = 1;
uint32 revision = 2;
}
message NifAP {
// oneof _ipv6
string ifname = 1;
int32 mode = 2;
string country_code = 3;
string ssid = 4;
string sec = 5;
string psw = 6;
bytes ipv4 = 7;
bytes ipv6 = 8;
}
message NifSTA {
// oneof _ssid
// oneof _psw
// oneof _rssi
// oneof _ipv4
// oneof _ipv6
string ifname = 1;
string ssid = 2;
string psw = 3;
int32 rssi = 4;
bytes ipv4 = 5;
bytes ipv6 = 6;
}
message DwarfEcho {
VocalType vocaltype = 1;
uint64 timestamp = 2;
bytes magic = 3;
uint64 ts_ping = 4;
bytes mac_address = 5;
StationModel model = 6;
string sn = 7;
string name = 8;
string psw = 9;
string fw_version = 10;
string ws_scheme = 11;
uint32 session = 12;
NifAP ap = 13;
NifSTA sta = 14;
}

View File

@ -0,0 +1,217 @@
// source: camera.proto
syntax = "proto3";
import "base.proto";
message ReqOpenCamera {
bool binning = 1;
int32 rtsp_encode_type = 2;
}
message ReqCloseCamera {
}
message ReqPhoto {
}
message ReqBurstPhoto {
int32 count = 1;
}
message ReqStopBurstPhoto {
}
message ReqStartRecord {
int32 encode_type = 1;
}
message ReqStopRecord {
}
message ReqSetExpMode {
int32 mode = 1;
}
message ReqGetExpMode {
}
message ReqSetExp {
int32 index = 1;
}
message ReqGetExp {
}
message ReqSetGainMode {
int32 mode = 1;
}
message ReqGetGainMode {
}
message ReqSetGain {
int32 index = 1;
}
message ReqGetGain {
}
message ReqSetBrightness {
int32 value = 1;
}
message ReqGetBrightness {
}
message ReqSetContrast {
int32 value = 1;
}
message ReqGetContrast {
}
message ReqSetHue {
int32 value = 1;
}
message ReqGetHue {
}
message ReqSetSaturation {
int32 value = 1;
}
message ReqGetSaturation {
}
message ReqSetSharpness {
int32 value = 1;
}
message ReqGetSharpness {
}
message ReqSetWBMode {
int32 mode = 1;
}
message ReqGetWBMode {
}
message ReqSetWBSence {
int32 value = 1;
}
message ReqGetWBSence {
}
message ReqSetWBCT {
int32 index = 1;
}
message ReqGetWBCT {
}
message ReqSetIrCut {
int32 value = 1;
}
message ReqGetIrcut {
}
message ReqStartTimeLapse {
}
message ReqStopTimeLapse {
}
message ReqSetAllParams {
int32 exp_mode = 1;
int32 exp_index = 2;
int32 gain_mode = 3;
int32 gain_index = 4;
int32 ircut_value = 5;
int32 wb_mode = 6;
int32 wb_index_type = 7;
int32 wb_index = 8;
int32 brightness = 9;
int32 contrast = 10;
int32 hue = 11;
int32 saturation = 12;
int32 sharpness = 13;
int32 jpg_quality = 14;
}
message ReqGetAllParams {
}
message ResGetAllParams {
repeated CommonParam all_params = 1;
int32 code = 2;
}
message ReqSetFeatureParams {
CommonParam param = 1;
}
message ReqGetAllFeatureParams {
}
message ResGetAllFeatureParams {
repeated CommonParam all_feature_params = 1;
int32 code = 2;
}
message ReqGetSystemWorkingState {
}
message ReqSetJpgQuality {
int32 quality = 1;
}
message ReqGetJpgQuality {
}
message ReqPhotoRaw {
}
message ReqSetRtspBitRateType {
int32 bitrate_type = 1;
}
message ReqDisableAllIspProcessing {
}
message ReqEnableAllIspProcessing {
}
message IspModuleState {
int32 module_id = 1;
bool state = 2;
}
message ReqSetIspModuleState {
repeated IspModuleState module_states = 1;
}
message ReqGetIspModuleState {
repeated int32 module_ids = 1;
}
message ReqSwitchResolution {
int32 resolution_index = 1;
}
message ReqSwitchFrameRate {
int32 fps_index = 1;
}
message ReqSwitchCropRatio {
int32 crop_ratio = 1;
}
message ReqSetPreviewQuality {
uint32 level = 1;
uint32 quality = 2;
}

View File

@ -0,0 +1,18 @@
// source: device.proto
package device;
syntax = "proto3";
import "base.proto";
message ReqLensDefog {
int32 state = 1;
}
message ReqAutoCooling {
int32 state = 1;
}
message ReqAutoShutdown {
int32 state = 1;
}

View File

@ -0,0 +1,39 @@
// source: focus.proto
syntax = "proto3";
message ReqManualSingleStepFocus {
uint32 direction = 1;
}
message ReqManualContinuFocus {
uint32 direction = 1;
}
message ReqStopManualContinuFocus {
}
message ReqNormalAutoFocus {
uint32 mode = 1;
uint32 center_x = 2;
uint32 center_y = 3;
}
message ReqAstroAutoFocus {
uint32 mode = 1;
}
message ReqStopAstroAutoFocus {
}
message ReqGetUserInfinityPos {
}
message ReqSetUserInfinityPos {
int32 pos = 1;
}
message ResUserInfinityPos {
int32 code = 1;
int32 pos = 2;
}

View File

@ -0,0 +1,30 @@
// source: itips.proto
syntax = "proto3";
message ReqITipsGet {
int32 mode = 1;
}
message ResITipsGet {
int32 mode = 1;
string itips_code = 2;
int32 code = 3;
}
message CommonITips {
int32 itips_status = 1;
string itips_code = 2;
}
message CommonStepITips {
int32 step_id = 1;
int32 step_status = 2;
repeated CommonITips step_itips = 3;
}
message ResITipsList {
repeated CommonStepITips itips_list = 1;
int32 mode = 2;
int32 code = 3;
}

View File

@ -0,0 +1,81 @@
// source: motor_control.proto
syntax = "proto3";
message ReqMotorServiceJoystick {
double vector_angle = 1;
double vector_length = 2;
}
message ReqMotorServiceJoystickFixedAngle {
double vector_angle = 1;
double vector_length = 2;
}
message ReqMotorServiceJoystickStop {
}
message ReqMotorRun {
int32 id = 1;
double speed = 2;
bool direction = 3;
int32 speed_ramping = 4;
int32 resolution_level = 5;
}
message ReqMotorRunInPulse {
int32 id = 1;
int32 frequency = 2;
bool direction = 3;
int32 speed_ramping = 4;
int32 resolution = 5;
int32 pulse = 6;
bool mode = 7;
}
message ReqMotorRunTo {
int32 id = 1;
double end_position = 2;
double speed = 3;
int32 speed_ramping = 4;
int32 resolution_level = 5;
}
message ReqMotorGetPosition {
int32 id = 1;
}
message ReqMotorStop {
int32 id = 1;
}
message ReqMotorReset {
int32 id = 1;
bool direction = 2;
}
message ReqMotorChangeSpeed {
int32 id = 1;
double speed = 2;
}
message ReqMotorChangeDirection {
int32 id = 1;
bool direction = 2;
}
message ResMotor {
int32 id = 1;
int32 code = 2;
}
message ResMotorPosition {
int32 id = 1;
int32 code = 2;
double position = 3;
}
message ReqDualCameraLinkage {
int32 x = 1;
int32 y = 2;
}

View File

@ -0,0 +1,518 @@
// source: notify.proto
package notify;
syntax = "proto3";
import "base.proto";
enum OperationState {
OPERATION_STATE_IDLE = 0;
OPERATION_STATE_RUNNING = 1;
OPERATION_STATE_STOPPING = 2;
OPERATION_STATE_STOPPED = 3;
}
enum AstroState {
ASTRO_STATE_IDLE = 0;
ASTRO_STATE_RUNNING = 1;
ASTRO_STATE_STOPPING = 2;
ASTRO_STATE_STOPPED = 3;
ASTRO_STATE_PLATE_SOLVING = 4;
}
enum SentryModeState {
SENTRY_MODE_STATE_IDLE = 0;
SENTRY_MODE_STATE_INIT = 1;
SENTRY_MODE_STATE_DETECT = 2;
SENTRY_MODE_STATE_TRACK = 3;
SENTRY_MODE_STATE_TRACK_FINISH = 4;
SENTRY_MODE_STATE_STOPPING = 5;
}
enum SentryObjectType {
SENTRY_OBJECT_TYPE_UNKNOWN = 0;
SENTRY_OBJECT_TYPE_UFO = 1;
SENTRY_OBJECT_TYPE_BIRD = 2;
SENTRY_OBJECT_TYPE_PERSON = 3;
SENTRY_OBJECT_TYPE_ANIMAL = 4;
SENTRY_OBJECT_TYPE_VEHICLE = 5;
SENTRY_OBJECT_TYPE_FLYING = 6;
SENTRY_OBJECT_TYPE_BOAT = 7;
}
message PictureMatching {
uint32 x = 1;
uint32 y = 2;
uint32 width = 3;
uint32 height = 4;
}
message StorageInfo {
uint32 available_size = 1;
uint32 total_size = 2;
int32 storage_type = 3;
bool is_valid = 4;
}
message Temperature {
int32 code = 1;
int32 temperature = 2;
}
message CmosTemperature {
// oneof _temperature
int32 temperature = 1;
int32 camera_type = 2;
}
message RecordTime {
uint32 record_time = 1;
uint32 camera_type = 2;
}
message TimeLapseOutTime {
uint32 interval = 1;
uint32 out_time = 2;
uint32 total_time = 3;
uint32 camera_type = 4;
}
message OperationStateNotify {
notify.OperationState state = 1;
}
message AstroCalibrationState {
notify.AstroState state = 1;
int32 plate_solving_times = 2;
}
message AstroGotoState {
notify.AstroState state = 1;
string target_name = 2;
}
message AstroTrackingState {
notify.OperationState state = 1;
string target_name = 2;
}
message ProgressCaptureRawDark {
int32 progress = 1;
int32 remaining_time = 2;
int32 camera_type = 3;
}
message ProgressCaptureRawLiveStacking {
// oneof _shooting_time
// oneof _stacked_time
int32 total_count = 1;
int32 update_type = 2;
int32 current_count = 3;
int32 stacked_count = 4;
int32 exp_index = 5;
int32 gain_index = 6;
string target_name = 7;
int32 camera_type = 8;
int32 shooting_time = 9;
int32 stacked_time = 10;
}
message Param {
repeated CommonParam param = 1;
}
message BurstProgress {
uint32 total_count = 1;
uint32 completed_count = 2;
uint32 camera_type = 3;
}
message PanoramaProgress {
int32 total_count = 1;
int32 completed_count = 2;
uint32 camera_type = 3;
}
message RgbState {
int32 state = 1;
}
message PowerIndState {
int32 state = 1;
}
message ChargingState {
int32 state = 1;
}
message BatteryInfo {
int32 percentage = 1;
}
message HostSlaveMode {
int32 mode = 1;
bool lock = 2;
}
message MTPState {
int32 mode = 1;
}
message TrackResult {
int32 x = 1;
int32 y = 2;
int32 w = 3;
int32 h = 4;
int32 id = 5;
}
message CPUMode {
int32 mode = 1;
}
message AstroTrackingSpecialState {
notify.OperationState state = 1;
string target_name = 2;
int32 index = 3;
}
message PowerOff {
}
message AlbumUpdate {
int32 media_type = 1;
}
message SentryState {
notify.SentryModeState state = 1;
notify.SentryObjectType object_type = 2;
}
message OneClickGotoState {
// oneof current_state
notify.AstroAutoFocusState astro_auto_focus_state = 1;
notify.AstroCalibrationState astro_calibration_state = 2;
notify.AstroGotoState astro_goto_state = 3;
notify.AstroTrackingState astro_tracking_state = 4;
}
message StreamType {
int32 stream_type = 1;
int32 cam_id = 2;
}
message MultiTrackResult {
repeated notify.TrackResult results = 1;
}
message EqSolvingState {
notify.OperationState state = 1;
}
message LongExpPhotoProgress {
double total_time = 1;
double exposured_time = 2;
uint32 camera_type = 3;
}
message ShootingScheduleResultAndState {
string schedule_id = 1;
int32 result = 2;
int32 state = 3;
}
message ShootingTaskState {
string schedule_task_id = 1;
int32 state = 2;
int32 code = 3;
}
message SkySeacherState {
notify.OperationState state = 1;
}
message ProgressAiEnhance {
int32 progress = 1;
int32 total_time = 2;
}
message CommonProgress {
enum ProgressType {
PROGRESS_TYPE_INITING = 0;
PROGRESS_TYPE_MOSAIC_MOVING = 1;
}
int32 current = 1;
int32 total = 2;
notify.CommonProgress.ProgressType progress_type = 3;
}
message CalibrationResult {
double azi = 1;
double alt = 2;
}
message FocusPosition {
int32 pos = 1;
}
message SentryAutoHand {
int32 mode = 1;
}
message PanoramaStitchUploadComplete {
int32 code = 1;
string user_id = 2;
string busi_no = 3;
string panorama_name = 4;
string mac = 5;
}
message PanoramaCompressionComplete {
int32 code = 1;
string panorama_name = 2;
string zip_file_path = 3;
string zip_file_md5 = 4;
uint64 zip_file_size = 5;
string stitch_param = 6;
}
message PanoramaCompressionProgress {
string panorama_name = 1;
uint32 total_files_num = 2;
uint32 compressed_files_num = 3;
}
message PanoramaUploadCompressionProgress {
string user_id = 1;
string busi_no = 2;
string panorama_name = 3;
string mac = 4;
uint32 total_files_num = 5;
uint32 compressed_files_num = 6;
double speed = 7;
}
message PanoramaUploadProgress {
string user_id = 1;
string busi_no = 2;
string panorama_name = 3;
string mac = 4;
uint64 total_size = 5;
uint64 uploaded_size = 6;
double speed = 7;
}
message PanoramaCurrentUploadState {
int32 code = 1;
string user_id = 2;
string busi_no = 3;
string panorama_name = 4;
string mac = 5;
uint32 total_files_num = 6;
uint32 compressed_files_num = 7;
uint64 total_size = 8;
uint64 uploaded_size = 9;
uint32 step = 10;
}
message LowTempProtectionMode {
int32 mode = 1;
}
message StateSystemResourceOccupation {
enum TaskId {
IDLE = 0;
PANORAMA_UPLOAD = 1;
ASTRO_MULTI_STACK = 2;
}
notify.StateSystemResourceOccupation.TaskId task_id = 1;
notify.OperationState state = 2;
}
message BodyStatus {
enum BodyStatusEnum {
UNKNOWN = 0;
EQ_MODE = 1;
AZI_MODE = 2;
}
notify.BodyStatus.BodyStatusEnum body_status = 1;
}
message ProgressCaptureMosaic {
int32 total_count = 1;
int32 update_type = 2;
int32 current_count = 3;
int32 stacked_count = 4;
int32 exp_index = 5;
int32 gain_index = 6;
string target_name = 7;
int32 horizontal_scale = 8;
int32 vertical_scale = 9;
int32 rotation = 10;
int32 fov_id = 11;
int32 fov_total = 12;
}
message Wb {
uint64 mode = 1;
int32 ct = 2;
int32 scene = 3;
int32 camera_type = 4;
}
message GeneralIntParam {
uint64 param_id = 1;
int32 mode = 2;
int32 value = 3;
}
message GeneralFloatParam {
uint64 param_id = 1;
float value = 2;
}
message GeneralBoolParams {
uint64 param_id = 1;
bool value = 2;
}
message SwitchShootingMode {
int32 state = 1;
int32 source_mode = 2;
int32 dst_mode = 3;
}
message SwitchCropRatioState {
int32 state = 1;
int32 crop_ratio = 2;
}
message ResolutionParam {
uint64 param_id = 1;
int32 current_res_value = 2;
int32 current_fps_value = 3;
repeated int32 supported_fps_list = 4;
repeated int32 supported_resolution_list = 5;
}
message CaptureRawState {
notify.OperationState state = 1;
int32 camera_type = 2;
}
message PhotoState {
notify.OperationState state = 1;
int32 camera_type = 2;
}
message BurstState {
notify.OperationState state = 1;
int32 camera_type = 2;
}
message RecordState {
notify.OperationState state = 1;
int32 camera_type = 2;
}
message TimeLapseState {
notify.OperationState state = 1;
int32 camera_type = 2;
}
message CaptureRawDarkState {
notify.OperationState state = 1;
int32 camera_type = 2;
}
message PanoramaState {
notify.OperationState state = 1;
int32 camera_type = 2;
}
message AstroAutoFocusState {
notify.OperationState state = 1;
}
message NormalAutoFocusState {
notify.OperationState state = 1;
}
message AstroAutoFocusFastState {
notify.OperationState state = 1;
}
message AreaAutoFocusState {
notify.OperationState state = 1;
}
message DualCameraLinkageState {
notify.OperationState state = 1;
}
message NormalTrackState {
notify.OperationState state = 1;
int32 camera_type = 2;
}
message SwitchResolutionFpsState {
notify.OperationState state = 1;
int32 camera_type = 2;
}
message CaptureCaliFrameState {
notify.OperationState state = 1;
int32 camera_type = 2;
int32 cali_frame_type = 3;
}
message CaptureCaliFrameProgress {
int32 progress = 1;
int32 camera_type = 2;
int32 cali_frame_type = 3;
}
message DeviceAttitude {
double pitch = 1;
double yaw = 2;
double roll = 3;
}
message SkyTargetFinderState {
notify.OperationState state = 1;
int32 scene_type = 2;
}
message PanoFramingThumbnailUpdateNotify {
bytes webp_data = 1;
}
message PanoFramingRectUpdateNotify {
double norm_x_tl = 1;
double norm_y_tl = 2;
double norm_x_br = 3;
double norm_y_br = 4;
double norm_limit_x_left = 5;
double norm_limit_y_top = 6;
double norm_limit_x_right = 7;
double norm_limit_y_bottom = 8;
double rect_hor_fov = 9;
double rect_ver_fov = 10;
int32 error_code = 11;
}
message PanoFramingStateNotify {
int32 state = 1;
}
message AutoShutdown {
int32 state = 1;
}
message LensDefog {
int32 state = 1;
}
message AutoCooling {
int32 state = 1;
}

View File

@ -0,0 +1,108 @@
// source: panorama.proto
syntax = "proto3";
message ReqStartPanoramaByGrid {
}
message ReqStartPanoramaByEulerRange {
float yaw_range = 1;
float pitch_range = 2;
}
message ReqStartPanoramaStitchUpload {
uint64 resource_id = 1;
string user_id = 2;
int32 app_platform = 3;
string panorama_name = 4;
string ak = 5;
string sk = 6;
string token = 7;
string bucket = 8;
string bucket_prefix = 9;
string from = 10;
string env_type = 11;
}
message ReqStopPanorama {
}
message ReqStopPanoramaStitchUpload {
string user_id = 1;
}
message ReqGetPanoramaCurrentUploadState {
}
message ResGetPanoramaCurrentUploadState {
int32 code = 1;
string user_id = 2;
string busi_no = 3;
string panorama_name = 4;
string mac = 5;
uint32 total_files_num = 6;
uint32 compressed_files_num = 7;
uint64 total_size = 8;
uint64 uploaded_size = 9;
uint32 step = 10;
}
message ReqGetUploadPredict {
string panorama_name = 1;
}
message ResGetUploadPredict {
int32 code = 1;
string panorama_name = 2;
uint32 file_nums = 3;
string resolution = 4;
uint64 cloud_data_size = 5;
uint64 zip_data_size = 6;
uint64 app_zip_data_size = 7;
}
message PanoramaUploadParam {
string user_id = 1;
string busi_no = 2;
string panorama_name = 3;
string mac = 4;
uint32 total_files_num = 5;
uint32 compressed_files_num = 6;
uint64 total_size = 7;
uint64 uploaded_size = 8;
uint32 step = 9;
}
message ReqCompressPanorama {
string panorama_name = 1;
}
message ReqStopCompressPanorama {
}
message ReqStartPanoramaFraming {
}
message ReqResetPanoramaFraming {
}
message ReqStopPanoramaFraming {
}
message ReqStopPanoramaFramingAndStartGrid {
}
message ResStopPanoramaFraming {
int32 code = 1;
double centerX_degree_offset = 2;
double centerY_degree_offset = 3;
uint32 framing_rows = 4;
uint32 framing_cols = 5;
}
message ReqUpdatePanoramaFramingRect {
double norm_x_tl = 1;
double norm_y_tl = 2;
double norm_x_br = 3;
double norm_y_br = 4;
}

View File

@ -0,0 +1,52 @@
// source: param.proto
package param;
syntax = "proto3";
message ReqSetExposure {
uint64 param_id = 1;
int32 mode = 2;
int32 value = 3;
}
message ReqSetGain {
uint64 param_id = 1;
int32 mode = 2;
int32 value = 3;
}
message ReqSetWb {
uint64 param_id = 1;
int32 mode = 2;
int32 value = 3;
}
message ReqSetGeneralIntParam {
uint64 param_id = 1;
int32 value = 2;
}
message ReqSetGeneralFloatParam {
uint64 param_id = 1;
float value = 2;
}
message ReqSetGeneralBoolParams {
uint64 param_id = 1;
bool value = 2;
}
message ReqSetAutoParam {
int32 camera_type = 1;
int32 shooting_tech = 2;
bool is_auto = 3;
}
message ResSetAutoParam {
int32 shooting_mode = 1;
int32 camera_type = 2;
int32 shooting_tech = 3;
bool is_auto = 4;
bool update_all = 5;
int32 code = 6;
}

21
analysis/protos/RGB.proto Normal file
View File

@ -0,0 +1,21 @@
// source: rgb.proto
syntax = "proto3";
message ReqOpenRgb {
}
message ReqCloseRgb {
}
message ReqPowerDown {
}
message ReqOpenPowerInd {
}
message ReqClosePowerInd {
}
message ReqReboot {
}

View File

@ -0,0 +1,157 @@
// source: shooting_schedule.proto
syntax = "proto3";
enum ShootingScheduleState {
SHOOTING_SCHEDULE_STATE_INITIALIZED = 0;
SHOOTING_SCHEDULE_STATE_PENDING_SHOOT = 1;
SHOOTING_SCHEDULE_STATE_SHOOTING = 2;
SHOOTING_SCHEDULE_STATE_COMPLETED = 3;
SHOOTING_SCHEDULE_STATE_EXPIRED = 4;
}
enum ShootingScheduleSyncState {
SHOOTING_SCHEDULE_SYNC_STATE_PENDING_SYNC = 0;
SHOOTING_SCHEDULE_SYNC_STATE_SYNCED = 1;
}
enum ShootingScheduleResult {
SHOOTING_SCHEDULE_RESULT_PENDING_START = 0;
SHOOTING_SCHEDULE_RESULT_ALL_COMPLETED = 1;
SHOOTING_SCHEDULE_RESULT_PARTIALLY_COMPLETED = 2;
SHOOTING_SCHEDULE_RESULT_ALL_FAILED = 3;
}
enum ShootingTaskState {
SHOOTING_TASK_STATUS_IDLE = 0;
SHOOTING_TASK_STATUS_SHOOTING = 1;
SHOOTING_TASK_STATUS_SUCCESS = 2;
SHOOTING_TASK_STATUS_FAILED = 3;
SHOOTING_TASK_STATUS_INTERRUPTED = 4;
}
enum ShootingScheduleMode {
SHOOTING_SCHEDULE_MODE_ASTRO_DEEP_SKY = 0;
}
message ShootingTaskMsg {
string schedule_id = 1;
string params = 2;
ShootingTaskState state = 3;
int32 code = 4;
int64 created_time = 5;
int64 updated_time = 6;
string schedule_task_id = 7;
int32 param_mode = 8;
int32 param_version = 9;
int32 create_from = 10;
}
message ShootingScheduleMsg {
string schedule_id = 1;
string schedule_name = 2;
int32 device_id = 3;
string mac_address = 4;
int64 start_time = 5;
int64 end_time = 6;
ShootingScheduleResult result = 7;
int64 created_time = 8;
int64 updated_time = 9;
ShootingScheduleState state = 10;
int32 lock = 11;
string password = 12;
repeated ShootingTaskMsg shooting_tasks = 13;
int32 param_mode = 14;
int32 param_version = 15;
string params = 16;
int64 schedule_time = 17;
ShootingScheduleSyncState sync_state = 18;
}
message ReqSyncShootingSchedule {
ShootingScheduleMsg shooting_schedule = 1;
}
message ResSyncShootingSchedule {
ShootingScheduleMsg shooting_schedule = 1;
repeated string time_conflict_schedule_ids = 2;
int32 code = 3;
bool can_replace = 4;
}
message ReqCancelShootingSchedule {
string id = 1;
string password = 2;
}
message ResCancelShootingSchedule {
string id = 1;
int32 code = 2;
}
message ReqGetAllShootingSchedule {
}
message ResGetAllShootingSchedule {
repeated ShootingScheduleMsg shooting_schedule = 1;
int32 code = 2;
}
message ReqGetShootingScheduleById {
string id = 1;
}
message ResGetShootingScheduleById {
ShootingScheduleMsg shooting_schedule = 1;
int32 code = 2;
}
message ReqGetShootingTaskById {
string id = 1;
}
message ResGetShootingTaskById {
ShootingTaskMsg shooting_task = 1;
int32 code = 2;
}
message ReqReplaceShootingSchedule {
ShootingScheduleMsg shooting_schedule = 1;
}
message ResReplaceShootingSchedule {
ShootingScheduleMsg shooting_schedule = 1;
repeated ShootingScheduleMsg replaced_shooting_schedule = 2;
int32 code = 3;
}
message ReqUnlockShootingSchedule {
string id = 1;
string password = 2;
}
message ResUnlockShootingSchedule {
string id = 1;
int32 code = 2;
}
message ReqLockShootingSchedule {
string id = 1;
string password = 2;
}
message ResLockShootingSchedule {
string id = 1;
string password = 2;
int32 code = 3;
}
message ReqDeleteShootingSchedule {
string id = 1;
string password = 2;
}
message ResDeleteShootingSchedule {
string id = 1;
int32 code = 2;
}

View File

@ -0,0 +1,72 @@
// source: system.proto
syntax = "proto3";
message ReqSetTime {
uint64 timestamp = 1;
double timezone_offset = 2;
}
message ReqSetTimezone {
string timezone = 1;
}
message ReqSetMtpMode {
int32 mode = 1;
}
message ReqSetCpuMode {
int32 mode = 1;
}
message ReqsetMasterLock {
bool lock = 1;
}
message ReqGetDeviceActivateInfo {
int32 issuer = 1;
}
message ResDeviceActivateInfo {
int32 activate_state = 1;
int32 activate_process_state = 2;
string request_param = 3;
}
message ReqDeviceActivateWriteFile {
string request_param = 1;
}
message ResDeviceActivateWriteFile {
int32 code = 1;
string request_param = 2;
}
message ReqDeviceActivateSuccessfull {
string request_param = 1;
}
message ResDeviceActivateSuccessfull {
int32 code = 1;
int32 activate_state = 2;
}
message ReqDisableDeviceActivate {
string request_param = 1;
}
message ResDisableDeviceActivate {
int32 code = 1;
int32 activate_state = 2;
}
message ReqSetLocation {
double latitude = 1;
double longitude = 2;
double altitude = 3;
string country_region = 4;
string province = 5;
string city = 6;
string district = 7;
bool enable = 8;
}

View File

@ -0,0 +1,204 @@
// source: task_center.proto
syntax = "proto3";
import "notify.proto";
import "panorama.proto";
import "astro.proto";
enum TaskId {
TASK_ID_IDLE = 0;
TASK_ID_PANORAMA_UPLOAD = 1;
TASK_ID_ASTRO_MULTI_STACK_THUMBNAIL_GENERATION = 2;
TASK_ID_ASTRO_MULTI_STACK = 3;
TASK_ID_CAPTURE_CALI_FRAME = 4;
}
enum ExclusiveTaskType {
EXCLUSIVE_TYPE_NONE = 0;
EXCLUSIVE_TYPE_CAMERA = 1;
EXCLUSIVE_TYPE_MOTOR = 2;
EXCLUSIVE_TYPE_FOCUS_MOTOR = 4;
EXCLUSIVE_TYPE_SYSTEM_IO = 8;
EXCLUSIVE_TYPE_SYSTEM_WIFI = 16;
}
message TaskAttr {
int32 exclusive_mask = 1;
int32 priority = 2;
}
message TaskState {
// oneof extendedState
notify.OperationState base_state = 1;
notify.AstroState astro_extended_state = 2;
}
message TaskParam {
// oneof param
PanoramaUploadParam panorama_upload = 1;
MakeFitsThumbTaskParam make_fits_thumb_task_param = 2;
RepostprocessTaskParam repostprocess_task_param = 3;
CaptureCaliFrameTaskParam capture_cali_frame_task_param = 4;
}
message ResNotifyTaskState {
TaskId task_id = 1;
TaskAttr task_attr = 2;
TaskState state = 3;
TaskParam param = 4;
}
message ReqStartTask {
// oneof param
TaskId task_id = 1;
ReqStartMakeFitsThumb req_make_fits_thumb_param = 2;
ReqStartRepostprocess req_repostprocess_param = 3;
}
message ReqStopTask {
TaskId task_id = 1;
}
message ResTaskCenter {
int32 code = 1;
TaskId task_id = 2;
}
message ClientParams {
int32 encode_type = 1;
}
message ReqEnterCamera {
ClientParams client_param = 3;
}
message ResEnterCamera {
int32 code = 1;
int32 shooting_mode_id = 2;
}
message ReqSwitchShootingMode {
int32 mode = 1;
}
message ResSwitchShootingMode {
int32 code = 1;
int32 shooting_mode_id = 2;
}
message ReqSwitchShootingTech {
int32 tech = 1;
}
message ResSwitchShootingTech {
int32 code = 1;
int32 shooting_tech_id = 2;
}
message ReqGetDeviceStateInfo {
}
message ExclusiveCameraState {
// oneof current_state
notify.CaptureRawState capture_raw_state = 1;
notify.PhotoState photo_state = 2;
notify.BurstState burst_state = 3;
notify.RecordState record_state = 4;
notify.TimeLapseState timelapse_state = 5;
notify.CaptureCaliFrameState capture_cali_frame_state = 6;
notify.PanoramaState panorama_state = 7;
notify.SentryState sentry_state = 8;
}
message TeleCameraStateInfo {
// oneof _cmos_temperature
ExclusiveCameraState exclusive_state = 1;
notify.StreamType stream_type = 2;
double h_fov = 3;
double v_fov = 4;
uint32 resolution_width = 5;
uint32 resolution_height = 6;
notify.CmosTemperature cmos_temperature = 7;
}
message WideCameraStateInfo {
// oneof _cmos_temperature
ExclusiveCameraState exclusive_state = 1;
notify.StreamType stream_type = 2;
double h_fov = 3;
double v_fov = 4;
uint32 resolution_width = 5;
uint32 resolution_height = 6;
notify.CmosTemperature cmos_temperature = 7;
}
message ExclusiveFocusMotorState {
// oneof current_state
notify.AstroAutoFocusState astro_auto_focus_state = 1;
notify.NormalAutoFocusState normal_auto_focus_state = 2;
notify.AstroAutoFocusFastState astro_auto_focus_fast_state = 3;
notify.AreaAutoFocusState area_auto_focus_state = 4;
}
message FocusMotorStateInfo {
// oneof _focus_position
ExclusiveFocusMotorState exclusive_state = 1;
notify.FocusPosition focus_position = 2;
}
message ExclusiveMotionMotorState {
// oneof current_state
notify.AstroCalibrationState astro_calibration_state = 1;
notify.AstroGotoState astro_goto_state = 2;
notify.AstroTrackingState astro_tracking_state = 3;
notify.NormalTrackState normal_track_state = 4;
notify.OneClickGotoState one_click_goto_state = 5;
notify.EqSolvingState eq_state = 6;
notify.SentryState sentry_state = 7;
notify.SkyTargetFinderState sky_target_finder_state = 8;
}
message MotionMotorStateInfo {
ExclusiveMotionMotorState exclusive_state = 1;
notify.SentryAutoHand sentry_auto_hand = 2;
}
message DeviceStateInfo {
notify.RgbState rgb_state = 1;
notify.PowerIndState power_ind_state = 2;
notify.ChargingState charging_state = 3;
notify.StorageInfo storage_info = 4;
notify.MTPState mtp_state = 5;
notify.CPUMode cpu_mode = 6;
notify.Temperature temperature = 7;
notify.BodyStatus body_status = 8;
notify.BatteryInfo battery_info = 9;
notify.CalibrationResult calibration_result = 10;
notify.PictureMatching picture_matching = 11;
notify.AutoShutdown auto_shutdown = 12;
notify.LensDefog lens_defog = 13;
notify.AutoCooling auto_cooling = 14;
}
message ConnectionStateInfo {
notify.HostSlaveMode host_slave_mode = 1;
}
message ShootingModeAndTech {
int32 shooting_mode = 1;
int32 parent_shooting_mode = 2;
repeated int32 shooting_techs = 3;
}
message ResGetDeviceStateInfo {
int32 shooting_mode = 1;
TeleCameraStateInfo tele_camera_state_info = 2;
WideCameraStateInfo wide_camera_state_info = 3;
FocusMotorStateInfo focus_motor_state_info = 4;
MotionMotorStateInfo motion_motor_state_info = 5;
DeviceStateInfo device_state_info = 6;
int32 code = 7;
ConnectionStateInfo connection_state_info = 8;
repeated ShootingModeAndTech shooting_mode_and_techs = 9;
}

View File

@ -0,0 +1,41 @@
// source: track.proto
syntax = "proto3";
message ReqStartTrack {
int32 x = 1;
int32 y = 2;
int32 w = 3;
int32 h = 4;
int32 cam_id = 5;
}
message ReqStopTrack {
}
message ReqPauseTrack {
}
message ReqContinueTrack {
}
message ReqStartSentryMode {
int32 type = 1;
}
message ReqStopSentryMode {
}
message ReqMOTTrackOne {
int32 id = 1;
}
message ReqUFOAutoHandMode {
int32 mode = 1;
}
message ReqStartTrackClick {
int32 x = 1;
int32 y = 2;
int32 cam_id = 3;
}

View File

@ -0,0 +1,140 @@
// source: voice_assistant.proto
syntax = "proto3";
import "base.proto";
import "notify.proto";
import "task_center.proto";
enum VoiceCommandType {
VOICE_CMD_UNKNOWN = 0;
VOICE_CMD_GET_STATUS = 1;
VOICE_CMD_TAKE_PHOTO = 2;
VOICE_CMD_START_RECORD = 3;
VOICE_CMD_STOP_RECORD = 4;
VOICE_CMD_START_TIMELAPSE = 5;
VOICE_CMD_STOP_TIMELAPSE = 6;
VOICE_CMD_START_BURST = 7;
VOICE_CMD_STOP_BURST = 8;
VOICE_CMD_START_ASTRO = 9;
VOICE_CMD_STOP_ASTRO = 10;
VOICE_CMD_START_SENTRY = 11;
VOICE_CMD_STOP_SENTRY = 12;
VOICE_CMD_MOVE = 13;
VOICE_CMD_GOTO_TARGET = 14;
VOICE_CMD_CALIBRATION = 15;
VOICE_CMD_AUTO_FOCUS = 16;
VOICE_CMD_STOP_FOCUS = 17;
VOICE_CMD_STOP_ALL = 18;
}
message ReqVoiceCommand {
// oneof params
VoiceCommandType command_type = 1;
int32 shooting_mode = 2;
VoicePhotoParams photo_params = 10;
VoiceRecordParams record_params = 11;
VoiceTimelapseParams timelapse_params = 12;
VoiceBurstParams burst_params = 13;
VoiceAstroParams astro_params = 14;
VoiceSentryParams sentry_params = 15;
VoiceMoveParams move_params = 16;
VoiceGotoParams goto_params = 17;
VoiceCalibrationParams calibration_params = 18;
VoiceFocusParams focus_params = 19;
}
message VoicePhotoParams {
int32 camera_type = 1;
}
message VoiceRecordParams {
int32 camera_type = 1;
int32 duration_seconds = 2;
}
message VoiceTimelapseParams {
int32 camera_type = 1;
int32 interval_seconds = 2;
int32 duration_seconds = 3;
}
message VoiceBurstParams {
int32 camera_type = 1;
int32 count = 2;
}
message VoiceAstroParams {
string target_name = 1;
double ra = 2;
double dec = 3;
int32 index = 4;
double lon = 5;
double lat = 6;
bool auto_goto = 7;
bool force_start = 8;
}
message VoiceSentryParams {
int32 type = 1;
}
message VoiceMoveParams {
double azimuth_angle = 1;
double altitude_angle = 2;
int32 speed = 3;
}
message VoiceGotoParams {
string target_name = 1;
double ra = 2;
double dec = 3;
int32 index = 4;
double lon = 5;
double lat = 6;
int32 shooting_mode = 7;
}
message VoiceCalibrationParams {
double lon = 1;
double lat = 2;
}
message VoiceFocusParams {
bool is_infinity = 1;
}
message ResVoiceCommand {
// oneof result
int32 code = 1;
string message = 2;
VoiceCommandType command_type = 3;
VoiceStatusResult status_result = 10;
VoiceOperationResult operation_result = 11;
}
message AstroShootingProgress {
string target_name = 1;
int32 captured_count = 2;
int32 total_count = 3;
int32 stacked_count = 4;
int32 progress_percentage = 5;
int64 elapsed_time = 6;
int64 remaining_time = 7;
}
message VoiceStatusResult {
ResGetDeviceStateInfo device_state_info = 1;
AstroShootingProgress astro_progress = 2;
}
message VoiceOperationResult {
bool success = 1;
string detail_message = 2;
}
message ResNotifyVoiceAssistant {
VoiceCommandType command_type = 1;
notify.OperationState state = 2;
string message = 4;
}