Condividi tramite


Sviluppare un modulo IoT Edge C# per spostare file con Azure Stack Edge Pro FPGA

Importante

I dispositivi FPGA di Azure Stack Edge Pro hanno raggiunto la fine della vita a febbraio 2024.

Questo articolo illustra come creare un modulo IoT Edge per la distribuzione con il dispositivo AZURE Stack Edge Pro FPGA. Azure Stack Edge Pro FPGA è una soluzione di archiviazione che consente di elaborare i dati e inviarli in rete ad Azure.

È possibile usare i moduli azure IoT Edge con il fpga di Azure Stack Edge Pro per trasformare i dati durante lo spostamento in Azure. Il modulo usato in questo articolo implementa la logica per copiare un file da una condivisione locale a una condivisione cloud nel dispositivo AZURE Stack Edge Pro FPGA.

Questo articolo illustra come:

  • Creare un registro contenitori per archiviare e gestire i moduli (immagini Docker).
  • Creare un modulo IoT Edge da distribuire nel dispositivo AZURE Stack Edge Pro FPGA.

Informazioni sul modulo IoT Edge

Il dispositivo AZURE Stack Edge Pro FPGA può distribuire ed eseguire moduli IoT Edge. I moduli Edge sono essenzialmente contenitori Docker che eseguono un'attività specifica, ad esempio inserire un messaggio da un dispositivo, trasformare un messaggio o inviare un messaggio a un hub IoT. In questo articolo si creerà un modulo che copia i file da una condivisione locale a una condivisione cloud nel dispositivo Azure Stack Edge Pro FPGA.

  1. I file vengono scritti nella condivisione locale nel dispositivo FPGA di Azure Stack Edge Pro.
  2. Il generatore di eventi di file crea un evento di file per ogni file scritto nella condivisione locale. Gli eventi di file vengono generati anche quando viene modificato un file. Gli eventi di file vengono quindi inviati all'hub IoT Edge (nell'ambiente runtime di IoT Edge).
  3. Il modulo personalizzato IoT Edge elabora l'evento file per creare un oggetto evento file che contiene anche un percorso relativo per il file. Il modulo genera un percorso assoluto usando il percorso del file relativo e copia il file dalla condivisione locale alla condivisione cloud. Il modulo elimina quindi il file dalla condivisione locale.

Funzionamento del modulo Azure IoT Edge in Azure Stack Edge Pro FPGA

Una volta che il file si trova nella condivisione cloud, viene caricato automaticamente nell'account di archiviazione di Azure.

Prerequisiti

Prima di iniziare, assicurarsi di avere:

Creare un registro di container

Un registro Azure Container è un registro Docker privato in Azure in cui è possibile archiviare e gestire le immagini dei contenitori Docker private. I due servizi di registro Docker più diffusi disponibili nel cloud sono Registro Azure Container e Docker Hub. Questo articolo usa il Container Registry.

  1. Da un browser, accedi al portale di Azure .

  2. Selezionare Crea una risorsa > Contenitori > Registro dei Contenitori. Fare clic su Crea.

  3. Fornire:

    1. Nome univoco del Registro di sistema in Azure che contiene da 5 a 50 caratteri alfanumerici.

    2. Scegli un abbonamento .

    3. Crea nuovo o scegli un gruppo di risorse esistente.

    4. Selezionare una posizione. È consigliabile che questa ubicazione sia uguale a quella associata alla risorsa Azure Stack Edge.

    5. Imposta utente amministratore su Abilita.

    6. Imposta lo SKU su Basic.

      Creare registro dei container

  4. Selezionare Crea.

  5. Dopo aver creato il registro contenitori, passare a esso e selezionare Chiavi di accesso.

    Ottenere le chiavi di accesso

  6. Copiare i valori per Server di accesso, Nome utente e Password. Questi valori verranno usati in un secondo momento per pubblicare l'immagine Docker nel registro e per aggiungere le credenziali del Registro di sistema al runtime di Azure IoT Edge.

Creare un progetto di modulo IoT Edge

La procedura seguente crea un progetto di modulo IoT Edge basato su .NET Core 2.1 SDK. Il progetto usa Visual Studio Code e l'estensione Azure IoT Edge.

Creare una nuova soluzione

Creare un modello di soluzione C# che è possibile personalizzare con il proprio codice.

  1. In Visual Studio Code selezionare Visualizza > Palette comandi per aprire la palette comandi di VS Code.

  2. Nel riquadro comandi immettere ed eseguire il comando Azure: Accedi e seguire le istruzioni per accedere all'account Azure. Se è già stato eseguito l'accesso, è possibile ignorare questo passaggio.

  3. Nel riquadro comandi immettere ed eseguire il comando Azure IoT Edge: Nuova soluzione IoT Edge. Nel riquadro comandi specificare le informazioni seguenti per creare la soluzione:

    1. Selezionare la cartella in cui si vuole creare la soluzione.

    2. Specificare un nome per la soluzione o accettare l'impostazione predefinita EdgeSolution.

      Creare una nuova soluzione 1

    3. Scegliere Modulo C# come modello di modulo.

    4. Sostituire il nome predefinito del modulo con il nome da assegnare, in questo caso FileCopyModule.

      Creare una nuova soluzione 2

    5. Specificare il registro contenitori creato nella sezione precedente come repository di immagini per il primo modulo. Sostituire localhost:5000 con il valore del server di accesso copiato.

      La stringa finale è simile a <Login server name>/<Module name>. In questo esempio la stringa è: mycontreg2.azurecr.io/filecopymodule.

      Creare una nuova soluzione 3

  4. Passare a File > Apri cartella.

    Creare una nuova soluzione 4

  5. Sfogliare e puntare alla cartella EdgeSolution che hai creato in precedenza. La finestra di VS Code carica l'area di lavoro della soluzione IoT Edge con i cinque componenti di primo livello. Non si modificherà la cartella vscode , il file con estensione gitignore , il file con estensione env e il deployment.template.json in questo articolo.

    L'unico componente modificato è la cartella modules. Questa cartella include il codice C# per il modulo e i file Docker per compilare il modulo come immagine del contenitore.

    Creare una nuova soluzione 5

