Client für Interprozesskommunikation (IPC) APIs - Verwaltete Integrationen für AWS IoT Device Management

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Client für Interprozesskommunikation (IPC) APIs

Externe Komponenten auf dem Managed Integrations Hub können über dessen Agent-Komponente und Interprozesskommunikation (IPC) mit dem Managed Integrations Hub SDK kommunizieren. Eine externe Komponente auf dem Hub ist beispielsweise ein Daemon (ein kontinuierlich laufender Hintergrundprozess), der lokale Routinen verwaltet. Während der Kommunikation ist der IPC-Client die externe Komponente, die Befehle oder andere Anfragen veröffentlicht und Ereignisse abonniert. Der IPC-Server ist die Agentenkomponente im Hub-SDK für verwaltete Integrationen. Weitere Informationen finden Sie unter IPC-Client einrichten.

Um den IPC-Client zu erstellen, wird eine IPC-Client-Bibliothek IotmiLocalControllerClient bereitgestellt. Diese Bibliothek ermöglicht die clientseitige APIs Kommunikation mit dem IPC-Server in Agent, einschließlich des Sendens von Befehlsanfragen, der Abfrage von Gerätestatus, des Abonnierens von Ereignissen (wie dem Gerätestatusereignis) und der Verarbeitung ereignisbasierter Interaktionen.

Den IPC-Client einrichten

Die IotmiLocalControllerClient Bibliothek bietet grundlegende IPC-Funktionen APIs, die den Prozess der Implementierung von IPC in Ihren Anwendungen vereinfachen und optimieren. In den folgenden Abschnitten wird beschrieben, was sie bietet. APIs

Anmerkung

