Учебник. Разработка модуля IoT Edge на C# с использованием контейнеров Linux

Применяется к:IoT Edge 1.1. Флажок IoT Edge 1.1 IoT Edge 1.2 IoT Edge 1.2 IoT Edge 1.3 IoT Edge 1.3 IoT Edge 1.4 IoT Edge 1.4

Разработайте и разверните код C# на устройствах с Azure IoT Edge с помощью Visual Studio Code.

Вы можете использовать модули Azure IoT Edge для развертывания кода, который реализует бизнес-логику непосредственно на устройствах IoT Edge. В этом руководстве рассматриваются создание и развертывание модуля IoT Edge, который фильтрует данные датчика. Вы используете имитированное устройство IoT Edge, созданное при изучении кратких руководств. В этом руководстве описано следующее:

  • Используйте Visual Studio Code, чтобы создать модуль IoT Edge на основе пакета SDK для .NET Core.
  • Использовать Visual Studio Code и Docker для создания образа Docker и его публикации в реестре.
  • Развертывать модуль на устройстве IoT Edge.
  • Просматривать сформированные данные.

Модуль IoT Edge, создаваемый в этом руководстве, фильтрует данные температуры, которые создаются устройством. Оно отправляет сообщения, только если температура превышает заданное пороговое значение. Такой тип пограничного анализа удобен для сокращения объема данных, передаваемых в облако и сохраняемых в нем.

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

Предварительные требования

В этом учебнике описана разработка модуля на C# с помощью Visual Studio Code и его развертывание на устройстве IoT Edge. Если вы разрабатываете модули с использованием контейнеров Windows, перейдите к статье Разработка модуля IoT Edge на C# с использованием контейнеров Windows.

В приведенной ниже таблице приведены возможные варианты для разработки и развертывания модулей C# с использованием контейнеров Linux:

C# Visual Studio Code Visual Studio
Linux AMD64 Модули C# для LinuxAMD64 в VS Code Модули C# для LinuxAMD64 в Visual Studio
Linux ARM32 Модули C# для LinuxARM32 в VS Code Модули C# для LinuxARM32 в Visual Studio
Linux ARM64 Модули C# для LinuxARM64 в VS Code Модули C# для LinuxARM64 в Visual Studio

Перед началом работы с этим учебником вы должны были настроить среду разработки, выполнив инструкции, приведенные в этой статье. После работы с этим руководством у вас должны быть готовы все необходимые компоненты:

Для работы с этими учебниками подготовьте дополнительные необходимые компоненты на компьютере для разработки:

Создание проекта модуля

Описанный ниже процесс позволяет создать проект модуля IoT Edge для языка C# с использованием Visual Studio Code и расширения Azure IoT Tools. После создания шаблона проекта добавьте новый код, чтобы модуль фильтровал сообщения по их сообщаемым свойствам.

Создание нового проекта

Создайте шаблон решения C#, который можно настроить с помощью собственного кода.

  1. В Visual Studio Code выберите Представление>Палитра команд для открытия палитры команд VS Code.

  2. В палитре команд введите и выполните команду Azure: Sign in (Azure: войти). Следуйте инструкциям, чтобы войти в свою учетную запись Azure. Если вход был выполнен, то этот шаг можно пропустить.

  3. В палитре команд введите и выполните команду Azure IoT Edge: New IoT Edge Solution (Azure IoT Edge: создать решение IoT Edge). Следуйте инструкциям на экране в палитре команд для создания решения.

    Поле Значение
    Выбор папки Выберите расположение на компьютере разработчика для VS Code, чтобы создать файлы решения.
    Введите название решения. Введите описательное имя решения или примите имя по умолчанию EdgeSolution.
    Выбор шаблона модуля Выберите модуль C# .
    Указание имени модуля Присвойте модулю имя CSharpModule.
    Указание репозитория изображений Docker для модуля Репозиторий изображений включает в себя имя реестра контейнеров и имя образа контейнера. Образ контейнера предварительно заполняется именем, которое вы указали на последнем шаге. Замените localhost:5000 значением сервера входа из реестра контейнеров Azure. Вы можете узнать сервер входа на странице "Обзор" реестра контейнеров на портале Azure.

    Окончательный репозиторий образа выглядит так: <имя_регистра>.azurecr.io/csharpmodule.

    Выбор репозитория образа Docker

Добавление учетных данных реестра

Файл среды хранит учетные данные для реестра контейнеров и совместно использует их со средой выполнения IoT Edge. Среде выполнения нужны эти учетные данные, чтобы извлечь частный образ на устройство IoT Edge. Используйте учетные данные из раздела Ключи доступа в реестре контейнеров Azure.