Aggiornare il modulo con codice personalizzato

  1. Nello strumento di esplorazione di VS Code aprire i moduli > FileCopyModule > Program.cs.

  2. Nella parte superiore dello spazio dei nomi FileCopyModule, aggiungere le seguenti istruzioni using per i tipi che saranno utilizzati successivamente. Microsoft.Azure.Devices.Client.Transport.Mqtt è un protocollo per inviare messaggi all'hub IoT Edge.

    namespace FileCopyModule
    {
        using Microsoft.Azure.Devices.Client.Transport.Mqtt;
        using Newtonsoft.Json;
    
  3. Aggiungere la variabile InputFolderPath e OutputFolderPath alla classe Program.

    class Program
        {
            static int counter;
            private const string InputFolderPath = "/home/input";
            private const string OutputFolderPath = "/home/output";
    
  4. Subito dopo il passaggio precedente, aggiungere la classe FileEvent per definire il corpo del messaggio.

    /// <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. Nel metodo Init il codice crea e configura un oggetto ModuleClient . Questo oggetto consente al modulo di connettersi al runtime locale di Azure IoT Edge usando il protocollo MQTT per inviare e ricevere messaggi. La stringa di connessione usata nel metodo Init viene fornita al modulo dal runtime di IoT Edge. Il codice registra un callback di FileCopy per ricevere messaggi da un hub IoT Edge tramite l'endpoint input1 . Sostituire il metodo Init con il codice seguente.

    /// <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. Rimuovere il codice per il metodo PipeMessage e, al suo posto, inserire il codice per 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. Salvare il file.

  8. È anche possibile scaricare un esempio di codice esistente per questo progetto. È quindi possibile convalidare il file salvato rispetto al file program.cs in questo esempio.

Creare la soluzione IoT Edge

Nella sezione precedente è stata creata una soluzione IoT Edge e è stato aggiunto codice a FileCopyModule per copiare i file dalla condivisione locale alla condivisione cloud. Ora devi creare un'immagine del contenitore per la soluzione e caricarla nel tuo registro contenitori.

  1. In VSCode passare a Terminale > Nuovo terminale per aprire un nuovo terminale integrato di Visual Studio Code.

  2. Accedere a Docker immettendo il comando seguente nel terminale integrato.

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

    Usare il server di login e il nome utente copiati dal registro del contenitore.

    Creare ed eseguire il push della soluzione IoT Edge

  3. Quando viene richiesta la password, specificare la password. È anche possibile recuperare i valori per il server di accesso, il nome utente e la password dalle chiavi di accesso nel registro contenitori nel portale di Azure.

  4. Dopo aver specificato le credenziali, è possibile eseguire il push dell'immagine del modulo nel registro Azure Container. In Esplora risorse di VS Code, fare clic con il pulsante destro del mouse sul file di module.json e selezionare Compila ed Esegui il push della soluzione IoT Edge.

    Compilare ed eseguire il push della soluzione IoT Edge 2

    Quando si indica a Visual Studio Code di compilare la soluzione, vengono eseguiti due comandi nel terminale integrato: docker build e docker push. Questi due comandi compilano il codice, inseriscono in contenitori il CSharpModule.dlle quindi esemettono il codice nel registro contenitori specificato durante l'inizializzazione della soluzione.

    Verrà richiesto di scegliere la piattaforma del modulo. Selezionare amd64 corrispondente a Linux.

    Selezionare la piattaforma

    Importante

    Sono supportati solo i moduli Linux.

    È possibile che venga visualizzato l'avviso seguente che è possibile ignorare:

    Program.cs(77,44): avviso CS1998: questo metodo asincrono non dispone degli operatori 'await' e verrà eseguito in modo sincrono. È consigliabile usare l'operatore 'await' per attendere chiamate API non bloccate o 'await Task.Run(...)' per eseguire operazioni associate alla CPU in un thread in background.

  5. È possibile visualizzare l'indirizzo completo dell'immagine del contenitore con tag nel terminale integrato di VS Code. L'indirizzo dell'immagine viene compilato da informazioni contenute nel file module.json con il formato <repository>:<version>-<platform>. Per questo articolo, dovrebbe apparire come mycontreg2.azurecr.io/filecopymodule:0.0.1-amd64.

Passaggi successivi

Per distribuire ed eseguire questo modulo in Azure Stack Edge Pro FPGA, vedere la procedura descritta in Aggiungere un modulo.