Share via


Tutorial - Use o MQTT para desenvolver um cliente de dispositivo IoT sem usar um SDK de dispositivo

Você deve usar um dos SDKs de Dispositivo IoT do Azure para criar seus clientes de dispositivo IoT, se possível. No entanto, em cenários como o uso de um dispositivo com restrição de memória, talvez seja necessário usar uma biblioteca MQTT para se comunicar com seu hub IoT.

Os exemplos neste tutorial usam a biblioteca MQTT do Eclipse Mosquitto .

Neste tutorial, irá aprender a:

  • Crie os aplicativos de exemplo de cliente de dispositivo de linguagem C.
  • Execute um exemplo que usa a biblioteca MQTT para enviar telemetria.
  • Execute um exemplo que usa a biblioteca MQTT para processar uma mensagem da nuvem para o dispositivo enviada do seu hub IoT.
  • Execute um exemplo que usa a biblioteca MQTT para gerenciar o dispositivo gêmeo no dispositivo.

Você pode usar uma máquina de desenvolvimento Windows ou Linux para concluir as etapas neste tutorial.

Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.

Pré-requisitos

Prepare o seu ambiente para o CLI do Azure

  • Use o ambiente Bash no Azure Cloud Shell. Para obter mais informações, consulte Guia de início rápido para Bash no Azure Cloud Shell.

  • Se preferir executar comandos de referência da CLI localmente, instale a CLI do Azure. Se estiver a utilizar o Windows ou macOS, considere executar a CLI do Azure num contentor Docker. Para obter mais informações, consulte Como executar a CLI do Azure em um contêiner do Docker.

    • Se estiver a utilizar uma instalação local, inicie sessão no CLI do Azure ao utilizar o comando az login. Para concluir o processo de autenticação, siga os passos apresentados no seu terminal. Para outras opções de entrada, consulte Entrar com a CLI do Azure.

    • Quando solicitado, instale a extensão da CLI do Azure na primeira utilização. Para obter mais informações sobre as extensões, veja Utilizar extensões com o CLI do Azure.

    • Execute o comando az version para localizar a versão e as bibliotecas dependentes instaladas. Para atualizar para a versão mais recente, execute o comando az upgrade.

Pré-requisitos da máquina de desenvolvimento

Se estiver a utilizar o Windows:

  1. Instale o Visual Studio (Comunidade, Professional ou Enterprise). Certifique-se de habilitar o desenvolvimento Desktop com carga de trabalho C++ .

  2. Instale o CMake. Habilite a opção Adicionar CMake ao PATH do sistema para todos os usuários .

  3. Instale a versão x64 do Mosquitto.

Se você estiver usando Linux:

  1. Execute o seguinte comando para instalar as ferramentas de compilação:

    sudo apt install cmake g++
    
  2. Execute o seguinte comando para instalar a biblioteca de cliente Mosquitto:

    sudo apt install libmosquitto-dev
    

Configurar o ambiente

Se você ainda não tiver um hub IoT, execute os seguintes comandos para criar um hub IoT de camada livre em um grupo de recursos chamado mqtt-sample-rg. O comando usa o nome my-hub como um exemplo para o nome do hub IoT a ser criado. Escolha um nome exclusivo para seu hub IoT para usar no lugar de my-hub:

az group create --name mqtt-sample-rg --location eastus
az iot hub create --name my-hub --resource-group mqtt-sample-rg --sku F1 

Anote o nome do seu hub IoT, você precisará dele mais tarde.

Registre um dispositivo em seu hub IoT. O comando a seguir registra um dispositivo chamado mqtt-dev-01 em um hub IoT chamado my-hub. Certifique-se de usar o nome do seu hub IoT:

az iot hub device-identity create --hub-name my-hub --device-id mqtt-dev-01

Use o comando a seguir para criar um token SAS que conceda ao dispositivo acesso ao seu hub IoT. Certifique-se de usar o nome do seu hub IoT:

az iot hub generate-sas-token --device-id mqtt-dev-01 --hub-name my-hub --du 7200

Anote o token SAS que o comando produz quando precisar dele mais tarde. O token SAS tem a aparência de SharedAccessSignature sr=my-hub.azure-devices.net%2Fdevices%2Fmqtt-dev-01&sig=%2FnM...sNwtnnY%3D&se=1677855761