Dieses Thema bezieht sich speziell auf eine externe Komponente wie einen IPC-Client und nicht auf die Implementierungen eines IPC-Servers.

  1. Erstellen Sie einen IPC-Client

    Sie müssen zuerst den IPC-Client initialisieren, bevor er zur Bearbeitung von Anfragen verwendet werden kann. Sie können einen Konstruktor in der IotmiLocalControllerClient Bibliothek verwenden, der den Abonnentenkontext char *subscriberCtx als Parameter verwendet und auf dieser Grundlage einen IPC-Client-Manager erstellt. Im Folgenden finden Sie ein Beispiel für die Erstellung eines IPC-Clients:

    // Context for subscriber char subscriberCtx[] = "example_ctx"; // Instantiate the client IotmiLocalControllerClient lcc(subscriberCtx);
  2. Abonnieren Sie eine Veranstaltung

    Sie können den IPC-Client für Ereignisse des Ziel-IPC-Servers abonnieren. Wenn der IPC-Server ein Ereignis veröffentlicht, das der Client abonniert hat, empfängt der Client dieses Ereignis. Verwenden Sie zum Abonnieren die registerSubscriber Funktion und geben Sie das Ereignis, das Sie abonnieren IDs möchten, sowie den benutzerdefinierten Rückruf an.

    Im Folgenden finden Sie eine Definition der registerSubscriber Funktion und ihre Beispielverwendung:

    iotmi_statusCode_t registerSubscriber( std::vector<iotmiIpc_eventId_t> eventIds, SubscribeCallbackFunction cb);
    // A basic example of customized subscribe callback, which prints the event ID, data, and length received void customizedSubscribeCallback(iotmiIpc_eventId_t event_id, uint32_t length, const uint8_t *data, void *ctx) { IOTMI_IPC_LOGI("Received subscribed event id: %d\n" "length: %d\n" "data: %s\n", event_id, length, data); } iotmi_statusCode_t status; status = lcc.registerSubscriber({IOTMI_IPC_EVENT_DEVICE_UPDATE_TO_RE}, customerProvidedSubscribeCallback);

    Die status ist so definiert, dass überprüft wird, ob der Vorgang (wie Abonnieren oder Anfrage senden) erfolgreich ist. Wenn der Vorgang erfolgreich ist, lautet der zurückgegebene StatusIOTMI_STATUS_OK (= 0).

    Anmerkung

    Die IPC-Bibliothek hat die folgenden Dienstkontingente für die maximale Anzahl von Abonnenten und Ereignissen in einem Abonnement:

    • Maximale Anzahl von Abonnenten pro Prozess: 5

      Definiert wie IOTMI_IPC_MAX_SUBSCRIBER in der IPC-Bibliothek.

    • Maximale Anzahl definierter Ereignisse: 32

      Definiert wie IOTMI_IPC_EVENT_PUBLIC_END in der IPC-Bibliothek.

    • Jeder Abonnent hat ein 32-Bit-Ereignisfeld, in dem jedes Bit einem definierten Ereignis entspricht.

  3. Connect den IPC-Client mit dem Server

    Die Connect-Funktion in der IotmiLocalControllerClient Bibliothek erledigt Aufgaben wie das Initialisieren des IPC-Clients, das Registrieren von Abonnenten und das Abonnieren von Ereignissen, die in der Funktion bereitgestellt wurden. registerSubscriber Sie können die Connect-Funktion auf dem IPC-Client aufrufen.

    status = lcc.connect();

    Vergewissern Sie sich, dass der zurückgegebene Status lautet, IOTMI_STATUS_OK bevor Sie Anfragen senden oder andere Operationen ausführen.

  4. Befehlsanfrage und Gerätestatusabfrage senden

    Der IPC-Server in Agent kann Befehlsanforderungen und Gerätestatusanfragen verarbeiten.

    • Befehlsanfrage

      Bilden Sie eine Payload-Zeichenfolge für die Befehlsanforderung und rufen Sie dann die sendCommandRequest Funktion auf, um sie zu senden. Zum Beispiel:

      status = lcc.sendCommandRequest(payloadData, iotmiIpcMgr_commandRequestCb, nullptr);
      /** * @brief method to send local control command * @param payloadString A pre-defined data format for local command request. * @param callback a callback function with typedef as PublishCallbackFunction * @param client_ctx client provided context * @return */ iotmi_statusCode_t sendCommandRequest(std::string payloadString, PublishCallbackFunction callback, void *client_ctx);

      Weitere Informationen zum Format der Befehlsanforderung finden Sie unter Befehlsanforderungen.

      Beispiel Rückruffunktion

      Der IPC-Server sendet zunächst eine Nachrichtenbestätigung Command received, will send command response back an den IPC-Client. Nach Erhalt dieser Bestätigung kann der IPC-Client ein Befehlsantwort-Ereignis erwarten.

      void iotmiIpcMgr_commandRequestCb(iotmi_statusCode_t ret_status, void *ret_data, void *ret_client_ctx) { char* data = NULL; char *ctx = NULL; if (ret_status != IOTMI_STATUS_OK) return; if (ret_data == NULL) { IOTMI_IPC_LOGE("error, event data NULL"); return; } if (ret_client_ctx == NULL) { IOTMI_IPC_LOGE("error, event client ctx NULL"); return; } data = (char *)ret_data; ctx = (char *)ret_client_ctx; IOTMI_IPC_LOGI("response received: %s \n", data); }
    • Anfrage zum Gerätestatus

      Ähnlich wie die sendCommandRequest Funktion benötigt auch diese sendDeviceStateQuery Funktion eine Payload-Zeichenfolge, den entsprechenden Callback und den Client-Kontext.

      status = lcc.sendDeviceStateQuery(payloadData, iotmiIpcMgr_deviceStateQueryCb, nullptr);

Definitionen und Payloads der IPC-Schnittstelle

Dieser Abschnitt konzentriert sich auf IPC-Schnittstellen speziell für die Kommunikation zwischen dem Agenten und externen Komponenten und enthält Beispielimplementierungen von IPC APIs zwischen diesen beiden Komponenten. In den folgenden Beispielen verwaltet die externe Komponente lokale Routinen.

In der IoTManagedIntegrationsDevice-IPC Bibliothek sind die folgenden Befehle und Ereignisse für die Kommunikation zwischen dem Agenten und der externen Komponente definiert.

