Neu: Die KI-Firewall überwacht jedes Modul und erklärt jeden Vorfall in einfachen Worten. So funktioniert es

Geräte- und Profil-API

REST-Routen für Geräte, Gerätezugangsdaten, Verbindungsdetails, das Gerätelog und Geräteprofile, mit Parametern, Antworten und Fehlern.

Diese Routen verwalten Geräte und Geräteprofile per Code. Die Pfade liegen unter https://<your host>/tenant/<tenantId>. Konventionen (Paginierung, strikte Bodies, Zeiten) stehen in REST API basics.

Geräte

MethodePfadBerechtigungFunktion
GET/api/iot/devicesiot_device.devices.readGeräte auflisten
POST/api/iot/devicesiot_device.devices.createGerät und dessen Zugriffstoken anlegen
GET/api/iot/devices/{deviceId}iot_device.devices.readEin Gerät abrufen
PATCH/api/iot/devices/{deviceId}iot_device.devices.updateName, Bezeichnung, Typ, Profil, Status, Zusatzinformationen ändern
DELETE/api/iot/devices/{deviceId}iot_device.devices.deleteGerät löschen
GET/api/iot/devices/{deviceId}/connectioniot_device.devices.readWo sich das Gerät verbindet
GET/api/iot/devices/{deviceId}/connectionsiot_device.devices.readDas Verbindungsprotokoll
GET/api/iot/devices/{deviceId}/logiot_device.devices.readVerbindungsprotokoll und Audit-Einträge, zusammengeführt

Geräte auflisten

GET /api/iot/devices (Seiten ab 1)

ParameterWerte
pageab 1 (Standard 1)
pageSize1 bis 100 (Standard 20)
searchbis zu 128 Zeichen: Name, Bezeichnung oder Seriennummer
deviceProfileIdeine Profil-ID
statusACTIVE, QUARANTINED oder DISABLED
isGatewaytrue oder false
onlinetrue, false oder unknown
sortname, connection, lastSeen, createdAt, mit :asc oder :desc
{
  "devices": [
    {
      "deviceId": "6f1c…",
      "name": "pump-station-04",
      "label": "Pump station 4",
      "type": "pump-controller",
      "serial": null,
      "deviceProfileId": "a1b2…",
      "status": "ACTIVE",
      "isGateway": false,
      "gatewayDeviceId": null,
      "model": null,
      "fwTitle": null,
      "fwVersion": null,
      "online": true,
      "active": true,
      "lastConnectAt": "2026-11-08T06:12:03.000Z",
      "lastDisconnectAt": null,
      "lastActivityAt": "2026-11-09T09:41:10.000Z",
      "lastRemoteIp": "203.0.113.20",
      "lastTransport": "mqtts",
      "additionalInfo": {},
      "createdAt": "2026-10-01T08:00:00.000Z",
      "updatedAt": "2026-11-08T06:12:03.000Z"
    }
  ],
  "total": 1
}

online ist null bei einem Profil, dessen Online-Regel Nur zuletzt gesehen ist. GET /api/iot/devices/{deviceId} antwortet mit { "device": {...} } mit denselben Feldern plus profileName und profileTransport.

Gerät anlegen

POST/tenant/{tenantId}/api/iot/devices

Felder: name (Pflicht, 1 bis 128 Zeichen, eindeutig), label (bis 255), type (bis 64), deviceProfileId (sonst das Standardprofil), isGateway, additionalInfo (ein Objekt mit bis zu 50 Schlüsseln und 8 KiB). Die Antwort enthält das Gerät und bei Profilen, deren Geräte sich selbst anmelden, ein Zugriffstoken in credential.secret.token. Das Token wird nur in dieser Antwort angezeigt.

Request-Body application/json

{
    "name": "pump-station-04",
    "label": "Pump station 4",
    "deviceProfileId": "a1b2…"
}

Beispiel curl

curl -X POST 'https://<your-host>/tenant/{tenantId}/api/iot/devices' \
  -H 'Content-Type: application/json' \
  -d '{"name":"pump-station-04","label":"Pump station 4","deviceProfileId":"a1b2…"}'

Antworten

