Nouveau : le pare-feu IA surveille chaque module et explique chaque incident en termes simples. Découvrez comment ça marche

API de micrologiciel et de réglages des appareils

Déployez des micrologiciels signés, affectez-les, lancez et pilotez les déploiements par vagues, et lisez comme modifiez les réglages des appareils sous licence via REST : routes, corps de requête et erreurs.

Cette page couvre deux familles de routes : les mises à jour du firmware (OTA) et les réglages à distance des appareils. Leur fonctionnement pour les utilisateurs est décrit dans Mises à jour du firmware (OTA), Vagues de déploiement du firmware et Réglages à distance des appareils. Les chemins sont sous https://<your host>/tenant/<tenantId>.

Routes du firmware

MéthodeCheminPermissionAction
GET/api/iot/ota/packagesiot_ota.readLister les paquets (status, title)
POST/api/iot/ota/packagesiot_ota.packages.manageTéléverser un paquet (multipart)
GET/api/iot/ota/packages/{packageId}iot_ota.readUn paquet avec ses compteurs de mises à jour
PATCH/api/iot/ota/packages/{packageId}iot_ota.packages.manageNotes de version, ou statut DEPRECATED, READY à nouveau, REVOKED
DELETE/api/iot/ota/packages/{packageId}iot_ota.packages.manageSupprimer un paquet inutilisé
GET, POST/api/iot/ota/assignmentslecture : iot_ota.read ; affectation : iot_ota.assignLister ou créer des affectations
DELETE/api/iot/ota/assignments/{assignmentId}iot_ota.assignRetirer une affectation
GET/api/iot/ota/rolloutsiot_ota.readDéploiements par vagues (packageId, status)
GET, POST/api/iot/ota/rollouts/{rolloutId}lecture ; iot_ota.assignLecture ; { "action": "pause" \| "resume" \| "abort" }
GET/api/iot/ota/statesiot_ota.readTentatives de mise à jour (packageId, state, limit jusqu’à 500)
GET, POST/api/iot/ota/devices/{deviceId}lecture ; iot_ota.assignMise à jour d’un appareil ; { "action": "retry" }
GET, PUT/api/iot/ota/settings/{profile\|device}/{id}lecture ; iot_ota.assignRéglages OTA d’un profil, ou exception de liaison limitée d’un appareil
GET, POST/api/iot/ota/signing-keyslecture ; iot_ota.keys.manageLister ou ajouter des clés publiques de signature
DELETE/api/iot/ota/signing-keys/{keyId}iot_ota.keys.manageRévoquer une clé

L’ajout et la révocation des clés de signature sont réservés au propriétaire, une clé API ne peut donc pas les effectuer.

Téléverser un paquet

POST /api/iot/ota/packages accepte multipart/form-data avec deux parties : file (l’image) et meta (texte JSON). La somme de contrôle est vérifiée avant tout stockage, et la signature est vérifiée par rapport à vos clés enregistrées.

curl -s -X POST "https://$HOST/tenant/$TENANT/api/iot/ota/packages" \
  -H "Authorization: Bearer $HERMETRY_KEY" \
  -F "file=@router-fw-2.5.0.bin" \
  -F 'meta={"title":"router-fw","version":"2.5.0","checksum":"<sha256 of the file>","signatureScheme":"usign-ed25519","signature":"<text of the .sig file>","profileId":"a1b2…","releaseNotes":"Fixes LTE reconnect."}'
Champ metaRègles
title1 à 128 ; lettres, chiffres, ., _, +, -
version1 à 64 ; lettres, chiffres, ., _, +, ~, -
checksumSHA-256 du fichier, 64 caractères hexadécimaux
signatureSchemeusign-ed25519 (une signature détachée dans signature), le schéma de démarrage sécurisé de la famille d’appareils visée par le paquet, ou none (uniquement si le profil autorise les images non signées)
typeFIRMWARE ou SOFTWARE
profileId, hardwareModels (jusqu’à 50), minFromVersionAppareils concernés
releaseNotesjusqu’à 4 000 caractères

