Поделиться через


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

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

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

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

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

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

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

Предпосылки

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

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

  2. Установка CMake. Включите опцию Добавить CMake в системную переменную PATH для всех пользователей.

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

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

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

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

Это важно

В этой статье представлена инструкция по подключению устройства с использованием подписи общего доступа, также называемой аутентификацией по симметричному ключу. Этот метод проверки подлинности удобнее для тестирования и оценки, но проверка подлинности устройства с помощью сертификатов X.509 является более безопасным подходом. Дополнительные сведения см. в разделе Лучшие методы обеспечения безопасности IoT-решений > Безопасность подключения.

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

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

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 и получить сообщение от облака к устройству через ваш IoT-хаб.

Запустите пример 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 функция вызывается дважды. В первый раз устройство получает ответ от IoT-хаба об обновленном свойстве. Затем устройство запрашивает двойник устройства. Во второй раз устройство получает запрашиваемый двойник устройства. В следующем фрагменте кода показана 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>

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

Дальнейшие действия

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