# Plan de test — dwarfctl sur télescope réel ## Conditions de test - **Télescope** : DWARF II, firmware 2.1.6, mode AP (hotspot WiFi) - **IP** : `192.168.88.1` - **Réseau** : machine connectée au hotspot du télescope - **Environnement** : intérieur, journée (pas d'accès au ciel/étoiles) ## Découvertes protocolaires importantes ### Modèle de réponse du télescope Le télescope utilise **type=3 (REPLY)** pour les réponses directes, PAS type=1 (RESPONSE). De plus, certaines commandes ne reçoivent AUCUNE réponse directe — seulement des notifications (type=2). | Pattern | Commandes | Comportement | |---------|-----------|--------------| | **Reply type=3 (même cmd)** | `photo` (10002), `focus auto` (15000), `focus step` (15001), `state` (16405) | Réponse directe avec le même cmd → request-response | | **Notification uniquement** | `rgb-on/off` (13500/13501), `camera open/close` (10000/10001), `camera params` (10036) | Pas de reply → fire-and-forget + vérifier via `state` | | **Fire-and-forget natif** | `motor slew` (14006), `motor stop` (14002) | Pas d'ack attendu | ### Implémentation dans dwarfctl - `send()` : attend un type=3 reply (10s timeout) — pour photo, focus, state - `sendNotify()` : fire-and-forget — pour RGB, camera open/close, motor slew - Flag `--debug` / `-d` : loggue tout le trafic WebSocket (cmd, module, type, taille data) ## Tests par groupe ### ✅ 1. Connexion (PASS) | Test | Commande | Résultat | |------|----------|---------| | Ping | `ping 192.168.88.1` | ✅ 36ms | | Port 9900 (WebSocket) | `/dev/tcp/192.168.88.1/9900` | ✅ OPEN | | Port 80 (RTSP) | `/dev/tcp/192.168.88.1/80` | ✅ OPEN | | WebSocket handshake | `dwarfctl --ip 192.168.88.1 state` | ✅ connexion établie | ### ✅ 2. État du device (PASS) ```bash dwarfctl --ip 192.168.88.1 state ``` Réponse complète : shooting_mode, cameras (résolution, FoV), focus position (594), batterie (100%), stockage (38/52 GB), température CMOS, modes disponibles. ### ✅ 3. Caméra Tele (PASS) | Test | Commande | Debug | Statut | |------|----------|-------|--------| | Open camera | `camera open --cam tele` | fire-and-forget | ✅ | | Photo | `camera photo --cam tele` | reply cmd=10002 type=3 data=11B | ✅ photo capturée | | Focus step out | `focus step 1` | reply cmd=15001 type=3 data=0B | ✅ | ### ✅ 4. Moteurs / Slew (PASS) Tests systématiques effectués — tous les mouvements confirmés visuellement sur le télescope. #### 4.1 Directions cardinales (joystick cmd 14006) | Direction | Angle | Length | Durée | Résultat | |-----------|-------|--------|-------|----------| | HAUT | 0° | 0.3 | 2s | ✅ mouvement observé | | DROITE | 90° | 0.3 | 2s | ✅ mouvement observé | | BAS | 180° | 0.3 | 2s | ✅ mouvement observé | | GAUCHE | 270° | 0.3 | 2s | ✅ mouvement observé | **Système de coordonnées joystick** : angle en degrés (polaire), 0°=haut, 90°=droite, 180°=bas, 270°=gauche. Length = vitesse normalisée (0.0 à 1.0). #### 4.2 Vitesses variables | Vitesse | Length | Résultat | |---------|--------|----------| | Lente | 0.1 | ✅ mouvement visible et lent | | Moyenne | 0.5 | ✅ mouvement net | | Rapide | 0.9 | ✅ mouvement rapide | #### 4.3 Diagonales | Direction | Angle | Résultat | |-----------|-------|----------| | HAUT-DROITE | 45° | ✅ mouvement diagonal | | BAS-GAUCHE | 225° | ✅ mouvement diagonal | Le joystick est bien polaire — 360° de liberté, pas seulement 4 directions. #### 4.4 Arrêt d'urgence | Test | Commande | Résultat | |------|----------|----------| | Stop pendant slew | `motor stop 0` (cmd 14002) | ✅ arrêt immédiat | | Stop motor 1 | `motor stop 1` | ✅ | Le `motor stop` interrompt un slew en cours instantanément. #### 4.5 Motor run/goto (cmd 14000) | Test | Commande | Résultat | |------|----------|----------| | Run to position | `motor goto 0 10 5` | ✅ fire-and-forget envoyé | `ReqMotorRunTo` : moteur ID, position cible, vitesse. Fire-and-forget (pas de ack type=3). #### 4.6 Observations sur la lecture de position - **`focus_position`** (moteur de mise au point) : visible dans `state` → `focus_position:{pos:593}`, reste stable pendant les mouvements de pointage. - **Position moteurs de pointage (RA/DEC)** : `motion_motor_state_info:{exclusive_state:{}}` reste vide — la position des moteurs alt-az n'est PAS exposée dans `GetDeviceState`. - Les messages proto `ReqMotorGetPosition` et `ReqMotorReset` existent dans le proto mais ne sont **pas utilisés par l'app Android** (aucune classe de requête correspondante). La lecture de position se fait probablement via les notifications d'attitude (cmd 15295 `CMD_NOTIFY_DEVICE_ATTITUDE`). ### ✅ 5. RGB / Power (PASS après fix fire-and-forget) | Test | Commande | Avant fix | Après fix | |------|----------|-----------|-----------| | RGB off | `power rgb-off` | ❌ timeout (cmd 13501) | ✅ fire-and-forget | | RGB on | `power rgb-on` | ❌ timeout (cmd 13500) | ✅ fire-and-forget | Vérification : `rgb_state:{}` (éteint) vs `rgb_state:{state:1}` (allumé) dans `state`. ### ✅ 6. Focus (PASS) | Test | Commande | Debug | Statut | |------|----------|-------|--------| | Autofocus | `focus auto` | notifications + reply cmd=15000 type=3 | ✅ | | Step out | `focus step 1` | reply cmd=15001 type=3 | ✅ | ### ✅ 7. System (NON TESTÉ — nécessite validation) | Test | Commande | Notes | |------|----------|-------| | Sync time | `system sync-time` | À tester | | Set location | `system set-location 48.86 2.35 35` | À tester | ### ❌ 8. Astrophotographie (NON TESTABLE — jour/intérieur) Ces commandes nécessitent un ciel étoilé nocturne : | Test | Raison | |------|--------| | `astro calibrate start` | Nécessite des étoiles visibles | | `astro goto-dso` | Nécessite le ciel | | `astro stack start` | Nécessite des étoiles | | `astro eq-solve start` | Nécessite des étoiles | | `track start` | Nécessite une cible mobile | ### ❌ 9. Camera params (KNOWN ISSUE) `camera params --cam tele` (cmd 10036) : le télescope ne renvoie pas de reply. Les paramètres sont toutefois visibles dans la réponse `state` (résolution, FoV). Les paramètres ajustables (exposure, gain) nécessiteraient une commande GET qui ne répond pas en type=3. ## Bugs corrigés pendant les tests 1. **`readLoop` ne dispatchait pas type=3 correctement** → corrigé : tous les types sont dispatchés vers `dispatchResponse` + `dispatchNotification` 2. **Commandes RGB/camera open attendaient un reply inexistant** → converties en fire-and-forget (`sendNotify`) 3. **Motor stop/goto attendaient un reply** → convertis en fire-and-forget 4. **Pas de logging** → ajout du flag `--debug` / `-d` ## Tests unitaires ``` ok github.com/antitbone/dwarfctl/internal/transport 0.003s ok github.com/antitbone/dwarfctl/internal/api 0.003s ``` 57 tests, tous PASS.