Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Обзор сценария
В этом сценарии создается устройство, которое отправляет следующие данные телеметрии в предварительно настроенное решение для удаленного мониторинга:
- Внешняя температура
- Внутренняя температура
- Влажность
Для простоты код на устройстве создает примеры значений, но мы рекомендуем расширить пример, подключив реальные датчики к устройству и отправив реальные данные телеметрии.
Устройство также может реагировать на методы, вызываемые на панели мониторинга решения, и требуемые значения свойств, заданные на панели мониторинга решения.
Для работы с этим руководством требуется активная учетная запись Azure. Если ее нет, можно создать бесплатную пробную учетную запись всего за несколько минут. Дополнительные сведения см. на странице бесплатной пробной версии Azure.
Перед началом работы
Перед написанием кода для устройства необходимо подготовить предварительно настроенное решение для удаленного мониторинга и подготовить новое пользовательское устройство в этом решении.
Подготовка предварительно настроенного решения для удаленного мониторинга
Созданное в этом руководстве устройство отправляет данные в экземпляр предварительно настроенного решения для удаленного мониторинга . Если вы еще не подготовили предварительно настроенное решение для удаленного мониторинга в учетной записи Azure, выполните следующие действия.
- На странице https://www.azureiotsolutions.com/ щелкните по +, чтобы создать решение.
- Нажмите кнопку "Выбрать " на панели удаленного мониторинга , чтобы создать решение.
- На странице "Создание решения для удаленного мониторинга " введите имя решения , выберите регион , в который вы хотите развернуть, и выберите подписку Azure для использования. Затем нажмите кнопку "Создать решение".
- Дождитесь завершения процесса настройки.
Предупреждение
Предварительно настроенные решения используют оплачиваемые службы Azure. Не забудьте удалить предварительно настроенное решение из подписки, чтобы избежать ненужных расходов. Вы можете полностью удалить предварительно настроенное решение из подписки, перейдя на страницу https://www.azureiotsolutions.com/ .
Когда процесс подготовки решения для удаленного мониторинга завершится, нажмите кнопку "Запустить ", чтобы открыть панель мониторинга решения в браузере.
Настройте ваше устройство в системе для удаленного мониторинга
Примечание.
Если вы уже подготовили устройство для вашего решения, можно пропустить данный шаг. При создании клиентского приложения необходимо знать учетные данные устройства.
Для подключения устройства к предварительно настроенного решения он должен идентифицировать себя в Центре Интернета вещей с использованием допустимых учетных данных. Учетные данные устройства можно получить на панели мониторинга решения. В этом руководстве позже вы добавите учетные данные устройства в клиентское приложение.
Чтобы добавить устройство в решение удаленного мониторинга, выполните следующие действия на панели мониторинга решения:
В левом нижнем углу панели мониторинга щелкните Добавить устройство.
На панели пользовательского устройства щелкните Добавить новое.
Выберите Позвольте мне определить собственный идентификатор устройства. Введите идентификатор устройства, например mydevice, нажмите кнопку "Проверить идентификатор ", чтобы убедиться, что имя еще не используется, а затем нажмите кнопку "Создать ", чтобы подготовить устройство.
Запишите учетные данные устройства (идентификатор устройства, имя узла Центра Интернета вещей и ключ устройства). Клиентское приложение должно использовать эти значения для подключения к решению удаленного мониторинга. Затем нажмите кнопку Готово.
Выберите устройство в списке устройств на панели мониторинга решения. Затем на панели сведений об устройстве щелкните Включить устройство. Состояние устройства теперь запущено. Теперь решение удаленного мониторинга может получать данные телеметрии с устройства и вызывать методы на устройстве.
Создание примера решения C в Windows
Ниже показано, как создать клиентское приложение, которое взаимодействует с предварительно настроенным решением для удаленного мониторинга. Это приложение написано на языке C и создано и запущено в Windows.
Создайте начальный проект в Visual Studio 2015 или Visual Studio 2017 и добавьте пакеты NuGet клиента устройства Центра Интернета вещей:
В Visual Studio создайте консольное приложение C с помощью шаблона консольного приложения Visual C++ Win32 . Назовите проект RMDevice.
На странице "Параметры приложения" в мастере приложений Win32 убедитесь, что консольное приложение выбрано, и снимите флажок предварительно скомпилированного заголовка и проверки жизненного цикла разработки безопасности (SDL).
В обозревателе решений удалите файлы stdafx.h, targetver.h и stdafx.cpp.
В обозревателе решений переименуйте файл RMDevice.cpp в RMDevice.c.
В обозревателе решений щелкните правой кнопкой мыши проект RMDevice и выберите пункт "Управление пакетами NuGet". Нажмите кнопку "Обзор", а затем найдите и установите следующие пакеты NuGet:
- Microsoft.Azure.IoTHub.Serializer
- Microsoft.Azure.IoTHub.IoTHubClient
- Microsoft.Azure.IoTHub.MqttTransport
В обозревателе решений щелкните правой кнопкой мыши проект RMDevice и выберите пункт "Свойства ", чтобы открыть диалоговое окно "Страницы свойств проекта". Дополнительные сведения см. в статье, посвященной настройке свойств проекта Visual C++.
Щелкните папку Компоновщик, затем щелкните вкладку Вход.
Добавьте crypt32.lib в свойство "Дополнительные зависимости ". Нажмите кнопку "ОК " и снова ОК , чтобы сохранить значения свойств проекта.
Добавьте библиотеку JSON Parson в проект RMDevice и добавьте необходимые #include
инструкции:
В подходящей папке на компьютере клонируйте репозиторий Parson GitHub с помощью следующей команды:
git clone https://github.com/kgabis/parson.git
Скопируйте файлы parson.h и parson.c из локальной копии репозитория Parson в папку проекта RMDevice .
В Visual Studio щелкните правой кнопкой мыши проект RMDevice , нажмите кнопку "Добавить" и выберите пункт "Существующий элемент".
В диалоговом окне "Добавление существующего элемента" выберите файлы parson.h и parson.c в папке проекта RMDevice . Затем нажмите кнопку "Добавить ", чтобы добавить эти два файла в проект.
В Visual Studio откройте файл RMDevice.c. Замените существующие
#include
инструкции следующим кодом:#include "iothubtransportmqtt.h" #include "schemalib.h" #include "iothub_client.h" #include "serializer_devicetwin.h" #include "schemaserializer.h" #include "azure_c_shared_utility/threadapi.h" #include "azure_c_shared_utility/platform.h" #include "parson.h"
Примечание.
Теперь можно убедиться, что у проекта есть правильные зависимости, настроенные путем его создания.
Укажите поведение устройства Интернета вещей
Клиентская библиотека сериализации IoT Hub использует модель для указания формата сообщений, которыми устройство обменивается с Центром Интернета вещей.
Добавьте следующие объявления переменных после инструкций
#include
. Замените значения заполнителей [Идентификатор устройства] и [Ключ устройства] значениями, указанными для устройства на панели мониторинга решения удаленного мониторинга. Используйте имя узла IoT Hub на панели мониторинга решения, чтобы заменить [имя IoTHub]. Например, если имя узла Центра Интернета вещей - contoso.azure-devices.net, замените [Имя IoTHub] на contoso:static const char* deviceId = "[Device Id]"; static const char* connectionString = "HostName=[IoTHub Name].azure-devices.net;DeviceId=[Device Id];SharedAccessKey=[Device Key]";
Добавьте следующий код, чтобы определить модель, которая позволяет устройству взаимодействовать с Центром Интернета вещей. Эта модель указывает, что устройство:
- Может отправлять температуру, внешнюю температуру, влажность и идентификатор устройства в виде телеметрии.
- Может отправлять метаданные об устройстве в Центр Интернета вещей. Устройство отправляет базовые метаданные в объект DeviceInfo при запуске.
- Может отправлять сообщаемые свойства в двойник устройства в Центре Интернета вещей. Эти сообщаемые свойства группируются в свойства конфигурации, устройства и системы.
- Может получать и работать с нужными свойствами, заданными в двойнике устройства в Центре управления Интернетом вещей.
- Может реагировать на прямые методы перезагрузки и инициирования обновления прошивки, вызываемые через портал решения. Устройство отправляет сведения о прямых методах, которые он поддерживает с помощью указанных свойств.
// Define the Model BEGIN_NAMESPACE(Contoso); /* Reported properties */ DECLARE_STRUCT(SystemProperties, ascii_char_ptr, Manufacturer, ascii_char_ptr, FirmwareVersion, ascii_char_ptr, InstalledRAM, ascii_char_ptr, ModelNumber, ascii_char_ptr, Platform, ascii_char_ptr, Processor, ascii_char_ptr, SerialNumber ); DECLARE_STRUCT(LocationProperties, double, Latitude, double, Longitude ); DECLARE_STRUCT(ReportedDeviceProperties, ascii_char_ptr, DeviceState, LocationProperties, Location ); DECLARE_MODEL(ConfigProperties, WITH_REPORTED_PROPERTY(double, TemperatureMeanValue), WITH_REPORTED_PROPERTY(uint8_t, TelemetryInterval) ); /* Part of DeviceInfo */ DECLARE_STRUCT(DeviceProperties, ascii_char_ptr, DeviceID, _Bool, HubEnabledState ); DECLARE_DEVICETWIN_MODEL(Thermostat, /* Telemetry (temperature, external temperature and humidity) */ WITH_DATA(double, Temperature), WITH_DATA(double, ExternalTemperature), WITH_DATA(double, Humidity), WITH_DATA(ascii_char_ptr, DeviceId), /* DeviceInfo */ WITH_DATA(ascii_char_ptr, ObjectType), WITH_DATA(_Bool, IsSimulatedDevice), WITH_DATA(ascii_char_ptr, Version), WITH_DATA(DeviceProperties, DeviceProperties), /* Device twin properties */ WITH_REPORTED_PROPERTY(ReportedDeviceProperties, Device), WITH_REPORTED_PROPERTY(ConfigProperties, Config), WITH_REPORTED_PROPERTY(SystemProperties, System), WITH_DESIRED_PROPERTY(double, TemperatureMeanValue, onDesiredTemperatureMeanValue), WITH_DESIRED_PROPERTY(uint8_t, TelemetryInterval, onDesiredTelemetryInterval), /* Direct methods implemented by the device */ WITH_METHOD(Reboot), WITH_METHOD(InitiateFirmwareUpdate, ascii_char_ptr, FwPackageURI), /* Register direct methods with solution portal */ WITH_REPORTED_PROPERTY(ascii_char_ptr_no_quotes, SupportedMethods) ); END_NAMESPACE(Contoso);
Реализация поведения устройства
Теперь добавьте код, реализующий поведение, определенное в модели.
Добавьте следующие функции, обрабатывающие требуемые свойства, заданные на панели мониторинга решения. Эти требуемые свойства определяются в модели:
void onDesiredTemperatureMeanValue(void* argument) { /* By convention 'argument' is of the type of the MODEL */ Thermostat* thermostat = argument; printf("Received a new desired_TemperatureMeanValue = %f\r\n", thermostat->TemperatureMeanValue); } void onDesiredTelemetryInterval(void* argument) { /* By convention 'argument' is of the type of the MODEL */ Thermostat* thermostat = argument; printf("Received a new desired_TelemetryInterval = %d\r\n", thermostat->TelemetryInterval); }
Добавьте следующие функции, которые обрабатывают прямые методы, вызываемые через Центр Интернета вещей. Эти прямые методы определяются в модели:
/* Handlers for direct methods */ METHODRETURN_HANDLE Reboot(Thermostat* thermostat) { (void)(thermostat); METHODRETURN_HANDLE result = MethodReturn_Create(201, "\"Rebooting\""); printf("Received reboot request\r\n"); return result; } METHODRETURN_HANDLE InitiateFirmwareUpdate(Thermostat* thermostat, ascii_char_ptr FwPackageURI) { (void)(thermostat); METHODRETURN_HANDLE result = MethodReturn_Create(201, "\"Initiating Firmware Update\""); printf("Recieved firmware update request. Use package at: %s\r\n", FwPackageURI); return result; }
Добавьте следующую функцию, которая отправляет сообщение в предварительно настроенное решение:
/* Send data to IoT Hub */ static void sendMessage(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const unsigned char* buffer, size_t size) { IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray(buffer, size); if (messageHandle == NULL) { printf("unable to create a new IoTHubMessage\r\n"); } else { if (IoTHubClient_SendEventAsync(iotHubClientHandle, messageHandle, NULL, NULL) != IOTHUB_CLIENT_OK) { printf("failed to hand over the message to IoTHubClient"); } else { printf("IoTHubClient accepted the message for delivery\r\n"); } IoTHubMessage_Destroy(messageHandle); } free((void*)buffer); }
Добавьте следующий обработчик обратного вызова, который запускается, когда устройство отправило новые сообщаемые значения свойств в предварительно настроенное решение:
/* Callback after sending reported properties */ void deviceTwinCallback(int status_code, void* userContextCallback) { (void)(userContextCallback); printf("IoTHub: reported properties delivered with status_code = %u\n", status_code); }
Добавьте следующую функцию для подключения устройства к предварительно настроенного решения в облаке и обмена данными. Эта функция выполняет следующие действия:
- Инициализирует платформу.
- Регистрирует пространство имен Contoso в библиотеке сериализации.
- Инициализирует клиент с помощью строки подключения устройства.
- Создайте экземпляр модели Thermostat.
- Создает и отправляет сообщаемые значения свойств.
- Отправляет объект DeviceInfo .
- Создает цикл для отправки телеметрии каждую секунду.
- Деинициализирует все ресурсы.
void remote_monitoring_run(void) { if (platform_init() != 0) { printf("Failed to initialize the platform.\n"); } else { if (SERIALIZER_REGISTER_NAMESPACE(Contoso) == NULL) { printf("Unable to SERIALIZER_REGISTER_NAMESPACE\n"); } else { IOTHUB_CLIENT_HANDLE iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, MQTT_Protocol); if (iotHubClientHandle == NULL) { printf("Failure in IoTHubClient_CreateFromConnectionString\n"); } else { #ifdef MBED_BUILD_TIMESTAMP // For mbed add the certificate information if (IoTHubClient_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK) { printf("Failed to set option \"TrustedCerts\"\n"); } #endif // MBED_BUILD_TIMESTAMP Thermostat* thermostat = IoTHubDeviceTwin_CreateThermostat(iotHubClientHandle); if (thermostat == NULL) { printf("Failure in IoTHubDeviceTwin_CreateThermostat\n"); } else { /* Set values for reported properties */ thermostat->Config.TemperatureMeanValue = 55.5; thermostat->Config.TelemetryInterval = 3; thermostat->Device.DeviceState = "normal"; thermostat->Device.Location.Latitude = 47.642877; thermostat->Device.Location.Longitude = -122.125497; thermostat->System.Manufacturer = "Contoso Inc."; thermostat->System.FirmwareVersion = "2.22"; thermostat->System.InstalledRAM = "8 MB"; thermostat->System.ModelNumber = "DB-14"; thermostat->System.Platform = "Plat 9.75"; thermostat->System.Processor = "i3-7"; thermostat->System.SerialNumber = "SER21"; /* Specify the signatures of the supported direct methods */ thermostat->SupportedMethods = "{\"Reboot\": \"Reboot the device\", \"InitiateFirmwareUpdate--FwPackageURI-string\": \"Updates device Firmware. Use parameter FwPackageURI to specify the URI of the firmware file\"}"; /* Send reported properties to IoT Hub */ if (IoTHubDeviceTwin_SendReportedStateThermostat(thermostat, deviceTwinCallback, NULL) != IOTHUB_CLIENT_OK) { printf("Failed sending serialized reported state\n"); } else { printf("Send DeviceInfo object to IoT Hub at startup\n"); thermostat->ObjectType = "DeviceInfo"; thermostat->IsSimulatedDevice = 0; thermostat->Version = "1.0"; thermostat->DeviceProperties.HubEnabledState = 1; thermostat->DeviceProperties.DeviceID = (char*)deviceId; unsigned char* buffer; size_t bufferSize; if (SERIALIZE(&buffer, &bufferSize, thermostat->ObjectType, thermostat->Version, thermostat->IsSimulatedDevice, thermostat->DeviceProperties) != CODEFIRST_OK) { (void)printf("Failed serializing DeviceInfo\n"); } else { sendMessage(iotHubClientHandle, buffer, bufferSize); } /* Send telemetry */ thermostat->Temperature = 50; thermostat->ExternalTemperature = 55; thermostat->Humidity = 50; thermostat->DeviceId = (char*)deviceId; while (1) { unsigned char*buffer; size_t bufferSize; (void)printf("Sending sensor value Temperature = %f, Humidity = %f\n", thermostat->Temperature, thermostat->Humidity); if (SERIALIZE(&buffer, &bufferSize, thermostat->DeviceId, thermostat->Temperature, thermostat->Humidity, thermostat->ExternalTemperature) != CODEFIRST_OK) { (void)printf("Failed sending sensor value\r\n"); } else { sendMessage(iotHubClientHandle, buffer, bufferSize); } ThreadAPI_Sleep(1000); } IoTHubDeviceTwin_DestroyThermostat(thermostat); } } IoTHubClient_Destroy(iotHubClientHandle); } serializer_deinit(); } } platform_deinit(); }
Для справки ниже приведен пример сообщения телеметрии , отправляемого в предварительно настроенное решение:
{"DeviceId":"mydevice01", "Temperature":50, "Humidity":50, "ExternalTemperature":55}
Сборка и запуск примера
Добавьте код для вызова функции remote_monitoring_run , а затем создайте и запустите приложение устройства.
Замените основную функцию следующим кодом, чтобы вызвать функцию remote_monitoring_run :
int main() { remote_monitoring_run(); return 0; }
Нажмите "Собрать" и затем "Собрать решение", чтобы создать приложение для устройства.
В обозревателе решений щелкните правой кнопкой мыши проект RMDevice , щелкните "Отладка" и нажмите кнопку "Пуск нового экземпляра ", чтобы запустить пример. В консоли отображаются сообщения в виде отправки примера телеметрии в предварительно настроенное решение, получение требуемых значений свойств на панели мониторинга решения и реагирование на методы, вызываемые на панели мониторинга решения.
Просмотр телеметрии устройства на панели мониторинга
Панель мониторинга в решении удаленного мониторинга позволяет просматривать данные телеметрии, отправляемые устройствам в Центр Интернета вещей.
В браузере вернитесь на панель мониторинга решения для удаленного мониторинга, щелкните "Устройства " на левой панели, чтобы перейти к списку устройств.
В списке устройств должно быть указано, что состояние устройства запущено. В противном случае нажмите кнопку "Включить устройство" на панели сведений об устройстве .
Щелкните панель мониторинга , чтобы вернуться к панели мониторинга, выберите устройство в раскрывающемся списке "Просмотр устройства ", чтобы просмотреть данные телеметрии. Данные телеметрии из примера приложения — 50 единиц для внутренней температуры, 55 единиц для внешней температуры и 50 единиц для влажности.
Вызов метода на устройстве
Панель мониторинга в решении удаленного мониторинга позволяет вызывать методы на устройствах через Центр Интернета вещей. Например, в решении удаленного мониторинга можно вызвать метод для имитации перезагрузки устройства.
На панели мониторинга решения для удаленного мониторинга щелкните "Устройства " в левой панели, чтобы перейти к списку устройств.
Щелкните идентификатор устройства в списке устройств.
На панели сведений об устройстве щелкните "Методы".
В раскрывающемся списке "Метод" выберите "ИнициироватьFirmwareUpdate", а затем в FWPACKAGEURI введите фиктивный URL-адрес. Нажмите кнопку "Вызвать метод ", чтобы вызвать метод на устройстве.
Вы увидите сообщение в консоли, где выполняется код вашего устройства, когда устройство обрабатывает метод. Результаты метода добавляются в историю на портале решений:
Дальнейшие действия
В статье о настройке предварительно настроенных решений описаны некоторые способы расширения этого примера. Возможные расширения включают использование реальных датчиков и реализацию дополнительных команд.
Вы можете узнать больше о разрешениях на сайте azureiotsuite.com.