Gorjeta

Por padrão, o token SAS é válido por 60 minutos. A --du 7200 opção no comando anterior estende a duração do token para duas horas. Se ele expirar antes de você estar pronto para usá-lo, gere um novo. Você também pode criar um token com uma duração maior. Para saber mais, consulte az iot hub generate-sas-token.

Clone o repositório de exemplo

Use o seguinte comando para clonar o repositório de exemplo para um local adequado em sua máquina local:

git clone https://github.com/Azure-Samples/IoTMQTTSample.git

O repositório também inclui:

  • Um exemplo Python que usa a paho-mqtt biblioteca.
  • Instruções para usar a mosquitto_pub CLI para interagir com seu hub IoT.

Compilar os exemplos C

Antes de criar o exemplo, você precisa adicionar o hub IoT e os detalhes do dispositivo. No repositório clonado IoTMQTTSample, abra o arquivo mosquitto/src/config.h . Adicione o nome do hub IoT, o ID do dispositivo e o token SAS da seguinte maneira. Certifique-se de usar o nome do seu hub IoT:

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#define IOTHUBNAME "my-hub"
#define DEVICEID   "mqtt-dev-01"
#define SAS_TOKEN  "SharedAccessSignature sr=my-hub.azure-devices.net%2Fdevices%2Fmqtt-dev-01&sig=%2FnM...sNwtnnY%3D&se=1677855761"

#define CERTIFICATEFILE CERT_PATH "IoTHubRootCA.crt.pem"

Nota

O arquivo IoTHubRootCA.crt.pem inclui os certificados raiz da CA para a conexão TLS.

Salve as alterações no arquivo mosquitto/src/config.h .

Para criar os exemplos, execute os seguintes comandos em seu shell:

cd mosquitto
cmake -Bbuild
cmake --build build

No Linux, os binários estão na pasta ./build abaixo da pasta mosquitto .

No Windows, os binários estão na pasta .\build\Debug abaixo da pasta mosquitto .

Enviar telemetria

O exemplo de mosquitto_telemetry mostra como enviar uma mensagem de telemetria de dispositivo para nuvem para seu hub IoT usando a biblioteca MQTT.

Antes de executar o aplicativo de exemplo, execute o seguinte comando para iniciar o monitor de eventos para seu hub IoT. Certifique-se de usar o nome do seu hub IoT:

az iot hub monitor-events --hub-name my-hub

Execute o exemplo de mosquitto_telemetry . Por exemplo, no Linux:

./build/mosquitto_telemetry

O az iot hub monitor-events gera a seguinte saída que mostra a carga enviada pelo dispositivo:

Starting event monitor, use ctrl-c to stop...
{
    "event": {
        "origin": "mqtt-dev-01",
        "module": "",
        "interface": "",
        "component": "",
        "payload": "Bonjour MQTT from Mosquitto"
    }
}

Agora você pode parar o monitor de eventos.

Rever o código

Os trechos a seguir são retirados do arquivo mosquitto/src/mosquitto_telemetry.cpp .

As instruções a seguir definem as informações de conexão e o nome do tópico MQTT que você usa para enviar a mensagem de telemetria:

#define HOST IOTHUBNAME ".azure-devices.net"
#define PORT 8883
#define USERNAME HOST "/" DEVICEID "/?api-version=2020-09-30"

#define TOPIC "devices/" DEVICEID "/messages/events/"

A main função define o nome de usuário e a senha para autenticação com seu hub IoT. A palavra-passe é o token SAS que criou para o seu dispositivo:

mosquitto_username_pw_set(mosq, USERNAME, SAS_TOKEN);

O exemplo usa o tópico MQTT para enviar uma mensagem de telemetria para seu hub IoT:

int msgId  = 42;
char msg[] = "Bonjour MQTT from Mosquitto";

// once connected, we can publish a Telemetry message
printf("Publishing....\r\n");
rc = mosquitto_publish(mosq, &msgId, TOPIC, sizeof(msg) - 1, msg, 1, true);
if (rc != MOSQ_ERR_SUCCESS)
{
    return mosquitto_error(rc);
}
printf("Publish returned OK\r\n");

