Cliente de comunicación entre procesos (IPC) APIs - Integraciones gestionadas para AWS IoT Device Management

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Cliente de comunicación entre procesos (IPC) APIs

Los componentes externos del centro de integraciones gestionadas pueden comunicarse con el SDK del centro de integraciones gestionadas mediante su componente de agente y las comunicaciones entre procesos (IPC). Un ejemplo de componente externo del hub es un daemon (un proceso en segundo plano que se ejecuta de forma continua) que administra las rutinas locales. Durante la comunicación, el cliente IPC es el componente externo que publica comandos u otras solicitudes y se suscribe a los eventos. El servidor IPC es el componente del agente del SDK de Hub para integraciones gestionadas. Para obtener más información, consulte Configuración del cliente IPC.

Para crear el cliente IPC, se proporciona una biblioteca IotmiLocalControllerClient de clientes IPC. Esta biblioteca permite comunicarse desde el lado del cliente APIs con el servidor de IPC en Agent, lo que incluye enviar solicitudes de comandos, consultar los estados de los dispositivos, suscribirse a eventos (como el evento del estado del dispositivo) y gestionar las interacciones basadas en eventos.

Configuración del cliente IPC

La IotmiLocalControllerClient biblioteca es un compendio de la IPC básica APIs, que simplifica y agiliza el proceso de implementación de la IPC en sus aplicaciones. En las siguientes secciones se describe lo que proporciona. APIs

nota

Este tema está dedicado específicamente a un componente externo como un cliente de IPC y no a las implementaciones de un servidor de IPC.

  1. Cree un cliente IPC

    Primero debe inicializar el cliente IPC antes de que pueda usarse para procesar las solicitudes. Puede usar un constructor en la IotmiLocalControllerClient biblioteca, que toma el contexto del suscriptor char *subscriberCtx como parámetro y crea un administrador de clientes de IPC basado en él. A continuación se muestra un ejemplo de creación de un cliente IPC:

    // Context for subscriber char subscriberCtx[] = "example_ctx"; // Instantiate the client IotmiLocalControllerClient lcc(subscriberCtx);
  2. Suscríbase a un evento

    Puede suscribir el cliente de IPC a los eventos del servidor de IPC de destino. Cuando el servidor IPC publique un evento al que esté suscrito el cliente, el cliente recibirá ese evento. Para suscribirse, utilice la registerSubscriber función y proporcione el evento IDs al que desea suscribirse, así como la devolución de llamada personalizada.

    A continuación se muestra una definición de la registerSubscriber función y un ejemplo de su uso:

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

    statusSe define para comprobar si la operación (como suscribirse o enviar una solicitud) se ha realizado correctamente. Si la operación se realiza correctamente, el estado devuelto esIOTMI_STATUS_OK (= 0).

    nota

    La biblioteca de IPC tiene las siguientes cuotas de servicio para el número máximo de suscriptores y eventos de una suscripción:

    • Número máximo de suscriptores por proceso: 5

      Definido como IOTMI_IPC_MAX_SUBSCRIBER en la biblioteca IPC.

    • Número máximo de eventos definidos: 32

      Definido como IOTMI_IPC_EVENT_PUBLIC_END en la biblioteca de IPC.

    • Cada suscriptor tiene un campo de eventos de 32 bits, donde cada bit corresponde a un evento definido.

  3. Conecte el cliente IPC al servidor

    La función de conexión de la IotmiLocalControllerClient biblioteca realiza tareas como inicializar el cliente IPC, registrar los suscriptores y suscribirse a los eventos que se proporcionaron en la función. registerSubscriber Puede llamar a la función de conexión en el cliente IPC.

    status = lcc.connect();

    Confirme que el estado devuelto es IOTMI_STATUS_OK antes de enviar solicitudes o realizar otras operaciones.

  4. Envíe la solicitud de comando y la consulta de estado del dispositivo

    El servidor IPC del agente puede procesar las solicitudes de comandos y las solicitudes de estado del dispositivo.

    • Solicitud de comando

      Forme una cadena de carga útil de solicitud de comando y, a continuación, llame a la sendCommandRequest función para enviarla. Por ejemplo:

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

      Para obtener más información sobre el formato de solicitud de comando, consulte Solicitudes de comando.

      ejemplo función de devolución de llamada

      El servidor de IPC envía primero un mensaje de confirmación Command received, will send command response back al cliente de IPC. Tras recibir este acuse de recibo, el cliente de IPC puede esperar un evento de respuesta de comando.

      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); }
    • Solicitud de estado del dispositivo

      Al igual que la sendCommandRequest función, esta sendDeviceStateQuery función también toma una cadena de carga útil, la devolución de llamada correspondiente y el contexto del cliente.

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

Cargas útiles y definiciones de la interfaz IPC

Esta sección se centra en las interfaces de IPC específicas para la comunicación entre el agente y los componentes externos, y proporciona ejemplos de implementaciones de IPC APIs entre esos dos componentes. En los ejemplos siguientes, el componente externo administra las rutinas locales.

En la IoTManagedIntegrationsDevice-IPC biblioteca, se definen los siguientes comandos y eventos para la comunicación entre el agente y el componente externo.

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;

Solicitud de comando

Formato de solicitud de comando
  • ejemplo solicitud de comando
    { "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 } } ] } ] }] } }
Formato de respuesta al comando
  • Si la solicitud de comando del componente externo es válida, el agente la envía al CDMB (Common Data Model Bridge). La respuesta de comando real, que contiene el tiempo de ejecución del comando y otra información, no se devuelve inmediatamente al componente externo, ya que el procesamiento de los comandos lleva tiempo. Esta respuesta de comando es una respuesta instantánea del agente (como un acuse de recibo). La respuesta indica al componente externo que gestionó las integraciones recibió el comando y que lo procesará o lo descartará si no hay un token local válido. La respuesta al comando se envía en formato de cadena.

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

Solicitud de estado del dispositivo

El componente externo envía una solicitud de estado del dispositivo al agente. La solicitud proporciona el estado managedThingId de un dispositivo y, a continuación, el agente responde con el estado de ese dispositivo.

Formato de solicitud de estado del dispositivo
  • La solicitud de estado del dispositivo debe ser el managedThingId del dispositivo consultado.

    { "payload": { "managedThingId": "testManagedThingId" } }
Formato de respuesta del estado del dispositivo
  • Si la solicitud de estado del dispositivo es válida, el agente devuelve el estado en formato de cadena.

    ejemplo respuesta del estado del dispositivo para una solicitud válida
    { "payload": { "currentState": "exampleState" } }

    Si la solicitud de estado del dispositivo no es válida (por ejemplo, si no hay un token válido, no se puede procesar la carga útil u otro caso de error), el agente devuelve la respuesta. La respuesta incluye el código de error y el mensaje de error.

    ejemplo respuesta del estado del dispositivo a una solicitud no válida
    { "payload": { "response":{ "code": 111, "message": "errorMessage" } } }

Respuesta de comando

ejemplo formato de respuesta al comando
{ "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":[ {} ] } ] }] } }

Evento de notificación

ejemplo formato de evento de notificación
{ "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 } ] } ] }] } }