201Erstellt
{
    "device": {
        "deviceId": "6f1c…",
        "name": "pump-station-04",
        "status": "ACTIVE",
        "…": "…"
    },
    "credential": {
        "credential": {
            "credentialId": "…",
            "type": "ACCESS_TOKEN",
            "…": "…"
        },
        "secret": {
            "token": "Xq3…"
        }
    }
}
403Verboten
{
    "message": "The device limit of this account is reached.",
    "code": "FORBIDDEN",
    "details": {
        "key": "max_devices",
        "limit": 43,
        "current": 43,
        "adding": 1
    }
}
409Konflikt
{
    "message": "A device with this name already exists.",
    "code": "CONFLICT",
    "details": {
        "reason": "name_taken"
    }
}

Gerät ändern

PATCH /api/iot/devices/{deviceId} akzeptiert beliebige der Felder name, label, type, deviceProfileId, isGateway, additionalInfo, status (ACTIVE oder DISABLED). Nur geänderte Werte senden. Ein unter Quarantäne stehendes Gerät wird über die Bereitstellung freigegeben, nicht hier: „Ein unter Quarantäne stehendes Gerät wird über die Bereitstellung aktiviert, nicht hier bearbeitet.“ Ein neuer Name, ein neues Profil oder das Deaktivieren beendet die aktive Sitzung des Geräts; es verbindet sich mit den neuen Einstellungen erneut.

Gerät löschen

DELETE antwortet mit { "message": "Device deleted." }. Die Messwerte des Geräts werden im Hintergrund entfernt. Ein Gerät, das noch verwendet wird, wird mit 409 abgelehnt, zum Beispiel: „The device is still in use by 1 asset placement or relation (iot_asset).“ Entfernen Sie es zuvor von seinem Asset und löschen Sie seine Relationen: siehe Placing devices und Relations.

Verbindungsdetails

GET /api/iot/devices/{deviceId}/connection gibt nichts Geheimes zurück:

{
  "connection": {
    "mqtt": { "host": "mqtt.example.com", "port": 8883, "tls": true },
    "httpBase": "https://acme.example.com",
    "topics": { "telemetry": "v1/telemetry", "attributes": "v1/attributes", "rpcRequest": "v1/rpc/req/+", "rpcResponse": "v1/rpc/res/{id}" },
    "telemetryKeys": [{ "key": "temperature", "type": "number" }]
  }
}

mqtt ist null, wenn das Profil MQTT an diesem Listener ablehnt; rpcRequest und rpcResponse sind null beim Schema Legacy compatible.

Protokolle

  • GET .../connections?page=1&pageSize=50: Verbindungsaufbau und -abbau, neueste zuerst (Seiten ab 1, pageSize bis 100).
  • GET .../log?page=1&pageSize=50&source=connection|audit: das Verbindungsprotokoll und die Audit-Einträge des Geräts, zusammengeführt, neueste zuerst. page × pageSize darf höchstens 1.000 ergeben.

Gerätezugangsdaten

MethodePfadFunktion
GET/api/iot/devices/{deviceId}/credentialsDie aktiven Zugangsdaten, ohne deren Geheimnis
PUT/api/iot/devices/{deviceId}/credentialsAuf andere Zugangsdaten wechseln
POST/api/iot/devices/{deviceId}/credentials/rotateEin neues Geheimnis desselben Typs (201)
DELETE/api/iot/devices/{deviceId}/credentialsZugangsdaten widerrufen

Alle benötigen iot_device.credentials.manage. Wechsel, Rotation und Widerruf beenden die alten Zugangsdaten sofort (es gibt kein Übergangsfenster) und trennen das Gerät.

PUT-Bodies:

{ "type": "ACCESS_TOKEN" }
{ "type": "MQTT_BASIC", "username": "pump04", "clientId": "pump04", "password": null }
{ "type": "X509_CERTIFICATE", "certificateId": "…" }

Bei MQTT_BASIC lassen Sie password weg (oder setzen null), um ein generiertes Passwort zu erhalten. Ein gewähltes Passwort braucht mindestens 16 Zeichen, Vielfalt und darf den Benutzernamen oder die Client-ID nicht enthalten. Der Benutzername provision ist reserviert. Die Antwort ist { "credential": {...}, "secret": { "token": "…" } } oder { ..., "secret": { "password": "…" } }, nur einmal angezeigt; ein X.509-Zertifikat hat kein Geheimnis. Ein X.509-Zugang wird rotiert, indem ein neues Zertifikat angehängt wird: „Ein X.509-Zugang wird durch Anhängen eines neuen Zertifikats rotiert.“ Siehe Device credentials.

