Dela via


Självstudie: Skapa och distribuera anpassade IoT Edge-moduler

gäller för:ja-ikonen IoT Edge 1.1

Viktigt!

IoT Edge 1.1 supportdatumet upphör var den 13 december 2022. I informationen om Microsoft-produktens livscykel hittar du fler uppgifter om vilken support som gäller för denna produkt, tjänst, teknik eller detta API. Mer information om hur du uppdaterar till den senaste versionen av IoT Edge finns i Uppdatera IoT Edge-.

I den här artikeln skapar vi tre IoT Edge-moduler som tar emot meddelanden från underordnade IoT-enheter, kör data via din maskininlärningsmodell och vidarebefordrar sedan insikter till IoT Hub.

IoT Edge-hubben underlättar modul-till-modulkommunikation. Om du använder IoT Edge-hubben som meddelandekö hålls modulerna oberoende av varandra. Moduler behöver bara ange de indata som de accepterar meddelanden och de utdata som de skriver meddelanden till.

Vi vill att IoT Edge-enheten ska utföra fyra saker åt oss:

  • Ta emot data från nedströmsenheterna.
  • Förutse återstående livslängd (RUL) för enheten som skickade data.
  • Skicka ett meddelande med RUL för enheten till IoT Hub. Den här funktionen kan bara ändras för att skicka data om RUL sjunker under en angiven nivå.
  • Spara underordnade enhetsdata i en lokal fil på IoT Edge-enheten. Den här datafilen laddas regelbundet upp till IoT Hub för att förfina träningen av maskininlärningsmodellen. Det är mer kostnadseffektivt att använda filuppladdning i stället för konstant meddelandeströmning.

För att utföra dessa uppgifter använder vi tre anpassade moduler:

  • RUL-klassificerare: Modulen turboFanRulClassifier som vi skapade i Träna och distribuera en Azure Machine Learning-modell är en standardmodul för maskininlärning som exponerar indata som kallas "amlInput" och utdata som kallas "amlOutput". "amlInput" förväntar sig att dess indata ser exakt ut som de indata som vi skickade till den ACI-baserade webbtjänsten. På samma sätt returnerar "amlOutput" samma data som webbtjänsten.

  • Avro-författare: Den här modulen tar emot meddelanden om "avroModuleInput"-indata och bevarar meddelandet i Avro-format till disken för senare uppladdning till IoT Hub.

  • Routermodul: Routermodulen tar emot meddelanden från underordnade enheter, formaterar och skickar sedan meddelanden till klassificeraren. Modulen tar sedan emot meddelandena från klassificeraren och vidarebefordrar meddelandet till Modulen Avro-skrivare. Slutligen skickar modulen bara RUL-förutsägelsen till IoT Hub.

    • Ingångar:

      • deviceInput: tar emot meddelanden från underordnade enheter
      • rulInput: tar emot meddelanden från "amlOutput"
    • Utgångar:

      • classify: skickar meddelanden till "amlInput"
      • writeAvro: skickar meddelanden till "avroModuleInput"
      • toIotHub: skickar meddelanden till $upstream, som skickar meddelandena till den anslutna IoT Hub

Följande diagram visar moduler, indata, utdata och IoT Edge Hub-vägarna för den fullständiga lösningen:

Arkitekturdiagram för tre moduler i IoT Edge

Stegen i den här artikeln utförs vanligtvis av en molnutvecklare.

I det här avsnittet av självstudien lär du dig att:

  • Skapa en IoT Edge-modul från anpassad kod.
  • Generera en Docker-avbildning från din anpassade modul.
  • Konfigurera om IoT Hub-routning för att stödja dina anpassade moduler.
  • Skapa, publicera och distribuera dina anpassade moduler.

Förutsättningar

Den här artikeln är en del av en serie för en självstudie om hur du använder Azure Machine Learning på IoT Edge. Varje artikel i serien bygger på arbetet i föregående artikel. Om du har kommit direkt till den här artikeln kan du gå till den första artikeln i serien.

Skapa en ny IoT Edge-lösning

Under körningen av den andra av våra två Azure Notebooks skapade och publicerade vi en containeravbildning som innehåller vår RUL-modell. Azure Machine Learning paketerade modellen som en del av avbildningsprocessen så att avbildningen kan distribueras som en Azure IoT Edge-modul.