La taille maximale par défaut est de 64 MiB. La réponse est 201 { "package": {...} }.

RefusMessage
400 file_missingJoignez le fichier du firmware.
413 too_largeLe paquet dépasse la taille autorisée.
413 quotaEspace de stockage insuffisant pour ce paquet.
422 checksum_mismatchLe SHA-256 du fichier téléversé ne correspond pas à celui fourni.
422La signature de l’image ne se vérifie pas avec une clé enregistrée.
409 package_existsUn paquet avec ce titre et cette version existe déjà.

Affecter et déployer

POST/tenant/{tenantId}/api/iot/ota/assignments

Affecter un paquet READY à un PROFILE ou à un DEVICE (dans targetId) ou à un GROUP (deviceIds, jusqu’à 5 000, ou selector.profileId, figés immédiatement). dryRun: true renvoie les comptages sans rien écrire. waves (1 à 20) déploie un profil ou un groupe par vagues ; un appareil seul n’est jamais déployé par vagues.

Corps de la requête application/json

{
    "packageId": "f00d…",
    "targetType": "PROFILE",
    "targetId": "a1b2…",
    "waves": [
        {
            "size": {
                "percent": 5
            },
            "soakMin": 60,
            "minSuccessPct": 95,
            "maxFailurePct": 2,
            "maxDurationMin": 1440
        },
        {
            "size": {
                "percent": 100
            },
            "soakMin": 0,
            "minSuccessPct": 95,
            "maxFailurePct": 2,
            "maxDurationMin": 2880
        }
    ]
}

Exemple curl

curl -X POST 'https://<your-host>/tenant/{tenantId}/api/iot/ota/assignments' \
  -H 'Content-Type: application/json' \
  -d '{"packageId":"f00d…","targetType":"PROFILE","targetId":"a1b2…","waves":[{"size":{"percent":5},"soakMin":60,"minSuccessPct":95,"maxFailurePct":2,"maxDurationMin":1440},{"size":{"percent":100},"soakMin":0,"minSuccessPct":95,"maxFailurePct":2,"maxDurationMin":2880}]}'

Réponses

201Créé
{
    "assignment": {
        "…": "…"
    },
    "preview": {
        "…": "…"
    },
    "result": {
        "…": "…"
    }
}
200OK
{
    "assignment": null,
    "preview": {
        "…": "…"
    }
}
409Conflit
{
    "message": "Only a ready package can be assigned.",
    "code": "CONFLICT"
}

La size d’une vague est { "percent": 0–100 } ou { "count": 1–100000 } ; la dernière vague prend le reste. soakMin de 0 à 10 080, minSuccessPct et maxFailurePct de 0 à 100, maxFailures facultatif, maxDurationMin de 5 à 43 200.

Statuts de déploiement : RUNNING, PAUSED, COMPLETED, ABORTED. Un contrôle échoué met le déploiement en pause ; resume le reprend, abort le termine.

Statuts de mise à jour

La mise à jour d’un appareil passe par QUEUED, INITIATED, WAITING, DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING et se termine par UPDATED, FAILED, TIMEOUT, ROLLED_BACK, SKIPPED ou CANCELLED. Seuls FAILED, TIMEOUT et ROLLED_BACK peuvent être relancés ({ "action": "retry" }), jusqu’à la limite de tentatives.

Réglages OTA

PUT /api/iot/ota/settings/profile/{profileId} accepte otaEnabled, allowMetered, allowUnsigned, downloadTimeoutMin (5 à 1 440), updateTimeoutMin (2 à 240), maxAttempts (1 à 10) ; null rétablit la valeur par défaut. Pour un appareil (/settings/device/{deviceId}), seul allowMetered est accepté : « Un appareil ne prend que le réglage de liaison limitée. »