typedef enum { // The async cmd used to send commands from the external component to Agent IOTMI_IPC_SVC_SEND_REQ_FROM_RE = 32, // The async cmd used to send device state query from the external component to Agent IOTMI_IPC_SVC_SEND_QUERY_FROM_RE = 33, // ... } iotmiIpcSvc_cmd_t;
typedef enum { // Event about device state update from Agent to the component IOTMI_IPC_EVENT_DEVICE_UPDATE_TO_RE = 3, // ... } iotmiIpc_eventId_t;

Befehlsanforderung

Format der Befehlsanforderung
  • Beispiel Befehlsanforderung
    { "payload": { "traceId": "LIGHT_DIMMING_UPDATE", "nodeId": "1", "managedThingId": <ManagedThingId of the device>, "endpoints": [{ "id": "1", "capabilities": [ { "id": "matter.LevelControl@1.4", "name": "Level Control", "version": "1.0", "actions":[ { "name": "UpdateState", "parameters": { "OnLevel": 5, "DefaultMoveRate": 30 } } ] } ] }] } }
Format der Befehlsantwort
  • Wenn die Befehlsanforderung der externen Komponente gültig ist, sendet der Agent sie an die CDMB (Common Data Model Bridge). Die eigentliche Befehlsantwort, die die Ausführungszeit des Befehls und andere Informationen enthält, wird nicht sofort an die externe Komponente zurückgesendet, da die Verarbeitung von Befehlen einige Zeit in Anspruch nimmt. Bei dieser Befehlsantwort handelt es sich um eine sofortige Antwort des Agenten (wie eine Bestätigung). Die Antwort teilt der externen Komponente mit, dass verwaltete Integrationen den Befehl erhalten haben. Falls kein gültiges lokales Token vorhanden ist, wird er entweder verarbeitet oder verworfen. Die Befehlsantwort wird in einem Zeichenkettenformat gesendet.

    std::string errorResponse = "No valid token for local command, cannot process."; *ret_buf_len = static_cast<uint32_t>(errorResponse.size()); *ret_buf = new uint8_t[*ret_buf_len]; std::memcpy(*ret_buf, errorResponse.data(), *ret_buf_len);

Anfrage zum Gerätestatus

Die externe Komponente sendet eine Anfrage zum Gerätestatus an den Agenten. Die Anfrage gibt den Status managedThingId eines Geräts an, und der Agent antwortet dann mit dem Status dieses Geräts.

Format der Anforderung zum Gerätestatus
  • Ihre Gerätestatusanfrage muss das managedThingId des abgefragten Geräts haben.

    { "payload": { "managedThingId": "testManagedThingId" } }
Antwortformat für den Gerätestatus
  • Wenn die Gerätestatusanfrage gültig ist, sendet der Agent den Status im Zeichenkettenformat zurück.

    Beispiel Antwort auf den Gerätestatus bei einer gültigen Anfrage
    { "payload": { "currentState": "exampleState" } }

    Wenn die Gerätestatusanfrage nicht gültig ist (z. B. wenn kein gültiges Token vorhanden ist, die Payload nicht verarbeitet werden kann oder ein anderer Fehlerfall vorliegt), sendet der Agent die Antwort zurück. Die Antwort enthält den Fehlercode und die Fehlermeldung.

    Beispiel Antwort auf den Gerätestatus auf eine ungültige Anfrage
    { "payload": { "response":{ "code": 111, "message": "errorMessage" } } }

Antwort auf den Befehl

Beispiel Format der Befehlsantwort
{ "payload": { "traceId": "LIGHT_DIMMING_UPDATE", "commandReceivedAt": "1684911358.533", "commandExecutedAt": "1684911360.123", "managedThingId": <ManagedThingId of the device>, "nodeId": "1", "endpoints": [{ "id": "1", "capabilities": [ { "id": "matter.OnOff@1.4", "name": "On/Off", "version": "1.0", "actions":[ {} ] } ] }] } }

Benachrichtigungsereignis

Beispiel Format des Benachrichtigungsereignisses
{ "payload": { "hasState": "true" "nodeId": "1", "managedThingId": <ManagedThingId of the device>, "endpoints": [{ "id": "1", "capabilities": [ { "id": "matter.OnOff@1.4", "name": "On/Off", "version": "1.0", "properties":[ { "name": "OnOff", "value": true } ] } ] }] } }