Расширение IoT Edge пытается извлечь учетные данные реестра контейнеров из Azure и заполнить их в файле среды. Проверьте, включены ли ваши учетные данные. В противном случае добавьте их:

  1. Откройте в обозревателе VS Code файл с расширением ENV.
  2. Обновите поля, указав имя пользователя и пароль, скопированные из реестра контейнера Azure.
  3. Сохраните этот файл.

Примечание

При работе с этим руководством используются учетные данные администратора для Реестра контейнеров Azure, что удобно для сценариев разработки и тестирования. Но после перехода в рабочую среду рекомендуется использовать для проверки подлинности вариант с минимальными правами, например субъект-службу. Дополнительные сведения см. в разделе Управление доступом к реестру контейнеров.

Выбор целевой архитектуры

Сейчас Visual Studio Code позволяет разрабатывать модули C# для устройств Linux AMD64 и Linux ARM32v7. Для каждого решения вам нужно выбрать одну целевую платформу, так как сборка и запуск контейнера для разных архитектур различается. По умолчанию используется Linux AMD64.

  1. Откройте палитру команд и выполните поиск Azure IoT Edge: Set Default Target Platform for Edge Solution (Azure IoT Edge: установить целевую платформу по умолчанию для решения Edge) или выберите значок ярлыка на боковой панели в нижней части окна.

  2. В палитре команд выберите целевую архитектуру из списка параметров. В рамках этого руководства мы используем в качестве устройства IoT Edge виртуальную машину Ubuntu. Поэтому сохраним значение по умолчанию amd64.

Обновление модуля с помощью пользовательского кода

  1. В обозревателе VS Code выберите modules>NodeModule>app.js.

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

    using System.Collections.Generic;     // For KeyValuePair<>
    using Microsoft.Azure.Devices.Shared; // For TwinCollection
    using Newtonsoft.Json;                // For JsonConvert
    
  3. Добавьте переменную temperatureThreshold к классу Program. Эта переменная устанавливает значение, которое должно быть измеренной температурой, чтобы данные были отправлены в Центр Интернета вещей.

    static int temperatureThreshold { get; set; } = 25;
    
  4. Добавьте MessageBody, Machine и Ambient к классу Program. Эти классы определяют ожидаемую схему текста входящего сообщения.

    class MessageBody
    {
        public Machine machine {get;set;}
        public Ambient ambient {get; set;}
        public string timeCreated {get; set;}
    }
    class Machine
    {
        public double temperature {get; set;}
        public double pressure {get; set;}
    }
    class Ambient
    {
        public double temperature {get; set;}
        public int humidity {get; set;}
    }
    
  5. Найдите функцию Init. Эта функция создает и настраивает объект ModuleClient, позволяющий модулю подключаться к локальной среде выполнения Azure IoT Edge для отправки и получения сообщений. После создания ModuleClient код считывает значение temperatureThreshold из требуемых свойств двойника модуля. Этот код регистрирует обратный вызов для получения сообщений из центра IoT Edge через конечную точку input1.

    Замените метод SetInputMessageHandlerAsync новым методом, который обновляет им конечной точки, и методом, который вызывается при получении входных данных. Также добавьте метод SetDesiredPropertyUpdateCallbackAsync для обновления нужных свойств. Чтобы внести это изменение, замените последнюю строку метода Init следующим кодом:

    // Register a callback for messages that are received by the module.
    // await ioTHubModuleClient.SetInputMessageHandlerAsync("input1", PipeMessage, iotHubModuleClient);
    
    // Read the TemperatureThreshold value from the module twin's desired properties
    var moduleTwin = await ioTHubModuleClient.GetTwinAsync();
    await OnDesiredPropertiesUpdate(moduleTwin.Properties.Desired, ioTHubModuleClient);
    
    // Attach a callback for updates to the module twin's desired properties.
    await ioTHubModuleClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertiesUpdate, null);
    
    // Register a callback for messages that are received by the module. Messages received on the inputFromSensor endpoint are sent to the FilterMessages method.
    await ioTHubModuleClient.SetInputMessageHandlerAsync("inputFromSensor", FilterMessages, ioTHubModuleClient);
    
  6. Добавьте метод onDesiredPropertiesUpdate к классу Program. Этот метод принимает изменения требуемых свойств из двойника модуля и соответствующим образом изменяет переменную temperatureThreshold. У каждого модуля есть собственный модуль-двойник, что позволяет настроить код, выполняемый в модуле, непосредственно из облака.

    static Task OnDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext)
    {
        try
        {
            Console.WriteLine("Desired property change:");
            Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));
    
            if (desiredProperties["TemperatureThreshold"]!=null)
                temperatureThreshold = desiredProperties["TemperatureThreshold"];
    
        }
        catch (AggregateException ex)
        {
            foreach (Exception exception in ex.InnerExceptions)
            {
                Console.WriteLine();
                Console.WriteLine("Error when receiving desired property: {0}", exception);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error when receiving desired property: {0}", ex.Message);
        }
        return Task.CompletedTask;
    }
    
  7. Замените метод PipeMessage методом FilterMessages. Этот метод вызывается каждый раз, когда модуль получает сообщение из центра IoT Edge. Он отфильтровывает сообщения о температуре ниже порогового значения, настроенного с помощью двойника модуля. Он также добавляет свойство MessageType в сообщение со значением Alert.

    static async Task<MessageResponse> FilterMessages(Message message, object userContext)
    {
        var counterValue = Interlocked.Increment(ref counter);
        try
        {
            ModuleClient moduleClient = (ModuleClient)userContext;
            var messageBytes = message.GetBytes();
            var messageString = Encoding.UTF8.GetString(messageBytes);
            Console.WriteLine($"Received message {counterValue}: [{messageString}]");
    
            // Get the message body.
            var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
            if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
            {
                Console.WriteLine($"Machine temperature {messageBody.machine.temperature} " +
                    $"exceeds threshold {temperatureThreshold}");
                using (var filteredMessage = new Message(messageBytes))
                {
                    foreach (KeyValuePair<string, string> prop in message.Properties)
                    {
                        filteredMessage.Properties.Add(prop.Key, prop.Value);
                    }
    
                    filteredMessage.Properties.Add("MessageType", "Alert");
                    await moduleClient.SendEventAsync("output1", filteredMessage);
                }
            }
    
            // Indicate that the message treatment is completed.
            return MessageResponse.Completed;
        }
        catch (AggregateException ex)
        {
            foreach (Exception exception in ex.InnerExceptions)
            {
                Console.WriteLine();
                Console.WriteLine("Error in sample: {0}", exception);
            }
            // Indicate that the message treatment is not completed.
            var moduleClient = (ModuleClient)userContext;
            return MessageResponse.Abandoned;
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error in sample: {0}", ex.Message);
            // Indicate that the message treatment is not completed.
            ModuleClient moduleClient = (ModuleClient)userContext;
            return MessageResponse.Abandoned;
        }
    }
    
  8. Сохраните файл Program.cs.

  9. В обозревателе VS Code откройте файл deployment.template.json в рабочей области решения IoT Edge.

  10. Так как мы изменили имя конечной точки, которую прослушивает модуль, нам также нужно обновить маршруты в манифесте развертывания, чтобы edgeHub отправлял сообщения в новую конечную точку.

    Найдите раздел routes в двойнике модуля $edgeHub. Обновите маршрут sensorToCSharpModule, заменив input1 на inputFromSensor:

    "sensorToCSharpModule": "FROM /messages/modules/SimulatedTemperatureSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/CSharpModule/inputs/inputFromSensor\")"
    
  11. Добавьте двойник модуля CSharpModule в манифест развертывания. Вставьте следующее содержимое JSON в нижней части раздела modulesContent после двойника модуля $edgeHub:

       "CSharpModule": {
           "properties.desired":{
               "TemperatureThreshold":25
           }
       }
    

    Добавление двойника модуля в шаблон развертывания

  12. Сохраните файл deployment.template.json.

