Руководство. Использование MQTT для разработки клиента устройства Интернета вещей без использования пакета SDK для устройств

Вы должны использовать один из пакетов SDK для устройств Интернета вещей Azure для создания клиентов устройств Интернета вещей, если это возможно. Но в некоторых сценариях, например при ограниченном объеме памяти на устройстве, возможно, потребуется использовать библиотеку MQTT для обмена данными с центром Интернета вещей.

Примеры из этого руководства используют библиотеку Eclipse Mosquitto MQTT.

В этом руководстве описано следующее:

  • Создайте примеры приложений на языке C.
  • Запустите пример, использующий библиотеку MQTT для отправки данных телеметрии.
  • Запустите пример, использующий библиотеку MQTT для обработки сообщения из облака на устройство, отправляемого из Центра Интернета вещей.
  • Запустите пример, использующий библиотеку MQTT для управления двойником устройства на устройстве.

Чтобы выполнить действия, описанные в этом руководстве, можно использовать компьютер для разработки Windows или Linux.

Если у вас нет подписки Azure, создайте бесплатную учетную запись, прежде чем приступить к работе.

Необходимые компоненты

Подготовка среды к работе с Azure CLI

  • Используйте среду Bash в Azure Cloud Shell. Дополнительные сведения см . в кратком руководстве по Bash в Azure Cloud Shell.

  • Если вы предпочитаете выполнять справочные команды CLI локально, установите Azure CLI. Если вы работаете в Windows или macOS, Azure CLI можно запустить в контейнере Docker. Дополнительные сведения см. в статье Как запустить Azure CLI в контейнере Docker.

    • Если вы используете локальную установку, выполните вход в Azure CLI с помощью команды az login. Чтобы выполнить аутентификацию, следуйте инструкциям в окне терминала. Сведения о других возможностях, доступных при входе, см. в статье Вход с помощью Azure CLI.

    • Установите расширение Azure CLI при первом использовании, когда появится соответствующий запрос. Дополнительные сведения о расширениях см. в статье Использование расширений с Azure CLI.

    • Выполните команду az version, чтобы узнать установленную версию и зависимые библиотеки. Чтобы обновиться до последней версии, выполните команду az upgrade.

Предварительные требования к компьютеру разработки

Если вы используете Windows, выполните следующие действия.

  1. Установите Visual Studio (Community, Professional или Enterprise). Обязательно включите разработку классических приложений с помощью рабочей нагрузки C++ .

  2. Установка CMake. Включите CMake в системный ПУТЬ для всех пользователей .

  3. Установите версию x64 Mosquitto.

Если вы используете Linux:

  1. Выполните следующую команду, чтобы установить средства сборки:

    sudo apt install cmake g++
    
  2. Выполните следующую команду, чтобы установить клиентская библиотека Mosquitto:

    sudo apt install libmosquitto-dev
    

Настройка среды

Если у вас еще нет центра Интернета вещей, выполните следующие команды, чтобы создать центр Интернета вещей уровня "Бесплатный" в группе mqtt-sample-rgресурсов. Команда использует имя my-hub в качестве примера для создания центра Интернета вещей. Выберите уникальное имя центра Интернета вещей, которое будет использоваться вместо 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 

Запишите имя центра Интернета вещей, вам потребуется позже.

Зарегистрируйте устройство в Центре Интернета вещей. Следующая команда регистрирует устройство, вызывающееся mqtt-dev-01 в центре my-hubИнтернета вещей. Обязательно используйте имя центра Интернета вещей:

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

Используйте следующую команду, чтобы создать маркер SAS, предоставляющий устройству доступ к центру Интернета вещей. Обязательно используйте имя центра Интернета вещей:

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

Запишите маркер SAS, который выводит команду, как это нужно позже. Маркер SAS выглядит следующим образом. SharedAccessSignature sr=my-hub.azure-devices.net%2Fdevices%2Fmqtt-dev-01&sig=%2FnM...sNwtnnY%3D&se=1677855761

Совет

По умолчанию маркер SAS действителен в течение 60 минут. Параметр --du 7200 в предыдущей команде расширяет длительность маркера до двух часов. Если срок действия истекает, прежде чем вы будете готовы к использованию, создайте новый. Вы также можете создать маркер с более длительной длительностью. Дополнительные сведения см. в статье az iot hub generate-sas-token.

Клонирование примера репозитория

Используйте следующую команду, чтобы клонировать пример репозитория в подходящее расположение на локальном компьютере:

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

Репозиторий также включает:

  • Пример Python, использующий библиотеку paho-mqtt .
  • Инструкции по использованию интерфейса командной mosquitto_pub строки для взаимодействия с центром Интернета вещей.

Создание примеров C

Перед сборкой примера необходимо добавить сведения о центре Интернета вещей и устройства. В клонированного репозитория IoTMQTTSample откройте файл mosquitto/src/config.h . Добавьте имя центра Интернета вещей, идентификатор устройства и маркер SAS, как показано ниже. Обязательно используйте имя центра Интернета вещей:

// 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"

Примечание.

Файл IoTHubRootCA.crt.pem включает корневые сертификаты ЦС для подключения TLS.

Сохраните изменения в файле mosquitto/src/config.h .

Чтобы создать примеры, выполните следующие команды в оболочке:

cd mosquitto
cmake -Bbuild
cmake --build build

В Linux двоичные файлы находятся в папке ./build под папкой mosquitto .

В Windows двоичные файлы находятся в папке .\build\Debug под папкой mosquitto .

