Cliente de comunicação entre processos (IPC) APIs - Integrações gerenciadas para AWS IoT Device Management

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Cliente de comunicação entre processos (IPC) APIs

Os componentes externos no hub de integrações gerenciadas podem se comunicar com o SDK do Hub de integrações gerenciadas usando seu componente de agente e comunicações entre processos (IPC). Um exemplo de componente externo no hub é um daemon (um processo em segundo plano em execução contínua) que gerencia as rotinas locais. Durante a comunicação, o cliente IPC é o componente externo que publica comandos ou outras solicitações e se inscreve nos eventos. O servidor IPC é o componente Agente no SDK do Hub de integrações gerenciadas. Para obter mais informações, consulte Configurando o cliente IPC.

Para criar o cliente IPC, IotmiLocalControllerClient é fornecida uma biblioteca de clientes IPC. Essa biblioteca fornece comunicação do lado do cliente APIs com o servidor IPC no Agent, incluindo o envio de solicitações de comando, a consulta de estados do dispositivo, a assinatura de eventos (como o evento de estado do dispositivo) e o tratamento de interações baseadas em eventos.

Configurando o cliente IPC

A IotmiLocalControllerClient biblioteca é um invólucro em torno do IPC básico APIs, que simplifica e agiliza o processo de implementação do IPC em seus aplicativos. As seções a seguir descrevem o APIs que ele fornece.

nota

Este tópico é especificamente para um componente externo como cliente IPC e não para as implementações de um servidor IPC.

  1. Crie um cliente IPC

    Você deve primeiro inicializar o cliente IPC antes que ele possa ser usado para processar solicitações. Você pode usar um construtor na IotmiLocalControllerClient biblioteca, que usa o contexto do assinante char *subscriberCtx como parâmetro e cria um gerenciador de clientes IPC com base nele. Veja a seguir um exemplo de criação de um cliente IPC:

    // Context for subscriber char subscriberCtx[] = "example_ctx"; // Instantiate the client IotmiLocalControllerClient lcc(subscriberCtx);
  2. Inscreva-se em um evento

    Você pode inscrever o cliente IPC em eventos do servidor IPC de destino. Quando o servidor IPC publica um evento no qual o cliente está inscrito, o cliente recebe esse evento. Para se inscrever, use a registerSubscriber função e forneça o evento IDs para se inscrever, bem como o retorno de chamada personalizado.

    Veja a seguir uma definição da registerSubscriber função e seu exemplo de 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);

    O status é definido para verificar se a operação (como assinar ou enviar solicitação) foi bem-sucedida. Se a operação for bem-sucedida, o status retornado seráIOTMI_STATUS_OK (= 0).

    nota

    A biblioteca IPC tem as seguintes cotas de serviço para o número máximo de assinantes e eventos em uma assinatura:

    • Número máximo de assinantes por processo: 5

      Definido como IOTMI_IPC_MAX_SUBSCRIBER na biblioteca IPC.

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

      Definido como IOTMI_IPC_EVENT_PUBLIC_END na biblioteca IPC.

    • Cada assinante tem um campo de eventos de 32 bits, onde cada bit corresponde a um evento definido.

  3. Conecte o cliente IPC ao servidor

    A função de conexão na IotmiLocalControllerClient biblioteca executa tarefas como inicializar o cliente IPC, registrar assinantes e assinar eventos que foram fornecidos na função. registerSubscriber Você pode chamar a função de conexão no cliente IPC.

    status = lcc.connect();

    Confirme se o status retornado é IOTMI_STATUS_OK antes de enviar solicitações ou fazer outras operações.

  4. Enviar solicitação de comando e consulta de estado do dispositivo

    O servidor IPC no Agent pode processar solicitações de comando e solicitações de estado do dispositivo.

    • Solicitação de comando

      Forme uma string de carga útil de solicitação de comando e chame a sendCommandRequest função para enviá-la. Por exemplo:

      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 obter mais informações sobre o formato da solicitação de comando, consulte solicitações de comando.

      exemplo função de retorno de chamada

      O servidor IPC primeiro envia uma mensagem de confirmação Command received, will send command response back ao cliente IPC. Depois de receber essa confirmação, o cliente IPC pode esperar um evento de resposta 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); }
    • Solicitação de estado do dispositivo

      Da mesma forma que a sendCommandRequest função, essa sendDeviceStateQuery função também usa uma string de carga útil, o retorno de chamada correspondente e o contexto do cliente.

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

Definições e cargas úteis da interface IPC

Esta seção se concentra nas interfaces IPC especificamente para comunicação entre o Agente e os componentes externos e fornece exemplos de implementações de IPC APIs entre esses dois componentes. Nos exemplos a seguir, o componente externo gerencia as rotinas locais.

Na IoTManagedIntegrationsDevice-IPC biblioteca, os seguintes comandos e eventos são definidos para comunicação entre o Agente e o 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;

Solicitação de comando

Formato de solicitação de comando
  • exemplo solicitação 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 resposta de comando
  • Se a solicitação de comando do componente externo for válida, o agente a enviará para o CDMB (Common Data Model Bridge). A resposta real do comando que contém o tempo de execução do comando e outras informações não é enviada de volta ao componente externo imediatamente, pois o processamento dos comandos leva tempo. Essa resposta de comando é uma resposta instantânea do Agente (como uma confirmação). A resposta informa ao componente externo que as integrações gerenciadas receberam o comando e o processarão ou o descartarão se não houver um token local válido. A resposta do comando é enviada em formato de string.

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

Solicitação de estado do dispositivo

O componente externo envia uma solicitação de estado do dispositivo ao Agente. A solicitação fornece o managedThingId de um dispositivo e, em seguida, o Agente responde com o estado desse dispositivo.

Formato de solicitação de estado do dispositivo
  • A solicitação de estado do seu dispositivo deve ter a managedThingId do dispositivo consultado.

    { "payload": { "managedThingId": "testManagedThingId" } }
Formato de resposta ao estado do dispositivo
  • Se a solicitação de estado do dispositivo for válida, o Agente enviará o estado de volta no formato de string.

    exemplo resposta do estado do dispositivo para uma solicitação válida
    { "payload": { "currentState": "exampleState" } }

    Se a solicitação de estado do dispositivo não for válida (por exemplo, se não houver um token válido, a carga não puder ser processada ou outro caso de erro), o agente retornará a resposta. A resposta inclui o código de erro e a mensagem de erro.

    exemplo resposta do estado do dispositivo para uma solicitação inválida
    { "payload": { "response":{ "code": 111, "message": "errorMessage" } } }

Resposta do comando

exemplo formato de resposta de 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 notificação

exemplo formato de evento de notificação
{ "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 } ] } ] }] } }