Événements webhook : ota.update.* et ota.rollout.*, voir la Référence des événements webhook.

Routes des réglages d’appareil

Les réglages à distance concernent les appareils sous licence dont le modèle publie un manifeste de réglages.

MéthodeCheminPermissionAction
GET/api/iot/devices/{deviceId}/settingsiot_device_settings.readToutes les sections : valeurs souhaitées et remontées, état, dérive
GET/api/iot/devices/{deviceId}/settings/schema.readLe manifeste du modèle et du firmware de l’appareil
GET/api/iot/devices/{deviceId}/settings/history.readModifications passées (section, page à partir de 0, sort=at:desc)
GET/api/iot/devices/{deviceId}/settings/{section}.readUne section ; ETag correspond à sa révision
PUT/api/iot/devices/{deviceId}/settings/{section}.operate et les classes modifiéesRemplacer une section : { values, confirm? }
PATCH/api/iot/devices/{deviceId}/settings/{section}.operate et les classes modifiéesPatch de fusion : { patch, confirm? }
POST/api/iot/devices/{deviceId}/settings/{section}/reapply.operateRenvoyer la section souhaitée
GET/api/iot/device-settings/models, /model-schema?model=.readVos modèles et les sections d’un modèle
GET, POST/api/iot/device-settings/baselines.read ; .baselines.manageLister ou créer des lignes de base
GET, PUT, DELETE/api/iot/device-settings/baselines/{baselineId}.read; .baselines.manageLire, remplacer, supprimer
GET, POST/api/iot/device-settings/jobs.read; .jobs.manageLister ou lancer des tâches en masse
GET/api/iot/device-settings/jobs/{jobId}, .../targets.readUne tâche, ses vagues et ses appareils
POST/api/iot/device-settings/jobs/{jobId}/pause, /resume, /cancel.jobs.managePiloter une tâche

Ce qu’une écriture peut modifier dépend de la classe de chaque réglage modifié : les réglages de fonctionnement exigent iot_device_settings.operate, les réglages de configuration iot_device_settings.write, les réglages dangereux iot_device_settings.dangerous.write (propriétaire uniquement, jamais une clé d’API) et "confirm": true.

Modifier une section

GET  /api/iot/devices/{deviceId}/settings/network        → ETag: "7"
PATCH /api/iot/devices/{deviceId}/settings/network
If-Match: "7"
{ "patch": { "lte": { "apn": "iot.example" } } }
  • If-Match est obligatoire : sans lui, 428 « If-Match is required: send the rev you read. »
  • Une section modifiée depuis votre lecture : 412 « The section changed since it was read; read it again. » (rev_mismatch).
  • ?dryRun=true valide et liste ce qui serait modifié, sans rien enregistrer.
  • Un merge patch fusionne les objets, supprime avec null et remplace les listes entières.
  • Les écritures sont limitées à 600 par organisation et par minute.
  • Les secrets ne sont jamais renvoyés : un réglage secret se lit comme { "set": true }.

Un appareil qui ne prend pas les réglages par section répond 409 « This device does not take settings by section. » ; un appareil dont le manifeste n’est pas encore dans le catalogue, « The settings manifest of this device’s model and firmware is not in the catalog yet. »

Tâches en masse

POST /api/iot/device-settings/jobs avec l’en-tête Idempotency-Key : name (80 caractères au maximum), baselineId ou sections, selector (deviceIds, profileId ou models), waves facultatif ({ "percent": [1, 10, 100] } ou { "count": [...] }, jusqu’à 10), gates (minApplied, maxReverted sous forme de fractions de 0 à 1), onConflict (queue ou skip), offlineExpiryDays (1 à 90), waveTimeoutMin (1 à 1 440), confirm. Un Idempotency-Key répété renvoie la première tâche (200). ?dryRun=true renvoie le plan. Refus : 409 too_many_jobs ; 422 confirm_required, invalid_sections, no_devices, too_many_devices ; 403 class_forbidden.