Сборка и отправка модуля

В предыдущем разделе вы создали решение IoT Edge и добавили код в модуль CSharpModule. Новый код отфильтровывает сообщения в тех случаях, когда заявленная температура машины находится в допустимых пределах. Теперь необходимо создать решение в качестве образа контейнера и передать его в реестр контейнеров.

  1. Откройте интегрированный терминал VS Code, выбрав Вид>Терминал.

  2. Войдите в Docker. Для этого введите представленную ниже команду в окне терминала. Выполните вход в систему, используя имя пользователя, пароль и сервер входа из реестра контейнеров Azure. Вы можете получить эти значения в разделе Ключи доступа в разделе реестра на портале Azure.

    docker login -u <ACR username> -p <ACR password> <ACR login server>
    

    Возможно, появится предупреждение системы безопасности, в котором рекомендуется использовать --password-stdin. Для рабочих сценариев это лучшая методика, но мы не будем рассматривать ее в этом учебнике. Дополнительные сведения см. в описании команды docker login в справочнике.

  3. В обозревателе VS Code щелкните правой кнопкой мыши файл deployment.template.json и выберите Build and Push IoT Edge Solution (Создать и отправить решение IoT Edge).

    Эта команда сборки и отправки позволяет запустить три операции. Во-первых,в решении создается папка с именем config, которая содержит полный манифест развертывания на основе информации из шаблона развертывания и других файлов решения. Во-вторых, выполняется docker build для сборки образа контейнера на основе подходящего файла dockerfile для целевой архитектуры. В-третьих, выполняется docker push для отправки образа в реестр контейнеров.

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

Развертывание и запуск решения

Разверните проект модуля на устройстве IoT Edge с помощью обозревателя Visual Studio Code и расширения Azure IoT Tools. У вас уже есть манифест развертывания, подготовленный для вашего сценария (файл deployment.amd64.json в папке config). Теперь вам осталось выбрать устройство для получения развертывания.

Убедитесь, что устройство IoT Edge работает.

  1. В обозревателе Visual Studio Code в разделе Центр Интернета вещей Azure разверните меню Устройства, чтобы отобразить список устройств Интернета вещей.

  2. Щелкните имя устройства IoT Edge правой кнопкой мыши, а затем выберите Create Deployment for Single Device (Создание развертывания для одного устройства).

  3. Выберите файл deployment.amd64.json в папке config и щелкните Select Edge Deployment Manifest (Выбрать манифест развертывания Edge). Не используйте файл deployment.template.json.

  4. Разверните меню Модули для своего устройства, чтобы просмотреть список развернутых и запущенных модулей. Нажмите кнопку "Обновить". Появится новый запущенный модуль CSharpFunction, модуль SimulatedTemperatureSensor, а также $edgeAgent и $edgeHub.

    На запуск модулей может потребоваться несколько минут. Среда выполнения IoT Edge должна получить новый манифест развертывания, извлечь образы модулей из среды выполнения контейнеров, а затем запустить каждый новый модуль.

Просмотр сформированных данных

Когда вы примените манифест развертывания к устройству IoT Edge, в среде выполнения IoT Edge на устройстве начнется сбор сведений о новом развертывании и выполнение операций. Работа всех выполняющихся на устройстве модулей, которые не включены в манифест развертывания, будет остановлена. А модули, которых нет на устройстве, будут запущены.

  1. В обозревателе Visual Studio Code щелкните имя устройства IoT Edge правой кнопкой мыши и выберите Start Monitoring Built-in Event Endpoint (Начать мониторинг строенной конечной точки событий).

  2. Просмотрите сообщения, поступающие в Центр Интернета вещей. Для поступления сообщений может потребоваться некоторое время, так как устройство IoT Edge должно сначала получить новое развертывание и запустить все модули. После этого измененный нами код CModule ожидает, пока температура компьютера не достигнет 25 градусов, и лишь затем отправляет сообщения. С помощью кода также присваивается тип Оповещение всем сообщениям со сведениями о достижении порога температуры.

    Просмотр поступающих сообщений в Центре Интернета вещей

Изменение двойника модуля

Мы использовали в манифесте развертывания двойник модуля CSharpModule, чтобы задать порог температуры 25 градусов. С помощью двойника модуля вы можете изменять функциональные возможности без необходимости обновлять код модуля.

  1. В Visual Studio Code разверните окно подробных сведений об устройстве IoT Edge, чтобы просмотреть список выполняющихся модулей.

  2. Щелкните CSharpModule правой кнопкой мыши и выберите Edit module twin (Изменить двойник модуля).

  3. В списке требуемых свойств найдите TemperatureThreshold. Измените его значение, увеличив температуру на 5 или 10 градусов относительно последней сообщаемой температуры.

  4. Сохраните файл двойника модуля.

  5. Щелкните правой кнопкой мыши в любой точки на панели редактирования двойника модуля и выберите Update module twin (Обновление двойника модуля).

  6. Выполните мониторинг сообщений, поступающих с устройства в облако. Вы увидите, что поток сообщений прекратится, пока не будет достигнут новый порог температуры.

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

Если вы планируете перейти к следующей рекомендуемой статье, можно сохранить созданные и повторно используемые ресурсы и конфигурации. Это же устройство IoT Edge также можно использовать в качестве тестового устройства.

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

Удаление ресурсов Azure

Удаление ресурсов Azure и групп ресурсов является необратимым. Будьте внимательны, чтобы случайно не удалить не ту группу ресурсов или не те ресурсы. Если вы создали центр Интернета вещей в группе ресурсов, содержащей ресурсы, которые нужно сохранить, удалите только ресурс Центра Интернета вещей, не удаляя всю группу ресурсов.

Удаление ресурсов:

  1. Войдите на портал Azure и щелкните Группы ресурсов.

  2. Выберите группу ресурсов, содержащую тестовые ресурсы IoT Edge.

  3. Просмотрите список ресурсов, содержащихся в группе ресурсов. Если вы хотите удалить их все, щелкните Удалить группу ресурсов. Если вы хотите удалить только некоторые из них, щелкните нужные ресурсы отдельно.

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

В этом руководстве вы создали модуль IoT Edge, который содержит код для фильтрации необработанных данных, созданных вашим устройством IoT Edge.

Перейдите к следующим руководствам, чтобы узнать, как Azure IoT Edge поможет развернуть облачные службы Azure для обработки данных на пограничном устройстве.