Compartilhar via


Desenvolver um módulo do IoT Edge em C# para mover arquivos com o Azure Stack Edge Pro FPGA

Importante

Os dispositivos FPGA do Azure Stack Edge Pro atingiram o fim da vida útil em fevereiro de 2024.

Este artigo explica como criar um módulo do IoT Edge para implantação com seu dispositivo FPGA do Azure Stack Edge Pro. A FPGA do Azure Stack Edge Pro é uma solução de armazenamento que permite processar dados e enviá-los pela rede para o Azure.

Você pode usar módulos do Azure IoT Edge com sua FPGA do Azure Stack Edge Pro para transformar os dados conforme eles são movidos para o Azure. O módulo usado neste artigo implementa a lógica para copiar um arquivo de um compartilhamento local para um compartilhamento de nuvem em seu dispositivo FPGA do Azure Stack Edge Pro.

Neste artigo, você aprenderá a:

  • Crie um registro de contêiner para armazenar e gerenciar seus módulos (imagens do Docker).
  • Crie um módulo do IoT Edge para implantar em seu dispositivo FPGA do Azure Stack Edge Pro.

Sobre o módulo do IoT Edge

O dispositivo FPGA do Azure Stack Edge Pro pode implantar e executar módulos do IoT Edge. Os módulos de borda são essencialmente contêineres do Docker que executam uma tarefa específica, como ingerir uma mensagem de um dispositivo, transformar uma mensagem ou enviar uma mensagem para um Hub IoT. Neste artigo, você criará um módulo que copia arquivos de um compartilhamento local para um compartilhamento de nuvem em seu dispositivo FPGA do Azure Stack Edge Pro.

  1. Os arquivos são gravados no compartilhamento local em seu dispositivo FPGA do Azure Stack Edge Pro.
  2. O gerador de eventos de arquivo cria um evento de arquivo para cada arquivo gravado no compartilhamento local. Os eventos de arquivo também são gerados quando um arquivo é modificado. Os eventos de arquivo são então enviados para o Hub do IoT Edge (no tempo de execução do IoT Edge).
  3. O módulo personalizado do IoT Edge processa o evento de arquivo para criar um objeto de evento de arquivo que também contém um caminho relativo para o arquivo. O módulo gera um caminho absoluto usando o caminho de arquivo relativo e copia o arquivo do compartilhamento local para o compartilhamento de nuvem. Em seguida, o módulo exclui o arquivo do compartilhamento local.

Como o módulo do Azure IoT Edge funciona na FPGA do Azure Stack Edge Pro

Depois que o arquivo estiver no compartilhamento de nuvem, ele será carregado automaticamente em sua conta de Armazenamento do Azure.

Pré-requisitos

Antes de começar, verifique se você tem:

Criar um registro de contêiner

Um registro de contêiner do Azure é um registro privado do Docker no Azure, onde você pode armazenar e gerenciar suas imagens de contêiner privadas do Docker. Os dois serviços populares do Registro do Docker disponíveis na nuvem são o Registro de Contêiner do Azure e o Hub do Docker. Este artigo usa o Registro de Contêiner.

  1. Em um navegador, faça login no portal do Azure.

  2. Selecione Criar um Recurso > Contêineres > Registro de Contêiner. Clique em Criar.

  3. Fornecer:

    1. Um nome exclusivo do Registro no Azure que contém de 5 a 50 caracteres alfanuméricos.

    2. Escolha uma Assinatura .

    3. Crie um novo grupo de recursos ou escolha um existente .

    4. Selecione uma localização . Recomendamos que esse local seja o mesmo associado ao recurso do Azure Stack Edge.

    5. Alterne Usuário Administrador para Habilitar.

    6. Defina o SKU como Básico.

      Criar registro de contêiner

  4. Selecione Criar.

  5. Depois que o registro de contêiner for criado, navegue até ele e selecione as chaves do Access.

    Obter chaves de acesso

  6. Copie os valores para de servidor de logon, de nome de usuário e de senha. Você usará esses valores mais tarde para publicar a imagem do Docker no registro e adicionar as credenciais do Registro ao runtime do Azure IoT Edge.

Criar um projeto de módulo do IoT Edge

As etapas a seguir criam um projeto de módulo do IoT Edge com base no SDK do .NET Core 2.1. O projeto usa o Visual Studio Code e a extensão do Azure IoT Edge.

Criar uma nova solução