Para saber mais, consulte Enviar mensagens do dispositivo para a nuvem.

Receber uma mensagem da nuvem para o dispositivo

O exemplo de mosquitto_subscribe mostra como se inscrever em tópicos MQTT e receber uma mensagem de nuvem para dispositivo do seu hub IoT usando a biblioteca MQTT.

Execute o exemplo de mosquitto_subscribe . Por exemplo, no Linux:

./build/mosquitto_subscribe

Execute o seguinte comando para enviar uma mensagem da nuvem para o dispositivo a partir do seu hub IoT. Certifique-se de usar o nome do seu hub IoT:

az iot device c2d-message send --hub-name my-hub --device-id mqtt-dev-01 --data "hello world"

A saída do mosquitto_subscribe se parece com o exemplo a seguir:

Waiting for C2D messages...
C2D message 'hello world' for topic 'devices/mqtt-dev-01/messages/devicebound/%24.mid=d411e727-...f98f&%24.to=%2Fdevices%2Fmqtt-dev-01%2Fmessages%2Fdevicebound&%24.ce=utf-8&iothub-ack=none'
Got message for devices/mqtt-dev-01/messages/# topic

Rever o código

Os trechos a seguir são retirados do arquivo mosquitto/src/mosquitto_subscribe.cpp .

A instrução a seguir define o filtro de tópico que o dispositivo usa para receber mensagens da nuvem para o dispositivo. O # é um curinga de vários níveis:

#define DEVICEMESSAGE "devices/" DEVICEID "/messages/#"

A main função usa a mosquitto_message_callback_set função para definir um retorno de chamada para lidar com mensagens enviadas do seu hub IoT e usa a mosquitto_subscribe função para assinar todas as mensagens. O trecho a seguir mostra a função de retorno de chamada:

void message_callback(struct mosquitto* mosq, void* obj, const struct mosquitto_message* message)
{
    printf("C2D message '%.*s' for topic '%s'\r\n", message->payloadlen, (char*)message->payload, message->topic);

    bool match = 0;
    mosquitto_topic_matches_sub(DEVICEMESSAGE, message->topic, &match);

    if (match)
    {
        printf("Got message for " DEVICEMESSAGE " topic\r\n");
    }
}

Para saber mais, consulte Usar MQTT para receber mensagens da nuvem para o dispositivo.

Atualizar um dispositivo twin

O exemplo de mosquitto_device_twin mostra como definir uma propriedade relatada em um dispositivo gêmeo e, em seguida, ler a propriedade novamente.

Execute o mosquitto_device_twin exemplo. Por exemplo, no Linux:

./build/mosquitto_device_twin

A saída do mosquitto_device_twin se parece com o exemplo a seguir:

Setting device twin reported properties....
Device twin message '' for topic '$iothub/twin/res/204/?$rid=0&$version=2'
Setting device twin properties SUCCEEDED.

Getting device twin properties....
Device twin message '{"desired":{"$version":1},"reported":{"temperature":32,"$version":2}}' for topic '$iothub/twin/res/200/?$rid=1'
Getting device twin properties SUCCEEDED.

Rever o código

Os trechos a seguir são retirados do arquivo mosquitto/src/mosquitto_device_twin.cpp .

As instruções a seguir definem os tópicos que o dispositivo usa para assinar atualizações de gêmeos de dispositivo, ler o gêmeo de dispositivo e atualizar o gêmeo de dispositivo:

#define DEVICETWIN_SUBSCRIPTION  "$iothub/twin/res/#"
#define DEVICETWIN_MESSAGE_GET   "$iothub/twin/GET/?$rid=%d"
#define DEVICETWIN_MESSAGE_PATCH "$iothub/twin/PATCH/properties/reported/?$rid=%d"

A main função usa a mosquitto_connect_callback_set função para definir um retorno de chamada para lidar com mensagens enviadas do seu hub IoT e usa a mosquitto_subscribe função para se inscrever no $iothub/twin/res/# tópico.

O trecho a seguir mostra a connect_callback função que usa mosquitto_publish para definir uma propriedade relatada no gêmeo do dispositivo. O dispositivo publica a mensagem para o $iothub/twin/PATCH/properties/reported/?$rid=%d tópico. O %d valor é incrementado cada vez que o dispositivo publica uma mensagem para o tópico:

void connect_callback(struct mosquitto* mosq, void* obj, int result)
{
    // ... other code ...  

    printf("\r\nSetting device twin reported properties....\r\n");

    char msg[] = "{\"temperature\": 32}";
    char mqtt_publish_topic[64];
    snprintf(mqtt_publish_topic, sizeof(mqtt_publish_topic), DEVICETWIN_MESSAGE_PATCH, device_twin_request_id++);

    int rc = mosquitto_publish(mosq, NULL, mqtt_publish_topic, sizeof(msg) - 1, msg, 1, true);
    if (rc != MOSQ_ERR_SUCCESS)

    // ... other code ...  
}

O dispositivo se inscreve no $iothub/twin/res/# tópico e, quando recebe uma mensagem do seu hub IoT, a message_callback função a manipula. Quando você executa o exemplo, a message_callback função é chamada duas vezes. Na primeira vez, o dispositivo recebe uma resposta do hub IoT para a atualização de propriedade relatada. Em seguida, o dispositivo solicita o dispositivo gêmeo. Na segunda vez, o dispositivo recebe o dispositivo gêmeo solicitado. O trecho a seguir mostra a message_callback função:

void message_callback(struct mosquitto* mosq, void* obj, const struct mosquitto_message* message)
{
    printf("Device twin message '%.*s' for topic '%s'\r\n", message->payloadlen, (char*)message->payload, message->topic);

    const char patchTwinTopic[] = "$iothub/twin/res/204/?$rid=0";
    const char getTwinTopic[]   = "$iothub/twin/res/200/?$rid=1";

    if (strncmp(message->topic, patchTwinTopic, sizeof(patchTwinTopic) - 1) == 0)
    {
        // Process the reported property response and request the device twin
        printf("Setting device twin properties SUCCEEDED.\r\n\r\n");

        printf("Getting device twin properties....\r\n");

        char msg[] = "{}";
        char mqtt_publish_topic[64];
        snprintf(mqtt_publish_topic, sizeof(mqtt_publish_topic), DEVICETWIN_MESSAGE_GET, device_twin_request_id++);

        int rc = mosquitto_publish(mosq, NULL, mqtt_publish_topic, sizeof(msg) - 1, msg, 1, true);
        if (rc != MOSQ_ERR_SUCCESS)
        {
            printf("Error: %s\r\n", mosquitto_strerror(rc));
        }
    }
    else if (strncmp(message->topic, getTwinTopic, sizeof(getTwinTopic) - 1) == 0)
    {
        // Process the device twin response and stop the client
        printf("Getting device twin properties SUCCEEDED.\r\n\r\n");

        mosquitto_loop_stop(mosq, false);
        mosquitto_disconnect(mosq); // finished, exit program
    }
}

Para saber mais, consulte Usar MQTT para atualizar uma propriedade de relatório de gêmeo de dispositivo e Usar MQTT para recuperar uma propriedade de gêmeo de dispositivo.

Clean up resources (Limpar recursos)

Se você planeja continuar com mais artigos de desenvolvedor de dispositivos, poderá manter e reutilizar os recursos usados neste artigo. Caso contrário, você pode excluir os recursos criados neste artigo para evitar mais cobranças.

Você pode excluir o hub e o dispositivo registrado de uma só vez excluindo todo o grupo de recursos com o seguinte comando da CLI do Azure. Não use esse comando se esses recursos estiverem compartilhando um grupo de recursos com outros recursos que você deseja manter.

az group delete --name <YourResourceGroupName>

Para excluir apenas o hub IoT, execute o seguinte comando usando a CLI do Azure:

az iot hub delete --name <YourIoTHubName>

Para excluir apenas a identidade do dispositivo que você registrou com seu hub IoT, execute o seguinte comando usando a CLI do Azure:

az iot hub device-identity delete --hub-name <YourIoTHubName> --device-id <YourDeviceID>

Você também pode querer remover os arquivos de exemplo clonados de sua máquina de desenvolvimento.

Próximos passos

Agora que você aprendeu como usar a biblioteca MQTT Mosquitto para se comunicar com o Hub IoT, uma próxima etapa sugerida é revisar: