03 API IoBase v1.0
Format aligné spec PDF Christophe Holmes (Terega) du 2026-04-16 · Flux 01 + 04
Source de vérité
Document : API d'Ingestion IoT (CloudGate)-v1.0.pdf joint au mail Othmane Slaoui (IoT Valley) « Fwd: CloudGate : API Payload devices LoraWan » du 2026-04-20, lui-même forward de Christophe Holmes (Terega) du 2026-04-16.
Flux 01 — Sensor uplinks
Endpoint
| URL | POST <iobase_host>/api/v1/cloudgate/payloads |
|---|---|
| Méthode | POST |
| Content-Type | application/json |
Headers obligatoires
| Header | Source canvas | Description |
|---|---|---|
X-CloudGate-Id | global.cloudgate_device_name | Identifiant unique de la passerelle |
X-Device-Id | msg.DevEUI | DevEUI de la balise émettrice |
Authorization | 'Bearer ' .. global.iobase_token | Bearer DAP. Voir Chap. 02. |
Content-Type | hardcoded | application/json |
Body JSON (champs requis)
| Champ | Type | Requis | Source canvas / valeur |
|---|---|---|---|
equipment_model | String | Oui | global.iobase_equipment_model (def: asystom_sentinel) |
payload | String hex | Oui | Hex lowercase de msg.payload (trame LoRa raw) |
site | String | Oui | global.iobase_site (à set par Terega, def: TODO_SITE) |
datasource | String | Oui | global.iobase_datasource (à set par Terega, def: TODO_DATASOURCE) |
metrics | Array[String] | Oui | global.iobase_metrics_default (à set par Terega, def: []) |
options | String | Non | global.iobase_options. Omis du body si vide. |
timestamp | String ISO 8601 | Oui | os.date('!%Y-%m-%dT%H:%M:%SZ', os.time()) |
Exemple de POST réel (capturé du mock)
POST /api/v1/cloudgate/payloads HTTP/1.1
Host: 192.168.42.122:9000
Content-Type: application/json
Authorization: Bearer AT9d8f7a6e5b4c3d2e1a0f9e8d7c6b5a4e
X-CloudGate-Id: cloudgate-terega-01
X-Device-Id: 0004A30B010593C1
{
"equipment_model": "asystom_sentinel",
"payload": "00a2070e4c210239360be184f67dd87c417cc87a...",
"site": "TODO_SITE",
"datasource": "TODO_DATASOURCE",
"metrics": [],
"timestamp": "2026-04-25T14:35:22Z"
}
Codes de réponse
| Code | Statut | Comportement canvas |
|---|---|---|
| 200 | OK décodé + écrit Indaba | global.last_iobase_ok_ts = os.time() |
| 202 | Accepted (queued pour traitement) | Idem 200 |
| 400 | Bad Request (champ obligatoire manquant) | Log erreur. Pas de retry. À investiguer côté config (probablement global.iobase_* mal set). |
| 401/403 | Authentication failed | fn_trigger_refresh_on_401 → build_dap_refresh → retry du POST avec nouveau token |
| 500 | Server Error | Mis en queue offline (queueenabled=true), replay auto |
Flux 04 — Health
Endpoint
| URL | POST <iobase_host>/gateway/health |
|---|---|
| Méthode | POST |
| Content-Type | application/json |
| Auth | Bearer <global.iobase_token> |
Cadence d'émission
- Cron horaire (3600s) :
health hourlyinject - + 1 fire à chaque event capteur (per devis : « envoyer cycliquement à chaque event capteur + 1×/heure »)
Body Health
{
"timestamp": 1714056789,
"source": "cloudgate",
"device_id": "cloudgate-terega-01",
"life_counter": 6579,
"uptime_seconds": 6833,
"lora_uplinks_count": 33,
"last_lora_ts": 1714056772,
"last_iobase_ok_ts": 1714056774,
"last_asystom_ok_ts": 1714056775,
"lora_status": "active",
"gsm_rssi": -85,
"gsm_signal_quality": null,
"gsm_operator": "F-Bouygues Telecom",
"gsm_technology": "GSM",
"gsm_rfband": "GSM 900",
"modem_model": "BG96",
"sim_status": null
}
Sémantique des champs
life_counter
Compteur de vie 0→32000 cyclique. Indaba alerting détecte si figé entre 2 health POSTs.
uptime_seconds
os.time() - global.start_time. Reset à chaque reboot, pas à chaque deploy.lora_uplinks_count
Cumul depuis le boot. Permet de calculer le débit moyen côté serveur.
lora_status
Dérivé de la fraîcheur de la dernière trame :
active (< 5 min), idle (< 30 min), stale (≥ 30 min).last_iobase_ok_ts / last_asystom_ok_ts
Timestamp du dernier POST 2xx. Permet de mesurer la santé sortante.
gsm_rssi
RSSI en dBm depuis l'API admin CG
/api/diagnostics?device=wwan0. Plage typique -50 (excellent) à -110 (perdu).gsm_operator + gsm_technology + gsm_rfband + modem_model
Pour identifier le modem (Quectel BG96 sur le pilote), le réseau (GSM 900 / LTE / 4G), et l'opérateur (Bouygues, Orange, etc.).
Compatibilité legacy
Endpoint legacy
Le mock cockpit accepte aussi POST /sensor/data (ancien format des premières versions de la chaîne) en réponse 201, pour compatibilité avec les flow exports des sessions de dev. Le canvas actuel utilise exclusivement /api/v1/cloudgate/payloads.
À fournir par Terega avant prod
| Variable | Description | Exemple attendu |
|---|---|---|
global.iobase_host | URL host:port (sans scheme, http:// ajouté) | iobase.terega.fr |
global.iobase_site | Identifiant du site d'installation | vandellans |
global.iobase_datasource | Datasource Indaba | transportation |
global.iobase_metrics_default | Tableau JSON des métriques cibles, en string brut | '["50001m_iot_pit002","50001m_iot_tt002"]' |
global.iobase_equipment_model | Marque/modèle balise | asystom_sentinel (déjà default) |
Une fois ces 5 globals set (via inject startup ou console Lua), aucune modification du canvas n'est nécessaire — la chaîne bascule automatiquement de mock vers prod.