Geräteprofile

MethodePfadBerechtigungFunktion
GET/api/iot/device-profilesiot_device_profile.profiles.readAuflisten (page ab 1, pageSize, search, transportType, onlineRule, sort)
POST/api/iot/device-profilesiot_device_profile.profiles.writeAnlegen
GET/api/iot/device-profiles/{profileId}.profiles.readLesen
PATCH/api/iot/device-profiles/{profileId}.profiles.writeÄndern; expectedVersion senden
DELETE/api/iot/device-profiles/{profileId}.profiles.writeLöschen
POST/api/iot/device-profiles/{profileId}/default.profiles.writeAls Standard festlegen
POST/api/iot/device-profiles/{profileId}/duplicate.profiles.writeKopieren als „ (Kopie)“
GET/api/iot/device-profiles/{profileId}/key-usage?keys=a,b.profiles.readWer liest diese Schlüssel (Regeln, Boards, Flows)
GET, PUT, POST/api/iot/device-profiles/{profileId}/provisioningiot_device_profile.provisioning.manageBereitstellungseinstellungen; POST rotiert oder widerruft einen Bereitstellungsschlüssel

Sortierfelder: name, transport, online, updated. Eine Liste antwortet mit { "profiles": [...], "total": n }; ein Profil mit { "profile": {...} }.

Ein Profil anlegen

Ein neues Profil braucht einen name (bis 128 Zeichen) und eine onlineRule: LIVE_SOCKET (Live-Verbindung), UPLINK_WINDOW (Letzte Nachricht, braucht zusätzlich expectedIntervalS, 60 bis 604.800) oder LAST_SEEN_ONLY (Nur zuletzt gesehen). Jedes andere Feld erhält seinen Standardwert.

{
  "name": "Cold room sensor",
  "onlineRule": "UPLINK_WINDOW",
  "expectedIntervalS": 300,
  "transportType": "MQTT",
  "telemetrySchema": [
    { "key": "temperature", "type": "number", "unit": "°C", "label": "Temperature", "min": -30, "max": 10, "decimals": 1 }
  ]
}

Ausgewählte Felder und ihre Bereiche:

FeldBereich
transportTypeMQTT, HTTP, ANY oder ein registriertes Protokoll
allowedAuthModes1 bis 3 aus ACCESS_TOKEN, MQTT_BASIC, X509_CERTIFICATE
mqttTransportTLS_REQUIRED (Standard) oder PLAINTEXT_ALLOWED
allowedNetworksbis zu 64 Netze oder Adressen
payloadMaxBytes1.024 bis 65.536
downlinkMaxBytes1.024 bis 65.536
inactivityTimeoutSec10 bis 604.800
maxGatewayChildren0 bis 10.000
rpcTimeoutDefaultSec1 bis 300
onlineWindowFactor1,5 bis 10, eine Nachkommastelle
telemetrySchema, cfgSchemajeweils bis zu 500 Schlüssel
rateLimitscount:seconds[,count:seconds] pro Familie, zum Beispiel "telemetry_msgs": "10:1,300:60"

Lesen Sie zuerst ein bestehendes Profil, um jedes Feld mit seinem aktuellen Wert zu sehen; der Profil-Editor deckt dieselben Felder mit Erläuterungen ab, siehe Geräteprofile.

Ablehnungen

Ein Body, der eine Feldregel verletzt, ergibt ein 400 mit den Problemen in issues, jeweils mit path und message, zum Beispiel online_rule_required (ein neues Profil benötigt eine Online-Regel), expected_interval_required (Letzte Nachricht benötigt expectedIntervalS) oder online_rule_not_allowed (die Online-Regel passt nicht zum Transport).

Andere Ablehnungen enthalten details.reason, zum Beispiel:

GrundBedeutung
stale_profileJemand hat das Profil gespeichert, seit Sie es gelesen haben (409)
name_takenEin anderes Profil hat diesen Namen
default_profileDas Standardprofil kann nicht gelöscht werden
builtin_profileEin eingebautes Profil kann auf diesem Weg nicht geändert werden
still_referencedGeräte oder andere Datensätze verwenden das Profil noch
reference_unverifiableEin Modul, das das Profil verwenden könnte, konnte nicht abgefragt werden; versuchen Sie es erneut