Crie um modelo de solução C# que você possa personalizar com seu próprio código.

  1. No Visual Studio Code, selecione Exibir > Paleta de Comandos para abrir a paleta de comandos do VS Code.

  2. Na paleta de comandos, insira e execute o comando Azure: entre e siga as instruções para entrar em sua conta do Azure. Se você já estiver conectado, ignore esta etapa.

  3. Na paleta de comandos, insira e execute o comando Azure IoT Edge: nova solução do IoT Edge. Na paleta de comandos, forneça as seguintes informações para criar sua solução:

    1. Selecione a pasta na qual você deseja criar a solução.

    2. Forneça um nome para sua solução ou aceite o EdgeSolution padrão.

      Criar uma nova solução 1

    3. Escolha o Módulo C# como o modelo de módulo.

    4. Substitua o nome do módulo padrão pelo nome que você deseja atribuir, nesse caso, é FileCopyModule.

      Criar uma nova solução 2

    5. Especifique o registro de contêiner que você criou na seção anterior como o repositório de imagem do primeiro módulo. Substitua localhost:5000 pelo valor do servidor de logon copiado.

      A cadeia de caracteres final é parecida com <Login server name>/<Module name>. Neste exemplo, a cadeia de caracteres é: mycontreg2.azurecr.io/filecopymodule.

      Criar uma nova solução 3

  4. Vá para Arquivo > Abrir Pasta.

    Criar uma nova solução 4

  5. Navegue e aponte para a pasta EdgeSolution que você criou anteriormente. A janela do VS Code abre o workspace da solução IoT Edge com seus cinco componentes principais. Você não edita a pasta .vscode , o arquivo .gitignore , o arquivo .env e o deployment.template.json neste artigo.

    O único componente que você modifica é a pasta de módulos. Essa pasta tem o código C# do módulo e dos arquivos do Docker para criar seu módulo como uma imagem de contêiner.

    Criar uma nova solução 5

Atualizar o módulo com código personalizado

  1. No gerenciador do VS Code, abra os módulos > Program.cs FileCopyModule>.

  2. Na parte superior do namespace FileCopyModule, adicione as instruções de uso a seguir para tipos usados posteriormente. Microsoft.Azure.Devices.Client.Transport.Mqtt é um protocolo para enviar mensagens ao Hub do IoT Edge.

    namespace FileCopyModule
    {
        using Microsoft.Azure.Devices.Client.Transport.Mqtt;
        using Newtonsoft.Json;
    
  3. Adicione a variável InputFolderPath e OutputFolderPath à classe Program.

    class Program
        {
            static int counter;
            private const string InputFolderPath = "/home/input";
            private const string OutputFolderPath = "/home/output";
    
  4. Imediatamente após a etapa anterior, adicione a classe FileEvent para definir o corpo da mensagem.

    /// <summary>
    /// The FileEvent class defines the body of incoming messages. 
    /// </summary>
    private class FileEvent
    {
        public string ChangeType { get; set; }
    
        public string ShareRelativeFilePath { get; set; }
    
        public string ShareName { get; set; }
    }
    
  5. No método Init, o código cria e configura um objeto ModuleClient. Esse objeto permite que o módulo se conecte ao runtime local do Azure IoT Edge usando o protocolo MQTT para enviar e receber mensagens. A cadeia de conexão usada no método Init é fornecida ao módulo pelo runtime do IoT Edge. O código registra um callback FileCopy para receber mensagens de um hub IoT Edge via o endpoint input1. Substitua o método Init pelo código a seguir.

    /// <summary>
    /// Initializes the ModuleClient and sets up the callback to receive
    /// messages containing file event information
    /// </summary>
    static async Task Init()
    {
        MqttTransportSettings mqttSetting = new MqttTransportSettings(TransportType.Mqtt_Tcp_Only);
        ITransportSettings[] settings = { mqttSetting };
    
        // Open a connection to the IoT Edge runtime
        ModuleClient ioTHubModuleClient = await ModuleClient.CreateFromEnvironmentAsync(settings);
        await ioTHubModuleClient.OpenAsync();
        Console.WriteLine("IoT Hub module client initialized.");
    
        // Register callback to be called when a message is received by the module
        await ioTHubModuleClient.SetInputMessageHandlerAsync("input1", FileCopy, ioTHubModuleClient);
    }
    
  6. Remova o código do método PipeMessage e, em seu lugar, insira o código de FileCopy .

        /// <summary>
        /// This method is called whenever the module is sent a message from the IoT Edge Hub.
        /// This method deserializes the file event, extracts the corresponding relative file path, and creates the absolute input file path using the relative file path and the InputFolderPath.
        /// This method also forms the absolute output file path using the relative file path and the OutputFolderPath. It then copies the input file to output file and deletes the input file after the copy is complete.
        /// </summary>
        static async Task<MessageResponse> FileCopy(Message message, object userContext)
        {
            int counterValue = Interlocked.Increment(ref counter);
    
            try
            {
                byte[] messageBytes = message.GetBytes();
                string messageString = Encoding.UTF8.GetString(messageBytes);
                Console.WriteLine($"Received message: {counterValue}, Body: [{messageString}]");
    
                if (!string.IsNullOrEmpty(messageString))
                {
                    var fileEvent = JsonConvert.DeserializeObject<FileEvent>(messageString);
    
                    string relativeFileName = fileEvent.ShareRelativeFilePath.Replace("\\", "/");
                    string inputFilePath = InputFolderPath + relativeFileName;
                    string outputFilePath = OutputFolderPath + relativeFileName;
    
                    if (File.Exists(inputFilePath))                
                    {
                        Console.WriteLine($"Moving input file: {inputFilePath} to output file: {outputFilePath}");
                        var outputDir = Path.GetDirectoryName(outputFilePath);
                        if (!Directory.Exists(outputDir))
                        {
                            Directory.CreateDirectory(outputDir);
                        }
    
                        File.Copy(inputFilePath, outputFilePath, true);
                        Console.WriteLine($"Copied input file: {inputFilePath} to output file: {outputFilePath}");
                        File.Delete(inputFilePath);
                        Console.WriteLine($"Deleted input file: {inputFilePath}");
                    } 
                    else
                    {
                        Console.WriteLine($"Skipping this event as input file doesn't exist: {inputFilePath}");   
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Caught exception: {0}", ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
    
            Console.WriteLine($"Processed event.");
            return MessageResponse.Completed;
        }
    
  7. Salve este arquivo.

  8. Você pode também baixar um exemplo de código existente para este projeto. Em seguida, você pode validar o arquivo que salvou com o arquivo program.cs deste exemplo.

Criar sua solução do IoT Edge

Na seção anterior, você criou uma solução do IoT Edge e adicionou código ao FileCopyModule para copiar arquivos do compartilhamento local para o compartilhamento de nuvem. Agora você precisa construir a solução como uma imagem de contêiner e enviá-la para o registro de imagens de contêiner.

  1. No VSCode, acesse Terminal > Novo Terminal para abrir um novo terminal integrado do Visual Studio Code.

  2. Entre no Docker inserindo o seguinte comando no terminal integrado.

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

    Use o servidor de logon e o nome de usuário que você copiou do registro de contêiner.

    Criar e publicar solução IoT Edge

  3. Quando solicitado a fornecer a senha, forneça a senha. Você também pode recuperar os valores do servidor de logon, nome de usuário e senha nas Chaves de Acesso no registro de contêiner no portal do Azure .

  4. Depois que as credenciais forem fornecidas, você poderá enviar a imagem do módulo por push para o registro de contêiner do Azure. No Explorador do VS Code, clique com o botão direito do mouse no arquivo module.json e selecione Compilar e Enviar solução IoT Edge.

    Compilar e enviar a solução 2 do IoT Edge

    Quando você pede para o Visual Studio Code compilar sua solução, ele executa dois comandos no terminal integrado: docker build e docker push. Esses dois comandos criam seu código, armazenam o CSharpModule.dllem contêiner e, em seguida, enviam o código por push para o registro de contêiner especificado quando você inicializou a solução.

    Você será solicitado a escolher a plataforma do módulo. Selecione amd64 correspondente ao Linux.

    Selecionar plataforma

    Importante

    Somente os módulos do Linux têm suporte.

    Você pode ver o seguinte aviso que pode ignorar:

    Program.cs(77,44): aviso CS1998: este método assíncrono não tem operadores 'await' e será executado de forma síncrona. Considere usar o operador 'await' para aguardar chamadas à API sem bloqueio ou 'await Task.Run(...)' para realizar o trabalho associado à CPU em um thread em segundo plano.

  5. Você pode ver o endereço completo da imagem do contêiner com tag no terminal integrado do VS Code. O endereço da imagem é criado a partir de informações que estão no arquivo module.json com o formato <repository>:<version>-<platform>. Para este artigo, ele deve se parecer com mycontreg2.azurecr.io/filecopymodule:0.0.1-amd64.

Próximas etapas

Para implantar e executar este módulo no Azure Stack Edge Pro FPGA, consulte as etapas em Adicionar um módulo.