Отправка данных телеметрии

В примере mosquitto_telemetry показано, как отправить сообщение телеметрии устройства в облако в Центр Интернета вещей с помощью библиотеки MQTT.

Перед запуском примера приложения выполните следующую команду, чтобы запустить монитор событий для Центра Интернета вещей. Обязательно используйте имя центра Интернета вещей:

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

Запустите пример mosquitto_telemetry. Например, в Linux:

./build/mosquitto_telemetry

Создает az iot hub monitor-events следующие выходные данные, показывающие полезные данные, отправленные устройством:

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

Теперь можно остановить монитор событий.

Просмотр кода

Следующие фрагменты кода взяты из файла mosquitto/src/mosquitto_telemetry.cpp .

Следующие инструкции определяют сведения о подключении и имя раздела MQTT, используемого для отправки сообщения телеметрии:

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

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

Функция main задает имя пользователя и пароль для проверки подлинности в Центре Интернета вещей. Пароль — это маркер SAS, созданный для устройства:

mosquitto_username_pw_set(mosq, USERNAME, SAS_TOKEN);

В примере используется раздел MQTT для отправки сообщения телеметрии в центр Интернета вещей:

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

Дополнительные сведения см. в статье "Отправка сообщений устройства в облако".

Получение сообщения об облачном устройстве

В примере mosquitto_subscribe показано, как подписаться на разделы MQTT и получить сообщение из центра Интернета вещей с помощью библиотеки MQTT.

Запустите пример mosquitto_subscribe. Например, в Linux:

./build/mosquitto_subscribe

Выполните следующую команду, чтобы отправить сообщение из Центра Интернета вещей в облако. Обязательно используйте имя центра Интернета вещей:

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

Выходные данные из mosquitto_subscribe выглядят следующим образом:

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

Просмотр кода

Следующие фрагменты кода взяты из файла mosquitto/src/mosquitto_subscribe.cpp .

Следующая инструкция определяет фильтр раздела, который устройство использует для получения сообщений об облаке для устройств. Это # многоуровневый дикий карта:

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

Функция main использует mosquitto_message_callback_set функцию для настройки обратного вызова для обработки сообщений, отправленных из Центра Интернета вещей, и использует mosquitto_subscribe функцию для подписки на все сообщения. В следующем фрагменте кода показана функция обратного вызова:

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

Дополнительные сведения см. в статье "Использование MQTT для получения сообщений из облака на устройство".

Обновление двойника устройства

В примере mosquitto_device_twin показано, как задать сообщаемое свойство в двойнике устройства, а затем считывать свойство обратно.

Запустите пример mosquitto_device_twin. Например, в Linux:

./build/mosquitto_device_twin

Выходные данные из mosquitto_device_twin выглядят следующим образом:

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.

Просмотр кода

Следующие фрагменты кода взяты из файла mosquitto/src/mosquitto_device_twin.cpp .

Следующие инструкции определяют разделы, которые устройство использует для подписки на обновления двойника устройства, чтения двойника устройства и обновления двойника устройства:

#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"

Функция main использует mosquitto_connect_callback_set функцию для настройки обратного вызова для обработки сообщений, отправленных из Центра Интернета вещей, и использует mosquitto_subscribe функцию для подписки на $iothub/twin/res/# раздел.

В следующем фрагменте кода показана connect_callback функция, которая используется mosquitto_publish для задания сообщаемого свойства в двойнике устройства. Устройство публикует сообщение в $iothub/twin/PATCH/properties/reported/?$rid=%d разделе. Значение %d увеличивается каждый раз, когда устройство публикует сообщение в раздел:

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 ...  
}

Устройство подписывается на $iothub/twin/res/# раздел и когда оно получает сообщение из Центра Интернета вещей, message_callback функция обрабатывает ее. При запуске примера message_callback функция вызывается дважды. В первый раз устройство получает ответ от Центра Интернета вещей к отчету об обновлении свойств. Затем устройство запрашивает двойник устройства. Во второй раз устройство получает запрошенный двойник устройства. В следующем фрагменте кода показана message_callback функция:

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
    }
}

Дополнительные сведения см. в статье "Использование MQTT для обновления сообщаемого свойства двойника устройства" и использования MQTT для получения свойства двойника устройства.

Очистка ресурсов

Если вы планируете продолжить работу с дополнительными статьями разработчиков устройств, вы можете сохранить и повторно использовать ресурсы, используемые в этой статье. В противном случае можно удалить ресурсы, созданные в этой статье, чтобы избежать дополнительных расходов.

Вы можете одновременно удалить центр и зарегистрированное устройство, удалив всю группу ресурсов с помощью приведенной команды Azure CLI. Не выполняйте данную команду, если эти ресурсы находятся в группе ресурсов с другими нужными вам ресурсами.

az group delete --name <YourResourceGroupName>

Чтобы удалить только Центр Интернета вещей, выполните следующую команду с помощью Azure CLI:

az iot hub delete --name <YourIoTHubName>

Чтобы удалить только то удостоверение устройства, которое вы зарегистрировали в Центре Интернета вещей, выполните следующую команду с помощью интерфейса командной строки Azure:

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

Вы также можете удалить клонированные примеры файлов с компьютера, на котором выполняется разработка.

Следующие шаги

Теперь, когда вы узнали, как использовать библиотеку Mosquitto MQTT для взаимодействия с Центр Интернета вещей, рекомендуемый следующий шаг — проверить: