A Cockpit mock IoBase + Asystom + DAP
Pourquoi un mock ?
Au moment de la livraison de cette doc, ni IoBase ni Asystom Advisor ne sont accessibles depuis la CG (URLs prod, credentials, validation Jean-Marc à venir). Pour valider que toute la chaîne canvas fonctionne avant ces dépendances, on a écrit un serveur Python local qui simule les 3 APIs avec validation stricte des contrats spec.
Le fichier
| Path | /Users/pierredulac/dev/klaud-vault/1 PROJECTS/White Box/CloudGate/mock_cockpit.py |
|---|---|
| Stack | Python 3 stdlib uniquement (http.server + json) — zéro dépendance |
| Port | 9000 (bind 0.0.0.0 → joignable depuis CG via 192.168.42.122) |
| Lancement | python3 mock_cockpit.py |
| Dashboard | http://localhost:9000/dashboard |
Endpoints simulés
| Endpoint | Spec source | Validation |
|---|---|---|
POST /register | DAP IoBase intercom | Body {name}. Génère device_code, auto-validate. |
POST /Token | DAP IoBase intercom | Body {device_code, client_id}. 425 si pas validé. |
POST /refresh | DAP IoBase intercom | Body {refresh_token, client_id}. 401 si refresh_token consommé. |
POST /api/v1/cloudgate/payloads | API IoBase v1.0 PDF Holmes | Bearer + 6 champs body + ISO 8601. 400 si manquant. |
POST /gateway/health | Implicite spec | Bearer match access_token de la session. |
POST /lorawan | API Asystom PDF Patrick Duc | Basic auth + header X-Network. |
GET /getPendingMsgs?client=… | API Asystom PDF Patrick Duc | Réponse {device_list, payload, cmd}. |
POST /api/inject_downlink | cockpit-only | Permet au dashboard de planifier un downlink à recevoir au prochain poll. |
GET /api/state | cockpit-only | Retourne tout l'état RAM (uplinks, healths, dap_log, session, stats). |
Le dashboard
Auto-refresh toutes les 2 secondes. 5 cartes de validation + topologie animée.
Topologie
Vue [CloudGate]──5 flèches──[Mock Cockpit]. Chaque flèche s'allume vert quand le flux a eu de l'activité dans les 60 dernières secondes (badge "actif"), grise sinon.
Carte DAP
4 KPIs : register / Token / refresh / total. Fields device_code, validated, access_token, refresh_token, last call. Badge :
- 🔘 pas enrôlé : aucun device_code
- 🟠 enrôlé pas de token : device_code reçu mais pas encore Token (pending validation)
- 🟢 enrôlé · token actif : access_token + refresh_token stockés
Carte IoBase Flux 01
4 KPIs : uplinks count, DevEUI distincts, equipment_model du dernier, site du dernier. Affichage de la dernière trame avec X-CloudGate-Id, X-Device-Id, body keys, payload tronqué.
Carte Asystom Flux 02
Similaire à IoBase mais avec network header + format Loriot-like.
Carte Flux 03 Downlink
Affiche les polls reçus, downlinks en queue, dispatched (consommés par le dernier poll).
Bouton « Inject downlink » : permet de planifier un payload + cmd + DevEUI dans la queue. Au prochain poll Asystom (60s max), la chaîne CG le récupère et l'envoie en LoRa downlink.
Carte Flux 04 Health
7 KPIs : POSTs reçus, life_counter, uptime, lora_uplinks_count, lora_status, gsm_rssi, operator. Affichage du dernier health POST en clair.
Comment lancer
cd "1 PROJECTS/White Box/CloudGate"
python3 mock_cockpit.py
# → http://localhost:9000/dashboard
# Le canvas LuvitRED de la CG doit avoir ses globals pointés vers le mock :
# global.iobase_host = '192.168.42.122:9000'
# global.dap_host = '192.168.42.122:9000'
# global.asystom_url = 'http://192.168.42.122:9000'
# global.asystom_auth_b64 = 'dGVyZWdhOnRlc3Q=' (terega:test, dummy)
# global.asystom_client = 'terega'
Tests automatisés via curl
# Login pour obtenir une session LuvitRED
curl -c /tmp/lc.cookies -X POST -H "Content-Type: application/json" \
-d '{"username":"admin","password":"@IOTvalley31"}' \
http://192.168.42.1/api/login
# Trigger DAP register
curl -b /tmp/lc.cookies -X POST http://192.168.42.1:8080/inject/<DAP_REGISTER_ID>
# Trigger DAP get token (~2s plus tard)
curl -b /tmp/lc.cookies -X POST http://192.168.42.1:8080/inject/<DAP_TOKEN_ID>
# Vérifier l'état mock
curl http://localhost:9000/api/state | python3 -m json.tool
# Reset mock pour test propre
curl -X POST http://localhost:9000/api/clear
Migration mock → prod
Le passage en prod est une simple modification des globals dans fn_startup_init :
| Global | Mock value | Prod value (à fournir Terega/Asystom) |
|---|---|---|
iobase_host | 192.168.42.122:9000 | iobase.terega.fr |
dap_host | 192.168.42.122:9000 | dap.indaba.io |
asystom_url | http://192.168.42.122:9000 | https://advisor.asystom.cloud |
asystom_auth_b64 | dGVyZWdhOnRlc3Q= | (real base64 from Patrick) |
iobase_site | TODO_SITE | vandellans |
iobase_datasource | TODO_DATASOURCE | transportation |
iobase_metrics_default | [] | liste réelle des métriques Indaba |
Aucune modification du canvas n'est nécessaire. Les chaînes pivotent automatiquement.