Client de communication interprocessus (IPC) APIs - Intégrations gérées pour AWS IoT Device Management

Managed Integrations for AWS IoT Device Management est en version préliminaire et est susceptible de changer. Pour y accéder, contactez-nous depuis la console des intégrations gérées.

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Client de communication interprocessus (IPC) APIs

Les composants externes du hub d'intégrations gérées peuvent communiquer avec le SDK pour appareils finaux des intégrations gérées à l'aide de son composant agent et des communications interprocessus (IPC). Un exemple de composant externe du hub est un daemon (un processus d'arrière-plan exécuté en continu) qui gère les routines locales. Pendant la communication, le client IPC est le composant externe qui publie des commandes ou d'autres demandes, et qui s'abonne aux événements. Le serveur IPC est le composant agent du SDK pour appareils finaux des intégrations gérées. Pour plus d'informations, voir Configuration du client IPC.

Pour créer le client IPC, une bibliothèque cliente IPC IotmiLocalControllerClient est fournie. Cette bibliothèque permet, côté client APIs , de communiquer avec le serveur IPC dans l'Agent, notamment d'envoyer des demandes de commande, de demander l'état des appareils, de s'abonner à des événements (tels que l'événement d'état de l'appareil) et de gérer les interactions basées sur les événements.

Configuration du client IPC

La IotmiLocalControllerClient bibliothèque est une enveloppe d'IPC de base APIs, qui simplifie et rationalise le processus d'implémentation de l'IPC dans vos applications. Les sections suivantes décrivent APIs ce qu'il fournit.

Note

Cette rubrique concerne spécifiquement un composant externe en tant que client IPC et non les implémentations d'un serveur IPC.

  1. Création d'un client IPC

    Vous devez d'abord initialiser le client IPC avant de pouvoir l'utiliser pour traiter les demandes. Vous pouvez utiliser un constructeur dans la IotmiLocalControllerClient bibliothèque, qui prend le contexte de l'abonné char *subscriberCtx comme paramètre et crée un gestionnaire de clients IPC basé sur celui-ci. Voici un exemple de création d'un client IPC :

    // Context for subscriber char subscriberCtx[] = "example_ctx"; // Instantiate the client IotmiLocalControllerClient lcc(subscriberCtx);
  2. S'abonner à un événement

    Vous pouvez abonner le client IPC aux événements du serveur IPC de ciblage. Lorsque le serveur IPC publie un événement auquel le client est abonné, le client reçoit cet événement. Pour vous abonner, utilisez la registerSubscriber fonction et indiquez l'événement IDs auquel vous souhaitez vous abonner, ainsi que le rappel personnalisé.

    Voici une définition de la registerSubscriber fonction et un exemple de son utilisation :

    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);

    Le status est défini pour vérifier si l'opération (comme s'abonner ou envoyer une demande) est réussie. Si l'opération est réussie, le statut renvoyé estIOTMI_STATUS_OK (= 0).

    Note

    La bibliothèque IPC dispose des quotas de service suivants pour le nombre maximum d'abonnés et d'événements par abonnement :

    • Nombre maximum d'abonnés par processus : 5

      Défini comme IOTMI_IPC_MAX_SUBSCRIBER dans la bibliothèque IPC.

    • Nombre maximum d'événements définis : 32

      Défini comme IOTMI_IPC_EVENT_PUBLIC_END dans la bibliothèque IPC.

    • Chaque abonné dispose d'un champ d'événements de 32 bits, où chaque bit correspond à un événement défini.

  3. Connectez le client IPC au serveur

    La fonction de connexion de la IotmiLocalControllerClient bibliothèque effectue des tâches telles que l'initialisation du client IPC, l'enregistrement des abonnés et l'abonnement aux événements fournis dans la fonction. registerSubscriber Vous pouvez appeler la fonction de connexion sur le client IPC.

    status = lcc.connect();

    Vérifiez que le statut renvoyé est correct IOTMI_STATUS_OK avant d'envoyer des demandes ou d'effectuer d'autres opérations.

  4. Envoyer une demande de commande et une requête sur l'état de l'appareil

    Le serveur IPC de l'Agent peut traiter les demandes de commande et les demandes d'état de l'appareil.

    • Demande de commande

      Formez une chaîne de charge utile de demande de commande, puis appelez la sendCommandRequest fonction pour l'envoyer. Par exemple :

      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);

      Pour plus d'informations sur le format des demandes de commande, consultez la section Demandes de commande.

      Exemple fonction de rappel

      Le serveur IPC envoie d'abord un message d'accusé de réception Command received, will send command response back au client IPC. Après avoir reçu cet accusé de réception, le client IPC peut s'attendre à un événement de réponse de commande.

      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); }
    • Demande d'état de l'appareil

      De la même manière que la sendCommandRequest fonction, cette sendDeviceStateQuery fonction prend également une chaîne de charge utile, le rappel correspondant et le contexte du client.

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

Définitions et charges utiles de l'interface IPC

Cette section se concentre sur les interfaces IPC spécifiquement destinées à la communication entre l'agent et les composants externes, et fournit des exemples de mise en œuvre de l'IPC APIs entre ces deux composants. Dans les exemples suivants, le composant externe gère les routines locales.

Dans la IoTManagedIntegrationsDevice-IPC bibliothèque, les commandes et événements suivants sont définis pour la communication entre l'agent et le composant externe.

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;

Demande de commande

Format de demande de commande
  • Exemple demande de commande
    { "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 de réponse aux commandes
  • Si la demande de commande du composant externe est valide, l'agent l'envoie au CDMB (Common Data Model Bridge). La réponse de commande réelle qui contient l'heure d'exécution de la commande et d'autres informations n'est pas immédiatement renvoyée au composant externe, car le traitement des commandes prend du temps. Cette réponse de commande est une réponse instantanée de l'agent (comme un accusé de réception). La réponse indique au composant externe que les intégrations gérées ont reçu la commande et qu'il la traitera ou la supprimera s'il n'existe pas de jeton local valide. La réponse à la commande est envoyée sous forme de chaîne.

    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);

Demande d'état de l'appareil

Le composant externe envoie une demande d'état de l'appareil à l'agent. La demande fournit le managedThingId nom d'un appareil, puis l'agent répond en indiquant l'état de ce périphérique.

Format de demande d'état de l'appareil
  • La demande d'état de votre appareil doit porter le managedThingId nom de l'appareil demandé.

    { "payload": { "managedThingId": "testManagedThingId" } }
Format de réponse à l'état de l'appareil
  • Si la demande d'état de l'appareil est valide, l'agent renvoie l'état sous forme de chaîne.

    Exemple réponse à l'état de l'appareil pour une demande valide
    { "payload": { "currentState": "exampleState" } }

    Si la demande d'état de l'appareil n'est pas valide (par exemple, s'il n'existe pas de jeton valide, si la charge utile ne peut pas être traitée ou s'il existe un autre cas d'erreur), l'agent renvoie la réponse. La réponse inclut le code d'erreur et le message d'erreur.

    Exemple réponse à l'état de l'appareil pour une demande non valide
    { "payload": { "response":{ "code": 111, "message": "errorMessage" } } }

Réponse à la commande

Exemple format de réponse à la commande
{ "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":[ {} ] } ] }] } }

Événement de notification

Exemple format d'événement de notification
{ "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 } ] } ] }] } }