I det här steget ska vi skapa en Azure IoT Edge-lösning med hjälp av modulen "Azure Machine Learning" och rikta modulen mot den bild som vi publicerade med hjälp av Azure Notebooks.

  1. Öppna en fjärrskrivbordssession på den virtuella utvecklingsdatorn.

  2. Öppna mappen C:\source\IoTEdgeAndMlSample i Visual Studio Code.

  3. Högerklicka på utforskarpanelen (i det tomma utrymmet) och välj Ny IoT Edge-lösning.

    Skapa en ny IoT Edge-lösning

  4. Acceptera standardlösningsnamnet EdgeSolution.

  5. Välj Azure Machine Learning som modulmall.

  6. Ge modulen namnet turbofanRulClassifier.

  7. Välj din maskininlärningsarbetsyta. Den här arbetsytan är den turboFanDemo-arbetsyta som du skapade i Självstudie: Träna och distribuera en Azure Machine Learning-modell

  8. Välj den avbildning som du skapade när du körde Azure Notebook.

  9. Titta på lösningen och lägg märke till de filer som har skapats:

    • deployment.template.json: Den här filen innehåller definitionen av var och en av modulerna i lösningen. Det finns tre avsnitt att vara uppmärksam på i den här filen:

      • Registerautentiseringsuppgifter: Definierar den uppsättning anpassade containerregister som du använder i din lösning. Just nu bör det innehålla registret från din maskininlärningsarbetsyta, där din Azure Machine Learning-avbildning lagrades. Du kan ha valfritt antal containerregister, men för enkelhetens skull använder vi det här registret för alla moduler.

        "registryCredentials": {
          "<your registry>": {
            "username": "$CONTAINER_REGISTRY_USERNAME_<your registry>",
            "password": "$CONTAINER_REGISTRY_PASSWORD_<your registry>",
            "address": "<your registry>.azurecr.io"
          }
        }
        
      • Modules: Det här avsnittet innehåller den uppsättning användardefinierade moduler som medföljer den här lösningen. Moduldefinitionen turbofanRulClassifier refererar till bilden i ditt containerregister. När vi lägger till fler moduler i lösningen visas de i det här avsnittet.

        "modules": {
           "turbofanRulClassifier": {
             "version": "1.0",
             "type": "docker",
             "status": "running",
             "restartPolicy": "always",
             "settings": {
               "image": "turbofandemo2cd74296.azurecr.io/edgemlsample:1",
               "createOptions": {}
             }
           }
        }
        
      • Rutter: Vi kommer att arbeta med rutter en hel del i den här handledningen. Vägar definierar hur moduler kommunicerar med varandra. Den befintliga vägen som definieras av mallen matchar inte den routning vi behöver. Ta bort turbofanRulClassifierToIoTHub rutt.

        "$edgeHub": {
           "properties.desired": {
             "schemaVersion": "1.0",
             "routes": {
               "turbofanRulClassifierToIoTHub": "FROM /messages/modules/turbofanRulClassifier/outputs/* INTO $upstream"
             },
             "storeAndForwardConfiguration": {
               "timeToLiveSecs": 7200
             }
           }
        }
        
    • deployment.debug.template.json: den här filen är felsökningsversionen av deployment.template.json. Normalt bör vi hålla den här filen synkroniserad med innehållet i den deployment.template.json filen, men det krävs inte för den här självstudien.

    • .env: I den här filen ska du ange användarnamnet och lösenordet för åtkomst till registret.

      CONTAINER_REGISTRY_USERNAME_<your registry name>=<ACR username>
      CONTAINER_REGISTRY_PASSWORD_<your registry name>=<ACR password>
      

      Anmärkning

      I den här självstudien används autentiseringsuppgifter för administratörsinloggning för Azure Container Registry, vilket är praktiskt för utvecklings- och testscenarier. När du är redo för produktionsscenarier rekommenderar vi ett autentiseringsalternativ med minimala privilegier, som tjänsthuvudnamn. Mer information finns i Hantera åtkomst till containerregistret.

  10. Högerklicka på filen deployment.template.json i Visual Studio Code Explorer och välj Skapa IoT Edge-lösning.

  11. Observera att det här kommandot skapar en konfigurationsmapp med en deployment.amd64.json fil. Den här filen är den konkreta distributionsmallen för lösningen.

Lägg till routermodul

Sedan lägger vi till routermodulen i vår lösning. Router-modulen hanterar flera ansvarsområden för vår lösning:

  • Ta emot meddelanden från underordnade enheter: när meddelanden kommer till IoT Edge-enheten från underordnade enheter tar routermodulen emot meddelandet och börjar dirigera meddelandet.
  • Skicka meddelanden till modulen RUL-klassificerare: När ett nytt meddelande tas emot från en nedströmsenhet omvandlar Router-modulen meddelandet till det format som RUL-klassificeraren förväntar sig. Routern skickar meddelandet till RUL-klassificeraren för en RUL-förutsägelse. När klassificeraren har gjort en förutsägelse skickar den tillbaka meddelandet till routermodulen.
  • Skicka RUL-meddelanden till IoT Hub: när routern tar emot meddelanden från klassificeraren transformeras meddelandet till att endast innehålla viktig information, enhets-ID och RUL, och skickar det förkortade meddelandet till IoT-hubben. En ytterligare förfining, som vi inte har gjort här, skulle bara skicka meddelanden till IoT Hub när RUL-förutsägelsen faller under ett tröskelvärde (till exempel när RUL är färre än 100 cykler). Filtrering på det här sättet skulle minska mängden meddelanden och minska kostnaden för IoT-hubben.
  • Skicka ett meddelande till Modulen Avro Writer: För att bevara alla data som skickas av den underordnade enheten skickar Router-modulen hela meddelandet som tas emot från klassificeraren till Modulen Avro Writer, som bevarar och laddar upp data med IoT Hub-filuppladdning.

Router-modulen är en viktig del av lösningen som säkerställer att meddelanden bearbetas i rätt ordning.

Skapa modulen och kopiera filer

  1. Högerklicka på mappen moduler i Visual Studio Code och välj Lägg till IoT Edge-modul.

  2. Välj C#-modulen för modulmallen.

  3. Ge modulen namnet turbofanRouter.

  4. När du uppmanas att ange Docker-avbildningsregister, använd registret från arbetsytan för maskininlärning (du hittar registret i noden registryCredentials i din deployment.template.json-fil). Det här värdet är den fullständigt kvalificerade adressen till registret, till exempel <registry.azurecr.io/turbofanrouter>.

    Anmärkning

    I den här artikeln använder vi Azure Container Registry som skapades av Azure Machine Learning-arbetsytan. Detta är enbart för enkelhetens skull. Vi kunde ha skapat ett nytt containerregister och publicerat våra moduler där.

  5. I terminalen med kommandotolken kopierar du filerna från exempelmodulen till lösningen.

    copy c:\source\IoTEdgeAndMlSample\EdgeModules\modules\turbofanRouter\*.cs c:\source\IoTEdgeAndMlSample\EdgeSolution\modules\turbofanRouter\
    
  6. Acceptera uppmaningen att skriva över program.cs-filen.

Skapa routermodul

  1. I Visual Studio Code väljer du Terminal>Konfigurera standardbygguppgift.

  2. Välj Skapa tasks.json fil från mallen.

  3. Välj .NET Core.

  4. Ersätt innehållet i tasks.json med följande kod.

    {
      "version": "2.0.0",
      "tasks": [
        {
          "label": "build",
          "command": "dotnet",
          "type": "shell",
          "group": {
            "kind": "build",
            "isDefault": true
          },
          "args": [
            "build",
            "${workspaceFolder}/modules/turbofanRouter"
          ],
          "presentation": {
            "reveal": "always"
          },
          "problemMatcher": "$msCompile"
        }
      ]
    }
    
  5. Spara och stäng tasks.json.

  6. Kör build med Ctrl + Shift + B eller Terminal>Run Build Task.

Konfigurera modulvägar

Som nämnts ovan använder IoT Edge-körningen vägar som konfigurerats i filendeployment.template.json för att hantera kommunikationen mellan löst kopplade moduler. I det här avsnittet går vi in på hur du konfigurerar vägarna för modulen turbofanRouter. Vi tar först upp indatavägarna och går sedan vidare till utdata.

Ingångar

  1. I metoden Init() för Program.cs registrerar vi två återanrop för modulen:

    await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromLeafDevice, LeafDeviceInputMessageHandler, ioTHubModuleClient);
    await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromClassifier, ClassifierCallbackMessageHandler, ioTHubModuleClient);
    
  2. Det första återanropet lyssnar på meddelanden som skickas till deviceInput-sink. I diagrammet ovan ser vi att vi vill dirigera meddelanden från alla underordnade enheter till dessa indata. I filendeployment.template.json lägger du till en rutt som instruerar gränshubben att dirigera alla meddelanden som tas emot av IoT Edge-enheten och som inte skickades av en IoT Edge-modul, till ingången som heter "deviceInput" på turbofanRouter-modulen.

    "leafMessagesToRouter": "FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/deviceInput\")"
    
  3. Lägg sedan till en väg för meddelanden från modulen rulClassifier i modulen turbofanRouter:

    "classifierToRouter": "FROM /messages/modules/turbofanRulClassifier/outputs/amloutput INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/rulInput\")"
    

Utdata

Lägg till ytterligare fyra vägar till $edgeHub routningsparametern för att hantera utdata från routermodulen.

  1. Program.cs definierar metoden SendMessageToClassifier(), som använder modulklienten för att skicka ett meddelande till RUL-klassificeraren med hjälp av vägen:

    "routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")"
    
  2. SendRulMessageToIotHub() använder modulklienten för att bara skicka RUL-data för enheten till IoT Hub via vägen:

    "routerToIoTHub": "FROM /messages/modules/turboFanRouter/outputs/hubOutput INTO $upstream"
    
  3. SendMessageToAvroWriter() använder modulklienten för att skicka meddelandet med RUL-data som lagts till i modulen avroFileWriter.

    "routerToAvro": "FROM /messages/modules/turbofanRouter/outputs/avroOutput INTO BrokeredEndpoint(\"/modules/avroFileWriter/inputs/avroModuleInput\")"
    
  4. HandleBadMessage() skickar misslyckade meddelanden uppströms IoT Hub där de kan dirigeras för senare.

    "deadLetter": "FROM /messages/modules/turboFanRouter/outputs/deadMessages INTO $upstream"
    

Med alla vägar tillsammans bör noden "$edgeHub" se ut som följande JSON:

"$edgeHub": {
  "properties.desired": {
    "schemaVersion": "1.0",
    "routes": {
      "leafMessagesToRouter": "FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/deviceInput\")",
      "classifierToRouter": "FROM /messages/modules/turbofanRulClassifier/outputs/amlOutput INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/rulInput\")",
      "routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")",
      "routerToIoTHub": "FROM /messages/modules/turboFanRouter/outputs/hubOutput INTO $upstream",
      "routerToAvro": "FROM /messages/modules/turbofanRouter/outputs/avroOutput INTO BrokeredEndpoint(\"/modules/avroFileWriter/inputs/avroModuleInput\")",
      "deadLetter": "FROM /messages/modules/turboFanRouter/outputs/deadMessages INTO $upstream"
    },
    "storeAndForwardConfiguration": {
      "timeToLiveSecs": 7200
    }
  }
}

Anmärkning

När du lade till modulen turbofanRouter skapade du följande ytterligare väg: turbofanRouterToIoTHub": "FROM /messages/modules/turbofanRouter/outputs/* INTO $upstream. Ta bort den här vägen och lämna endast de vägar som anges ovan i filen deployment.template.json.

Lägg till Avro Writer-modul

Modulen Avro Writer har två ansvarsområden i vår lösning för att lagra meddelanden och ladda upp filer.

  • Lagra meddelanden: när Modulen Avro Writer tar emot ett meddelande skriver den meddelandet till det lokala filsystemet i Avro-format. Vi använder en bindmontering som monterar en katalog (i det här fallet /data/avrofiles) till en sökväg i modulens container. Med den här monteringen kan modulen skriva till en lokal sökväg (/avrofiles) och ha dessa filer tillgängliga direkt från IoT Edge-enheten.

  • Ladda upp filer: Modulen Avro Writer använder azure IoT Hub-filuppladdningsfunktionen för att ladda upp filer till ett Azure-lagringskonto. När en fil har laddats upp tar modulen bort filen från disken

Skapa modul och kopiera filer

  1. I Visual Studio Code väljer du Visa>kommandopalett och söker sedan efter och väljer Python: Välj Tolk.

  2. Välj din installerade Python-version 3.7 eller senare.

  3. Högerklicka på mappen moduler i Visual Studio Code och välj Lägg till IoT Edge-modul.

  4. Välj Python-modul.

  5. Namnge modulen avroFileWriter.

  6. När du uppmanas att ange docker-avbildningslagringsplatsen använder du samma register som du använde när du lade till routermodulen.

  7. Kopiera filer från exempelmodulen till lösningen.

    copy C:\source\IoTEdgeAndMlSample\EdgeModules\modules\avroFileWriter\*.py C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avroFileWriter\
    
  8. Acceptera överskrivningen av main.py.

  9. Observera att filemanager.py och schema.py har lagts till i lösningen och main.py har uppdaterats.

Anmärkning

När du öppnar en Python-fil kan du uppmanas att installera pylint. Du behöver inte installera en linter för att slutföra den här handledningen.

Bindmontering för datafiler

Som tidigare nämnts förlitar sig skrivarmodulen på förekomsten av en bindningsmontering för att skriva Avro-filer till enhetens filsystem.

Lägga till katalog på enheten

  1. Starta IoT Edge-enhetens virtuella dator i Azure-portalen om den inte redan är igång. Anslut till den med hjälp av SSH. Anslutningen kräver det DNS-namn som du kan kopiera från översiktssidan för den virtuella datorn i Azure-portalen.

    ssh -l <user>@<vm name>.<region>.cloudapp.azure.com
    
  2. När du har loggat in skapar du katalogen som innehåller de sparade underordnade enhetsmeddelandena.

    sudo mkdir -p /data/avrofiles
    
  3. Uppdatera katalogbehörigheter för att göra den skrivbar av containern.

    sudo chmod ugo+rw /data/avrofiles
    
  4. Verifiera att katalogen nu har skrivbehörighet (w) för användare, grupp och ägare.

    ls -la /data
    

    Katalogbehörigheter för avrofiles

Lägga till katalog i modulen

För att lägga till mappen till modulens container ändrar vi Dockerfiles som är associerade med modulen avroFileWriter. Det finns tre Dockerfiles som är associerade med modulen: Dockerfile.amd64, Dockerfile.amd64.debug och Dockerfile.arm32v7. Dessa filer bör hållas synkroniserade om vi vill felsöka eller distribuera till en arm32-enhet. I den här artikeln fokuserar du bara på Dockerfile.amd64.

  1. Öppna filen C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\Dockerfile.amd64 på den virtuella utvecklingsdatorn.

  2. Ändra filen så att den ser ut som i följande exempel:

    FROM ubuntu:xenial
    
    WORKDIR /app
    
    RUN apt-get update && apt-get install -y --no-install-recommends libcurl4-openssl-dev
    python3-pip libboost-python1.58-dev libpython3-dev && rm -rf /var/lib/apt/lists/*
    
    RUN pip3 install --upgrade pip
    COPY requirements.txt ./
    RUN pip install -r requirements.txt
    
    COPY . .
    
    RUN useradd -ms /bin/bash moduleuser
    RUN mkdir /avrofiles && chown moduleuser /avrofiles
    USER moduleuser
    
    CMD [ "python3", "-u", "./main.py" ]
    

    Kommandona mkdir och chown instruerar Docker-byggprocessen att skapa en toppnivåkatalog med namnet /avrofiles i avbildningen och sedan göra moduleuser till ägare av katalogen. Det är viktigt att dessa kommandon infogas efter att modulanvändaren har lagts till i avbildningen med kommandot useradd och innan kontexten växlar till modulanvändaren (USER moduleuser).

  3. Om det behövs gör du motsvarande ändringar i Dockerfile.amd64.debug och Dockerfile.arm32v7.

Lägga till bindningskonfiguration till avroFileWriter

Det sista steget för att skapa bindningen är att uppdatera deployment.template.json-filerna (och deployment.debug.template.json) med bindningsinformationen.

  1. Öppna deployment.template.json.

  2. Ändra moduldefinitionen för avroFileWriter genom att lägga till parametern Binds som pekar containerkatalogen /avrofiles till den lokala katalogen på gränsenheten. Moduldefinitionen bör matcha det här exemplet:

    "avroFileWriter": {
      "version": "1.0",
      "type": "docker",
      "status": "running",
      "restartPolicy": "always",
      "settings": {
        "image": "${MODULES.avroFileWriter}",
        "createOptions": {
          "HostConfig": {
            "Binds": [
              "/data/avrofiles:/avrofiles"
            ]
          }
        }
      }
    }
    

Bindmontering för åtkomst till config.yaml

Vi måste lägga till ytterligare en bindning för skrivarmodulen. Den här bindningen ger modulen åtkomst till att läsa anslutningssträngen från filen /etc/iotedge/config.yaml på IoT Edge-enheten. Vi behöver anslutningssträngen för att skapa en IoTHubClient så att vi kan anropa metoden upload_blob_async för att ladda upp filer till IoT-hubben. Stegen för att lägga till den här bindningen liknar dem i föregående avsnitt.

Uppdatera katalogbehörighet

  1. Anslut till din IoT Edge-enhet med hjälp av SSH.

    ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
    
  2. Lägg till läsbehörighet i filen config.yaml.

    sudo chmod +r /etc/iotedge/config.yaml
    
  3. Kontrollera att behörigheterna har angetts korrekt.

    ls -la /etc/iotedge/
    
  4. Kontrollera att behörigheterna för config.yaml är -r--r--r--.

Lägga till katalog i modulen

  1. Öppna dockerfile.amd64-filen på utvecklingsdatorn.

  2. Lägg till ytterligare en uppsättning mkdir kommandon och chown i filen så att det ser ut så här:

    FROM ubuntu:xenial
    
    WORKDIR /app
    
    RUN apt-get update && apt-get install -y --no-install-recommends libcurl4-openssl-dev
    python3-pip libboost-python1.58-dev libpython3-dev && rm -rf /var/lib/apt/lists/\*
    
    RUN pip3 install --upgrade pip
    COPY requirements.txt ./
    RUN pip install -r requirements.txt
    
    COPY . .
    
    RUN useradd -ms /bin/bash moduleuser
    RUN mkdir /avrofiles && chown moduleuser /avrofiles
    RUN mkdir -p /app/iotconfig && chown moduleuser /app/iotconfig
    
    USER moduleuser
    
    CMD "python3", "-u", "./main.py"]
    
  3. Gör motsvarande ändringar i Dockerfile.amd64.debug och Dockerfile.arm32v7.

Uppdatera modulkonfigurationen

  1. Öppna filen deployment.template.json.

  2. Ändra moduldefinitionen för avroFileWriter genom att lägga till en andra rad i parametern Binds som pekar containerkatalogen (/app/iotconfig) till den lokala katalogen på enheten (/etc/iotedge).

    "avroFileWriter": {
      "version": "1.0",
      "type": "docker",
      "status": "running",
      "restartPolicy": "always",
      "settings": {
        "image": "${MODULES.avroFileWriter}",
        "createOptions": {
          "HostConfig": {
            "Binds": [
              "/data/avrofiles:/avrofiles",
              "/etc/iotedge:/app/iotconfig"
            ]
          }
        }
      }
    }
    
  3. Gör motsvarande ändringar i deployment.debug.template.json.

Installera beroenden

Skrivarmodulen är beroende av två Python-bibliotek, fastavro och PyYAML. Vi måste installera beroendena på utvecklingsdatorn och instruera Docker-byggprocessen att installera dem i modulens avbildning.

PyYAML

  1. Öppna filen på din utvecklingsdator C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\requirements.txt och lägg till "pyyaml" på en ny rad i filen.

    azure-iothub-device-client~=1.4.3
    pyyaml
    
  2. Öppna dockerfile.amd64-filen och lägg till ett pip install kommando för att uppgradera setuptools.

    FROM ubuntu:xenial
    
    WORKDIR /app
    
    RUN apt-get update && \
        apt-get install -y --no-install-recommends libcurl4-openssl-dev python3-pip libboost-python1.58-dev libpython3-dev && \
        rm -rf /var/lib/apt/lists/\*
    
    RUN pip3 install --upgrade pip
    RUN pip install -U pip setuptools
    COPY requirements.txt ./
    RUN pip install -r requirements.txt
    
    COPY . .
    
    RUN useradd -ms /bin/bash moduleuser
    RUN mkdir /avrofiles && chown moduleuser /avrofiles
    RUN mkdir -p /app/iotconfig && chown moduleuser /app/iotconfig
    USER moduleuser
    
    CMD [ "python3", "-u", "./main.py" ]
    
  3. Installera pyyaml på din utvecklingsmaskin i ett terminalfönster.

    pip install pyyaml
    

Fastavro

  1. I requirements.txtlägger du till fastavro efter pyyaml.

    azure-iothub-device-client~=1.4.3
    pyyaml
    fastavro
    
  2. Installera fastavro på utvecklingsdatorn.

    pip install fastavro
    

Konfigurera om IoT Hub

Genom att introducera IoT Edge-enheten och modulerna i systemet har vi ändrat våra förväntningar på vilka data som ska skickas till hubben och i vilket syfte. Vi måste konfigurera om routningen i hubben för att hantera vår nya verklighet.

Anmärkning

Vi konfigurerar om hubben innan vi distribuerar moduler eftersom vissa av hubbinställningarna, särskilt filuppladdning, måste konfigureras korrekt för att avroFileWriter-modulen ska kunna köras korrekt

Konfigurera väg för RUL-meddelanden i IoT Hub

Med routern och klassificeraren på plats förväntar vi oss att få vanliga meddelanden som endast innehåller enhets-ID:t och RUL-förutsägelsen för enheten. Vi vill dirigera RUL-data till en egen lagringsplats där vi kan övervaka status för enheterna, skapa rapporter och utlösa aviseringar efter behov. Samtidigt vill vi att alla enhetsdata som fortfarande skickas direkt av en nedströmsenhet som ännu inte har anslutits till vår IoT Edge-enhet ska fortsätta att dirigeras till den aktuella lagringsplatsen.

Skapa en RUL-meddelandeväg

  1. Gå till din IoT-hubb på Azure Portal.

  2. På menyn i det vänstra fönstret går du till Hubbinställningar och väljer Meddelanderoutning.

  3. På fliken Vägar väljer du Lägg till.

  4. Ge vägen namnet RulMessageRoute.

  5. Välj Lägg till slutpunkt till höger om slutpunktsväljaren och välj Lagring.

  6. På sidan Lägg till en lagringsslutpunkt ger du slutpunkten namnet ruldata.

  7. Välj Välj en container.

  8. På sidan Lagringskonton hittar du det lagringskonto som du använder i den här självstudien, som heter iotedgeandml<unikt suffix>.

  9. Välj containern ruldata och klicka på Välj.

  10. På sidan Lägg till en lagringsslutpunkt väljer du Skapa för att skapa lagringsslutpunkten.

  11. Tillbaka på sidan Lägg till en väg ersätter du med följande fråga för true:

    IS_DEFINED($body.PredictedRul) AND NOT IS_DEFINED($body.OperationalSetting1)
    
  12. Expandera avsnittet Test och sedan avsnittet Meddelandetext . Ersätt meddelandetexten med det här exemplet på våra förväntade meddelanden:

    {
      "ConnectionDeviceId": "aaLeafDevice_1",
      "CorrelationId": "b27e97bb-06c5-4553-a064-e9ad59c0fdd3",
      "PredictedRul": 132.62721409309165,
      "CycleTime": 64.0
    }
    
  13. Välj Testväg. Om testet lyckas ser du "Meddelandet matchade frågan".

  14. Klicka på Spara.

Uppdatera turbofanDeviceDataToStorage-rutten

Vi vill inte dirigera nya förutsägelsedata till vår gamla lagringsplats, så uppdatera vägen för att förhindra den.

  1. På sidan IoT Hub-meddelanderoutning väljer du fliken Vägar .

  2. Välj turbofanDeviceDataToStorage, eller vilket namn du gav till din första enhetsdataväg.

  3. Uppdatera routningsfrågan till

    IS_DEFINED($body.OperationalSetting1)
    
  4. Expandera avsnittet Test och sedan avsnittet Meddelandetext . Ersätt meddelandet med det här exemplet på våra förväntade meddelanden:

    {
      "Sensor13": 2387.96,
      "OperationalSetting1": -0.0008,
      "Sensor6": 21.61,
      "Sensor11": 47.2,
      "Sensor9": 9061.45,
      "Sensor4": 1397.86,
      "Sensor14": 8140.39,
      "Sensor18": 2388.0,
      "Sensor12": 522.87,
      "Sensor2": 642.42,
      "Sensor17": 391.0,
      "OperationalSetting3": 100.0,
      "Sensor1": 518.67,
      "OperationalSetting2": 0.0002,
      "Sensor20": 39.03,
      "DeviceId": 19.0,
      "Sensor5": 14.62,
      "PredictedRul": 212.00132402791962,
      "Sensor8": 2388.01,
      "Sensor16": 0.03,
      "CycleTime": 42.0,
      "Sensor21": 23.3188,
      "Sensor15": 8.3773,
      "Sensor3": 1580.09,
      "Sensor10": 1.3,
      "Sensor7": 554.57,
      "Sensor19": 100.0
    }
    
  5. Välj Testväg. Om testet lyckas ser du "Meddelandet matchade frågan".

  6. Välj Spara.

Konfigurera filuppladdning

Konfigurera funktionen för uppladdning av IoT Hub-filer så att filskrivaremodulen kan ladda upp filer till lagring.

  1. I den vänstra menyn i IoT Hub går du till Hubbinställningar och väljer Filuppladdning.

  2. Välj Azure Storage Container.

  3. Välj ditt lagringskonto i listan.

  4. Välj den container som börjar med azureml-blobstore som läggs till med ett guid och klicka på Välj.

  5. Välj Spara. Portalen meddelar dig när sparande är klart.

Anmärkning

Vi aktiverar inte uppladdningsmeddelande för den här självstudien, men se Ta emot ett meddelande om filuppladdning för mer information om hur du hanterar meddelanden om filuppladdning.

Skapa, publicera och distribuera moduler

Nu när vi har gjort konfigurationsändringarna är vi redo att skapa avbildningarna och publicera dem i vårt Azure-containerregister. Byggprocessen använder deployment.template.json-filen för att avgöra vilka moduler som behöver skapas. Inställningarna för varje modul, inklusive version, finns i filen module.json i modulmappen. Byggprocessen kör först en Docker-version på Dockerfiles som matchar den aktuella konfigurationen som finns i module.json-filen för att skapa en avbildning. Sedan publicerar den avbildningen till registret från module.json-filen med en versionstagg som matchar den i module.json-filen. Slutligen skapar den ett konfigurationsspecifikt distributionsmanifest (till exempel deployment.amd64.json), som vi distribuerar till IoT Edge-enheten. IoT Edge-enheten läser informationen från distributionsmanifestet och baserat på instruktionerna laddas modulerna ned, vägarna konfigureras och eventuella önskade egenskaper anges. Den här distributionsmetoden har två biverkningar som du bör känna till:

  • Distributionsfördröjning: Eftersom IoT Edge-körningen måste känna igen ändringen av önskade egenskaper innan den börjar konfigureras om kan det ta lite tid efter att du har distribuerat modulerna tills körningen hämtar dem och börjar uppdatera IoT Edge-enheten.

  • Modulversioner spelar roll: Om du publicerar en ny version av en moduls container i containerregistret med samma versionstaggar som föregående modul, kommer körningen inte att ladda ned den nya versionen av modulen. Den gör en jämförelse av versionstaggen för den lokala avbildningen och den önskade avbildningen från distributionsmanifestet. Om dessa versioner matchar vidtar programmet ingen åtgärd. Därför är det viktigt att öka versionen av modulen varje gång du vill distribuera nya ändringar. Öka versionen genom att ändra versionsegenskapen under taggegenskapen i module.json-filen för modulen som du ändrar. Skapa och publicera sedan modulen.

    {
      "$schema-version": "0.0.1",
      "description": "",
      "image": {
        "repository": "<your registry>.azurecr.io/avrofilewriter",
        "tag": {
          "version": "0.0.1",
          "platforms": {
            "amd64": "./Dockerfile.amd64",
            "amd64.debug": "./Dockerfile.amd64.debug",
            "arm32v7": "./Dockerfile.arm32v7"
          }
        },
        "buildOptions": []
      },
      "language": "python"
    }
    

Skapa och publicera

  1. Starta Docker på den virtuella utvecklingsdatorn om den inte körs.

  2. I Visual Studio Code startar du en ny terminal med en kommandotolk och loggar in på ditt Azure-containerregister (ACR).

Du hittar nödvändiga värden för användarnamn, lösenord och inloggningsserver i Azure-portalen. Containerregistrets namn har formatet "turbofandemo<unique id>". I den vänstra menyn under Inställningar väljer du Åtkomstnycklar för att visa dem.

docker login -u <ACR username> -p <ACR password> <ACR login server>
  1. I Visual Studio Code högerklickar du på deployment.template.json och väljer Build and Push IoT Edge Solution (Skapa och push-lösning för IoT Edge).

Visa moduler i registret

När bygget är klart kan vi använda Azure-portalen för att granska våra publicerade moduler.

  1. Öppna Azure Container Registry för denna handledning. Containerregistrets namn har formatet "turbofandemo<unique id>".

  2. Välj Lagringsplatser under Tjänster på menyn till vänster.

  3. Observera att båda modulerna du skapade, avrofilewriter och turbofanrouter, visas som lagringsplatser.

  4. Välj turbofanrouter och observera att du har publicerat en bild taggad som 0.0.1-amd64.

    Visa den första taggade versionen av turbofanrouter

Distribuera moduler till IoT Edge-enhet

Vi har skapat och konfigurerat modulerna i vår lösning, nu distribuerar vi modulerna till IoT Edge-enheten.

  1. Högerklicka på filendeployment.amd64.json i mappen config i Visual Studio Code.

  2. Välj Skapa distribution för enskild enhet.

  3. Välj din IoT Edge-enhet , aaTurboFanEdgeDevice.

  4. Uppdatera panelen Azure IoT Hub-enheter i Visual Studio Code-utforskaren. Du bör se att de tre nya modulerna har distribuerats men inte körs ännu.

  5. Uppdatera igen efter några minuter så visas modulerna som körs.

    Visa moduler som körs i Visual Studio Code

Anmärkning

Det kan ta flera minuter för modulerna att starta och etablera sig i ett stabilt körningstillstånd. Under den tiden kan du se moduler starta och stoppas när de försöker upprätta en anslutning till IoT Edge-hubbmodulen.

Diagnostisering av fel

I det här avsnittet delar vi några tekniker för att förstå vad som har gått fel med en modul eller moduler. Ofta kan ett fel först upptäckas från statusen i Visual Studio Code.

Identifiera misslyckade moduler

  • Visual Studio Code: Titta på panelen för Azure IoT Hub-enheter. Om de flesta moduler är i ett körningstillstånd men en stoppas måste du undersöka den stoppade modulen ytterligare. Om alla moduler är i ett stoppat tillstånd under en längre tid kan det också tyda på fel.

  • Azure-portalen: Genom att gå till din IoT-hubb i portalen och sedan hitta sidan med enhetsinformation (under IoT Edge, öka detaljnivån på enheten) kan du upptäcka att en modul har rapporterat ett fel eller aldrig har rapporterat något till IoT-hubben.

Diagnostisera från enheten

Genom att logga in på IoT Edge-enheten (den virtuella Linux-datorn i vårt fall) kan du få tillgång till en hel del information om statusen för dina moduler. Den huvudsakliga mekanismen vi använder är Docker-kommandon som låter oss undersöka containrar och avbildningar på enheten.

  1. Logga in på din IoT Edge-enhet:

    ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
    
  2. Visa alla körande containrar. Vi förväntar oss att se en container för varje modul med ett namn som motsvarar modulen. Det här kommandot visar också den exakta avbildningen för containern inklusive version så att du kan matcha dina förväntningar. Du kan också lista avbildningar genom att ersätta "image" med "container" i kommandot .

    sudo docker container ls
    
  3. Hämta loggarna för en container. Det här kommandot matar ut det som har skrivits till StdErr och StdOut i containern. Det här kommandot fungerar för containrar som har startat och sedan dött av någon anledning. Det är också användbart för att förstå vad som har hänt med edgeAgent- eller edgeHub-containrarna.

    sudo docker container logs <container id>
    
  4. Inspektera en container. Det här kommandot ger massor av information om avbildningen. Data kan filtreras beroende på vad du letar efter. Om du till exempel vill se om bindningarna på avroFileWriter är korrekta kan du använda kommandot:

    sudo docker container inspect -f "{{ json .Mounts }}" avroFileWriter | python -m json.tool
    
  5. Anslut till en körande container. Det här kommandot kan vara användbart om du vill undersöka containern medan den körs:

    sudo docker exec -it avroFileWriter bash
    

Rensa resurser

Den här handledningen är en del av en serie där varje artikel bygger vidare på det arbete som gjorts i de föregående. Vänta med att rensa systemresurser tills du har slutfört den sista guiden.

Nästa steg

I den här artikeln skapade vi en IoT Edge-lösning i Visual Studio Code med tre moduler: en klassificerare, en router och en filskrivare/uppladdare. Vi konfigurerar rutterna så att modulerna kan kommunicera med varandra på edge-enheten. Vi ändrade konfigurationen av gränsenheten och uppdaterade Dockerfiles för att installera beroenden och lägga till bindningsmonteringar i modulernas containrar.

Därefter uppdaterade vi konfigurationen av IoT Hub för att dirigera våra meddelanden baserat på typ och hantera filuppladdningar. Med allt på plats distribuerade vi modulerna till IoT Edge-enheten och såg till att modulerna kördes korrekt.

Fortsätt till nästa artikel för att börja skicka data och se hur din lösning fungerar.