Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Si applica a:
IoT Edge 1.1
Importante
La data di fine del supporto di IoT Edge 1.1 è stata il 13 dicembre 2022. Controllare il ciclo di vita del prodotto Microsoft per informazioni su come è supportato questo prodotto, servizio, tecnologia o API. Per altre informazioni sull'aggiornamento alla versione più recente di IoT Edge, vedere Aggiornare IoT Edge.
In questo articolo vengono creati tre moduli IoT Edge che ricevono messaggi dai dispositivi IoT downstream, eseguono i dati tramite il modello di Machine Learning e quindi inoltrano informazioni dettagliate all'hub IoT.
L'hub di IoT Edge facilita la comunicazione tra moduli. L'uso dell'hub IoT Edge come broker di messaggi mantiene i moduli indipendenti l'uno dall'altro. Per i moduli è sufficiente specificare gli input su cui accettano i messaggi e gli output su cui scrivono i messaggi.
Il dispositivo IoT Edge deve eseguire quattro operazioni:
- Ricevere dati dai dispositivi downstream.
- Stimare la durata utile rimanente (URL) per il dispositivo che ha inviato i dati.
- Invia un messaggio con il RUL per il dispositivo all'IoT Hub. Questa funzione può essere modificata per inviare dati solo se l'URL scende al di sotto di un livello specificato.
- Salvare i dati del dispositivo downstream in un file locale nel dispositivo IoT Edge. Questo file di dati viene caricato periodicamente nell'hub IoT per perfezionare il training del modello di Machine Learning. L'uso del caricamento di file anziché lo streaming costante dei messaggi è più conveniente.
Per eseguire queste attività, vengono usati tre moduli personalizzati:
Classificatore RUL: Il modulo turboFanRulClassifier che abbiamo creato in Eseguire il training e distribuire un modello di Azure Machine Learning è un modulo di machine learning standard, che espone un input denominato "amlInput" e un output denominato "amlOutput". "amlInput" prevede che l'input sia esattamente simile all'input inviato al servizio Web basato su ACI. Analogamente, "amlOutput" restituisce gli stessi dati del servizio Web.
Scrittore Avro: Questo modulo riceve messaggi nell'input "avroModuleInput" e salva in modo permanente il messaggio in formato Avro su disco per il caricamento successivo nell'hub IoT.
Modulo router: Il modulo router riceve messaggi dai dispositivi downstream, quindi formatta e invia i messaggi al classificatore. Il modulo riceve quindi i messaggi dal classificatore e inoltra il messaggio al modulo writer Avro. Infine, il modulo invia solo la previsione RUL all'hub IoT.
Ingressi:
- deviceInput: riceve messaggi dai dispositivi downstream
- rulInput: riceve messaggi da "amlOutput"
Output:
- classify: invia messaggi a "amlInput"
- writeAvro: invia messaggi a "avroModuleInput"
- toIotHub: invia messaggi a $upstream, che passa i messaggi all'hub IoT connesso
Il diagramma seguente mostra i moduli, gli input, gli output e le route dell'hub IoT Edge per la soluzione completa:
I passaggi descritti in questo articolo vengono in genere eseguiti da uno sviluppatore cloud.
In questa sezione dell'esercitazione si apprenderà come:
- Creare un modulo IoT Edge dal codice personalizzato.
- Generare un'immagine Docker dal modulo personalizzato.
- Riconfigurare il routing dell'hub IoT per supportare i moduli personalizzati.
- Compilare, pubblicare e distribuire i moduli personalizzati.
Prerequisiti
Questo articolo fa parte di una serie di esercitazioni sull'uso di Azure Machine Learning in IoT Edge. Ogni articolo della serie si basa sul lavoro dell'articolo precedente. Se sei arrivato direttamente a questo articolo, visita il primo articolo della serie.
Creare una nuova soluzione IoT Edge
Durante l'esecuzione del secondo dei due Notebook di Azure, è stata creata e pubblicata un'immagine del contenitore contenente il modello URL. Azure Machine Learning, come parte del processo di creazione dell'immagine, ha creato un pacchetto del modello in modo che l'immagine sia distribuibile come modulo Azure IoT Edge.
In questo passaggio si creerà una soluzione Azure IoT Edge usando il modulo "Azure Machine Learning" e si punterà il modulo all'immagine pubblicata usando Azure Notebooks.
Aprire una sessione desktop remoto per la macchina virtuale di sviluppo.
Aprire la cartella C:\source\IoTEdgeAndMlSample in Visual Studio Code.
Fare clic con il pulsante destro del mouse sul pannello explorer (nello spazio vuoto) e selezionare Nuova soluzione IoT Edge.
Accettare il nome predefinito della soluzione EdgeSolution.
Scegliere Azure Machine Learning come modello di modulo.
Assegnare al modulo il nome turbofanRulClassifier.
Scegliere l'area di lavoro di Machine Learning. Questa area di lavoro è l'area di lavoro turboFanDemo creata in Esercitazione: Eseguire il training e distribuire un modello di Azure Machine Learning
Selezionare l'immagine creata durante l'esecuzione di Azure Notebook.
Esaminare la soluzione e notare i file creati:
deployment.template.json: Questo file contiene la definizione di ognuno dei moduli nella soluzione. Esistono tre sezioni a cui prestare attenzione in questo file:
Credenziali del Registro di sistema: Definisce il set di registri contenitori personalizzati usati nella soluzione. Al momento, dovrebbe contenere il Registro di sistema dall'area di lavoro di Machine Learning, che è la posizione in cui è stata archiviata l'immagine di Azure Machine Learning. È possibile avere un numero qualsiasi di registri contenitori, ma per semplicità si userà questo registro per tutti i moduli.
"registryCredentials": { "<your registry>": { "username": "$CONTAINER_REGISTRY_USERNAME_<your registry>", "password": "$CONTAINER_REGISTRY_PASSWORD_<your registry>", "address": "<your registry>.azurecr.io" } }Moduli: Questa sezione contiene il set di moduli definiti dall'utente che vanno con questa soluzione. La definizione del modulo turbofanRulClassifier fa riferimento all'immagine nel registro dei contenitori. Man mano che si aggiungono altri moduli alla soluzione, verranno visualizzati in questa sezione.
"modules": { "turbofanRulClassifier": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "turbofandemo2cd74296.azurecr.io/edgemlsample:1", "createOptions": {} } } }Route: si lavorerà con le route in questa esercitazione. Le route definiscono il modo in cui i moduli comunicano tra loro. La route esistente definita dal modello non corrisponde al routing necessario. Eliminare la
turbofanRulClassifierToIoTHubroute."$edgeHub": { "properties.desired": { "schemaVersion": "1.0", "routes": { "turbofanRulClassifierToIoTHub": "FROM /messages/modules/turbofanRulClassifier/outputs/* INTO $upstream" }, "storeAndForwardConfiguration": { "timeToLiveSecs": 7200 } } }
deployment.debug.template.json: questo file è la versione di debug di deployment.template.json. In genere, è consigliabile mantenere questo file sincronizzato con il contenuto del file deployment.template.json, ma questa operazione non è necessaria per questa esercitazione.
.env: questo file è dove è necessario specificare il nome utente e la password per l'accesso al Registro di sistema.
CONTAINER_REGISTRY_USERNAME_<your registry name>=<ACR username> CONTAINER_REGISTRY_PASSWORD_<your registry name>=<ACR password>Annotazioni
Questa esercitazione usa le credenziali di accesso amministratore per Registro Azure Container, utili per scenari di sviluppo e test. Quando si è pronti per gli scenari di produzione, è consigliabile usare un'opzione di autenticazione con privilegi minimi, ad esempio i principali di servizio. Per altre informazioni, vedere Gestire l'accesso al registro contenitori.
Fare clic con il pulsante destro del mouse sul file deployment.template.json nello strumento di esplorazione di Visual Studio Code e selezionare Compila soluzione IoT Edge.
Si noti che questo comando crea una cartella config con un file deployment.amd64.json. Questo file è il modello di distribuzione concreto per la soluzione.
Aggiungere il modulo Router
Aggiungere quindi il modulo Router alla soluzione. Il modulo Router gestisce diverse responsabilità per la soluzione:
- Ricevere messaggi dai dispositivi downstream: quando arrivano messaggi al dispositivo IoT Edge dai dispositivi downstream, il modulo Router riceve il messaggio e inizia a orchestrare il routing del messaggio.
- Inviare messaggi al modulo Classificatore URL: quando un nuovo messaggio viene ricevuto da un dispositivo downstream, il modulo Router trasforma il messaggio nel formato previsto dal classificatore URL. Il router invia il messaggio al classificatore RUL per una predizione RUL. Dopo aver eseguito una stima, il classificatore invia di nuovo il messaggio al modulo Router.
- Inviare messaggi URL all'hub IoT: quando il router riceve messaggi dal classificatore, trasforma il messaggio in modo che contenga solo le informazioni essenziali, l'ID dispositivo e la RUL e invia il messaggio abbreviato all'hub IoT. Un ulteriore perfezionamento, che non è stato fatto in questo caso, invierebbe messaggi all'hub IoT solo quando la previsione RUL scende al di sotto di una soglia (ad esempio, quando il RUL è inferiore a 100 cicli). Il filtro in questo modo riduce il volume di messaggi e riduce i costi dell'hub IoT.
- Inviare un messaggio al modulo Avro Writer: per mantenere tutti i dati inviati dal dispositivo downstream, il modulo Router invia l'intero messaggio ricevuto dal classificatore al modulo Avro Writer, che consentirà di salvare e caricare i dati usando il caricamento del file dell'hub IoT.
Il modulo Router è una parte importante della soluzione che garantisce che i messaggi vengano elaborati nell'ordine corretto.
Creare il modulo e copiare i file
Fare clic con il pulsante destro del mouse sulla cartella modules in Visual Studio Code e scegliere Aggiungi modulo IoT Edge.
Scegliere il modulo C# per il modello di modulo.
Assegnare al modulo il nome turbofanRouter.
Quando viene richiesto il repository di immagini Docker, usare il registro dall'area di lavoro di apprendimento automatico. Si può trovare il registro nel nodo registryCredentials del file deployment.template.json. Questo valore è l'indirizzo completo del Registro di sistema, ad esempio <registry.azurecr.io/turbofanrouter>.
Annotazioni
In questo articolo viene usato Registro Azure Container creato dall'area di lavoro di Azure Machine Learning. Questo è puramente per comodità. È stato possibile creare un nuovo registro contenitori e pubblicare i moduli in questa posizione.
Nel terminale, usando una shell del prompt dei comandi, copiate i file dal modulo di esempio nella soluzione.
copy c:\source\IoTEdgeAndMlSample\EdgeModules\modules\turbofanRouter\*.cs c:\source\IoTEdgeAndMlSample\EdgeSolution\modules\turbofanRouter\Accettare il prompt per sovrascrivere il file program.cs.
Modulo di costruzione router
In Visual Studio Code selezionare Terminale>Configura attività di compilazione predefinita.
Selezionare Crea tasks.json file da un modello.
Selezionare .NET Core.
Sostituire il contenuto di tasks.json con il codice seguente.
{ "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" } ] }Salva e chiudi tasks.json.
Esegui la build con
Ctrl + Shift + Bo Terminale>Esegui Attività di Build.
Configurare i percorsi dei moduli
Come accennato in precedenza, il runtime di IoT Edge usa le route configurate nel file deployment.template.json per gestire la comunicazione tra moduli ad accoppiamento libero. In questa sezione viene illustrato come configurare le route per il modulo turbofanRouter. Verranno prima illustrate le route di input e quindi si passerà agli output.
Ingressi dati
Nel metodo Init() di Program.cs vengono registrati due callback per il modulo:
await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromLeafDevice, LeafDeviceInputMessageHandler, ioTHubModuleClient); await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromClassifier, ClassifierCallbackMessageHandler, ioTHubModuleClient);Il primo callback resta in ascolto dei messaggi inviati all'elemento ricevente deviceInput. Dal diagramma sopra si vede che vogliamo instradare i messaggi da qualsiasi dispositivo downstream a questo ingresso. Nel file deployment.template.json aggiungere una route che indica all'hub perimetrale di instradare qualsiasi messaggio ricevuto dal dispositivo IoT Edge che non è stato inviato da un modulo IoT Edge nell'input denominato "deviceInput" nel modulo turbofanRouter:
"leafMessagesToRouter": "FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/deviceInput\")"Aggiungere quindi una route per i messaggi dal modulo rulClassifier nel modulo turbofanRouter:
"classifierToRouter": "FROM /messages/modules/turbofanRulClassifier/outputs/amloutput INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/rulInput\")"
Risultati
Aggiungere quattro route aggiuntive al parametro di route $edgeHub, per gestire gli output dal modulo Router.
Program.cs definisce il metodo SendMessageToClassifier(), che usa il client del modulo per inviare un messaggio al classificatore URL usando la route:
"routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")"SendRulMessageToIotHub() usa il client del modulo per inviare solo i dati url per il dispositivo all'hub IoT tramite la route:
"routerToIoTHub": "FROM /messages/modules/turboFanRouter/outputs/hubOutput INTO $upstream"SendMessageToAvroWriter() usa il client del modulo per inviare il messaggio con i dati URL aggiunti al modulo avroFileWriter.
"routerToAvro": "FROM /messages/modules/turbofanRouter/outputs/avroOutput INTO BrokeredEndpoint(\"/modules/avroFileWriter/inputs/avroModuleInput\")"HandleBadMessage() invia i messaggi non riusciti a monte dell'hub IoT dove possono essere instradati per un momento successivo.
"deadLetter": "FROM /messages/modules/turboFanRouter/outputs/deadMessages INTO $upstream"
Con tutte le route eseguite insieme al nodo "$edgeHub" dovrebbe essere simile al codice JSON seguente:
"$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
}
}
}
Annotazioni
L'aggiunta del modulo turbofanRouter ha creato la route aggiuntiva seguente: turbofanRouterToIoTHub": "FROM /messages/modules/turbofanRouter/outputs/* INTO $upstream. Rimuovere questa route, lasciando solo le route elencate sopra nel file deployment.template.json.
Aggiungere il modulo Avro Writer
Il modulo Avro Writer ha due responsabilità nella soluzione, per archiviare i messaggi e caricare i file.
Archivia i messaggi: quando il modulo Avro Writer riceve un messaggio, scrive il messaggio nel file system locale in formato Avro. Viene usato un montaggio bind, che monta una directory (in questo caso /data/avrofiles) in un percorso nel contenitore del modulo. Questo montaggio consente al modulo di scrivere in un percorso locale (/avrofiles) e di disporre di tali file accessibili direttamente dal dispositivo IoT Edge.
Caricare file: il modulo Avro Writer usa la funzionalità di caricamento file dell'hub IoT di Azure per caricare i file in un account di archiviazione di Azure. Dopo il caricamento di un file, il modulo elimina il file dal disco
Creare un modulo e copiare i file
In Visual Studio Code, selezionare Visualizza>Tavolozza comandi, e quindi cercare e selezionare Python: Select Interpreter (Python: Seleziona interprete).
Selezionare la versione di Python installata, 3.7 o successiva.
Fare clic con il pulsante destro del mouse sulla cartella modules in Visual Studio Code e scegliere Aggiungi modulo IoT Edge.
Scegliere Modulo Python.
Denominare il modulo
avroFileWriter.Quando viene richiesto il repository di immagini Docker, usare lo stesso Registro di sistema usato durante l'aggiunta del modulo Router.
Copiare i file dal modulo di esempio nella soluzione.
copy C:\source\IoTEdgeAndMlSample\EdgeModules\modules\avroFileWriter\*.py C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avroFileWriter\Accettare la sovrascrittura di main.py.
Si noti che filemanager.py e schema.py sono stati aggiunti alla soluzione e main.py è stato aggiornato.
Annotazioni
Quando si apre un file Python, potrebbe essere richiesto di installare pylint. Non è necessario installare il linter per completare questa esercitazione.
Montaggio vincolato per i file di dati
Come accennato in precedenza, il modulo di scrittura si basa sulla presenza di un bind mount per scrivere i file Avro sul file system del dispositivo.
Aggiungere la directory al dispositivo
Nel portale di Azure, avvia la macchina virtuale del dispositivo IoT Edge se non è in esecuzione. Connettersi a esso tramite SSH. La connessione richiede il nome DNS che è possibile copiare dalla pagina di panoramica per la macchina virtuale nel portale di Azure.
ssh -l <user>@<vm name>.<region>.cloudapp.azure.comDopo l'accesso, creare la directory che conterrà i messaggi del dispositivo downstream salvati.
sudo mkdir -p /data/avrofilesAggiornare i permessi della directory per renderla scrivibile dal contenitore.
sudo chmod ugo+rw /data/avrofilesVerificare che la directory disponga ora dell'autorizzazione di scrittura (w) per utente, gruppo e proprietario.
ls -la /data
Aggiungere la directory al modulo
Per aggiungere la directory al contenitore del modulo, verranno modificati i Dockerfile associati al modulo avroFileWriter. Al modulo sono associati tre Dockerfile: Dockerfile.amd64, Dockerfile.amd64.debug e Dockerfile.arm32v7. Questi file devono essere mantenuti sincronizzati nel caso in cui desideriamo eseguire il debug o la distribuzione in un dispositivo arm32. Per questo articolo, concentrarsi solo su Dockerfile.amd64.
Nella macchina virtuale di sviluppo aprire il file C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\Dockerfile.amd64 .
Modificare il file in modo che sia simile all'esempio seguente:
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" ]I
mkdircomandi echownindicano al processo di compilazione Docker di creare una directory di primo livello denominata /avrofiles nell'immagine e quindi rendere il moduloutente il proprietario di tale directory. È importante che questi comandi vengano inseriti dopo l'aggiunta dell'utente del modulo all'immagine con iluseraddcomando e prima che il contesto passi al modulouser (USER moduleuser).Se necessario, apportare le modifiche corrispondenti a Dockerfile.amd64.debug e Dockerfile.arm32v7.
Aggiungere la configurazione di binding ad avroFileWriter
Il passaggio finale della creazione dell'associazione consiste nell'aggiornare i file deployment.template.json (e deployment.debug.template.json) con le informazioni di associazione.
Aprire deployment.template.json.
Modificare la definizione del modulo per avroFileWriter aggiungendo il parametro
Bindsche collega la directory del contenitore /avrofiles alla directory locale sul dispositivo perimetrale. La definizione del modulo deve corrispondere a questo esempio:"avroFileWriter": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "${MODULES.avroFileWriter}", "createOptions": { "HostConfig": { "Binds": [ "/data/avrofiles:/avrofiles" ] } } } }
Montare un vincolo per l'accesso a config.yaml
È necessario aggiungere un altro bind per il modulo writer. Questo binding consente al modulo di leggere la stringa di connessione dal file /etc/iotedge/config.yaml nel dispositivo IoT Edge. È necessaria la stringa di connessione per creare un IoTHubClient in modo che sia possibile chiamare il metodo upload_blob_async per caricare i file nell'hub IoT. I passaggi per l'aggiunta di questo binding sono simili a quelli della sezione precedente.
Aggiornare i permessi della directory
Connettersi al dispositivo IoT Edge usando SSH.
ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.comAggiungere l'autorizzazione di lettura al file config.yaml.
sudo chmod +r /etc/iotedge/config.yamlVerificare che le autorizzazioni siano impostate correttamente.
ls -la /etc/iotedge/Assicurarsi che le autorizzazioni per config.yaml siano -r--r--r---.
Aggiungere la cartella al modulo
Nel computer di sviluppo aprire il file Dockerfile.amd64 .
Aggiungere un set aggiuntivo di
mkdircomandi echownal file in modo che sia simile al seguente: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"]Apportare le modifiche corrispondenti a Dockerfile.amd64.debug e Dockerfile.arm32v7.
Aggiornare la configurazione del modulo
Aprire il file deployment.template.json .
Modificare la definizione del modulo per avroFileWriter aggiungendo una seconda riga al
Bindsparametro che punta la directory del contenitore (/app/iotconfig) alla directory locale nel dispositivo (/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" ] } } } }Apportare le modifiche corrispondenti a deployment.debug.template.json.
Installa le dipendenze
Il modulo writer dipende da due librerie Python, fastavro e PyYAML. È necessario installare le dipendenze nel computer di sviluppo e indicare al processo di compilazione Docker di installarle nell'immagine del modulo.
PyYAML
Nel computer di sviluppo aprire il
C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\requirements.txtfile e aggiungere "pyyaml" in una nuova riga nel file.azure-iothub-device-client~=1.4.3 pyyamlAprire il file Dockerfile.amd64 e aggiungere un
pip installcomando per aggiornare 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" ]Al prompt dei comandi, installare pyyaml nel computer di sviluppo.
pip install pyyaml
Fastavro
In requirements.txtaggiungere fastavro dopo pyyaml.
azure-iothub-device-client~=1.4.3 pyyaml fastavroInstallare fastavro nel computer di sviluppo.
pip install fastavro
Riconfigurare l'hub IoT
Introducendo il dispositivo e i moduli IoT Edge nel sistema, sono state modificate le aspettative su quali dati verranno inviati all'hub e per quali scopi. È necessario riconfigurare il routing nell'hub per gestire la nuova realtà.
Annotazioni
È necessario riconfigurare l'hub prima di distribuire i moduli perché alcune delle impostazioni dell'hub, in particolare il caricamento di file, devono essere configurate correttamente per l'esecuzione corretta del modulo avroFileWriter
Configurare la route per i messaggi URL nell'hub IoT
Con il router e il classificatore in posizione, ci si aspetta di ricevere messaggi regolari contenenti solo l'ID del dispositivo e la previsione RUL per il dispositivo. Vogliamo instradare i dati RUL alla propria posizione di archiviazione dove possiamo monitorare lo stato dei dispositivi, compilare report e generare avvisi secondo necessità. Allo stesso tempo, vogliamo che tutti i dati dei dispositivi che vengono ancora inviati direttamente da un dispositivo a valle che non è ancora collegato a nostro dispositivo IoT Edge continuino a essere instradati verso la posizione attuale di archiviazione.
Creare un percorso di messaggi RUL
Nel portale di Azure passare all'hub IoT.
Dal menu nel riquadro sinistro, in Impostazioni hub selezionare Routing messaggi.
Nella scheda Route selezionare Aggiungi.
Assegnare alla route il nome RulMessageRoute.
Selezionare Aggiungi endpoint a destra del selettore endpoint e scegliere Archiviazione.
Nella pagina Aggiungi un endpoint di archiviazione assegnare all'endpoint il nome ruldata.
Selezionare Seleziona un contenitore.
Nella pagina Account di archiviazione, trova l'account di archiviazione usato in questa esercitazione, chiamato come iotedgeandml<suffisso univoco>.
Selezionare il contenitore ruldata e fare clic su Seleziona.
Nella pagina Aggiungi un endpoint di archiviazione selezionare Crea per creare l'endpoint di archiviazione.
Torna alla pagina Aggiungi una route e per la query di routing sostituisci
truecon la seguente query:IS_DEFINED($body.PredictedRul) AND NOT IS_DEFINED($body.OperationalSetting1)Espandere la sezione Test e quindi la sezione Corpo del messaggio . Sostituire il corpo del messaggio con questo esempio dei messaggi previsti:
{ "ConnectionDeviceId": "aaLeafDevice_1", "CorrelationId": "b27e97bb-06c5-4553-a064-e9ad59c0fdd3", "PredictedRul": 132.62721409309165, "CycleTime": 64.0 }Selezionare Test route. Se il test ha esito positivo, viene visualizzato il messaggio "Il messaggio corrispondeva alla query".
Fare clic su Salva.
Aggiornare il percorso turbofanDeviceDataToStorage
Non vogliamo instradare i nuovi dati previsionali alla vecchia posizione di archiviazione, quindi aggiorna il percorso per evitarlo.
Nella pagina Routing messaggi dell'hub IoT, selezionare la scheda Routes.
Selezionare turbofanDeviceDataToStorage o qualsiasi nome assegnato alla route iniziale dei dati del dispositivo.
Aggiornare la query di routing a
IS_DEFINED($body.OperationalSetting1)Espandere la sezione Test e quindi la sezione Corpo del messaggio . Sostituire il messaggio con questo esempio dei messaggi previsti:
{ "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 }Selezionare Test route. Se il test ha esito positivo, viene visualizzato il messaggio "Il messaggio corrispondeva alla query".
Selezionare Salva.
Configurare il caricamento di file
Configurare la funzionalità di caricamento file dell'hub IoT per consentire al modulo di scrittura file di caricare file nell'archivio.
Dal menu del riquadro sinistro nell'hub IoT, in Impostazioni hub scegliere Caricamento file.
Selezionare Contenitore di archiviazione di Azure.
Selezionare l'account di archiviazione dall'elenco.
Selezionare il contenitore che inizia con azureml-blobstore aggiunto con un GUID e fare clic su Seleziona.
Selezionare Salva. Il portale invia una notifica al completamento del salvataggio.
Annotazioni
Non si attiva la notifica di caricamento per questa esercitazione, ma vedere Ricevere una notifica di caricamento di file per informazioni dettagliate su come gestire la notifica di caricamento dei file.
Compilare, pubblicare e distribuire moduli
Ora che sono state apportate le modifiche alla configurazione, è possibile compilare le immagini e pubblicarle nel Registro Azure Container. Il processo di compilazione usa il file deployment.template.json per determinare quali moduli devono essere compilati. Le impostazioni per ogni modulo, inclusa la versione, sono disponibili nel file module.json nella cartella del modulo. Il processo di compilazione esegue prima una build Docker sui Dockerfile corrispondenti alla configurazione corrente presente nel file module.json per creare un'immagine. Pubblica quindi l'immagine nel Registro di sistema dal file module.json con un tag di versione corrispondente a quello nel file module.json. Infine, produce un manifesto di distribuzione specifico della configurazione (ad esempio, deployment.amd64.json), che verrà distribuito nel dispositivo IoT Edge. Il dispositivo IoT Edge legge le informazioni dal manifesto della distribuzione e, in base alle istruzioni, scarica i moduli, configura le route e imposta le proprietà desiderate. Questo metodo di distribuzione presenta due effetti collaterali che è necessario tenere presente:
Ritardo distribuzione: dal momento che il runtime di IoT Edge deve riconoscere la modifica alle proprietà desiderate prima di iniziare a riconfigurare, può richiedere molto tempo dopo la distribuzione dei moduli fino a quando il runtime non li preleva e inizia ad aggiornare il dispositivo IoT Edge.
Le versioni dei moduli sono importanti: se si pubblica una nuova versione del contenitore di un modulo nel registro contenitori usando gli stessi tag di versione del modulo precedente, il runtime non scaricherà la nuova versione del modulo. Esegue un confronto tra il tag di versione dell'immagine locale e l'immagine desiderata dal manifesto della distribuzione. Se tali versioni corrispondono, il runtime non esegue alcuna azione. È quindi importante incrementare la versione del modulo ogni volta che si desidera distribuire nuove modifiche. Incrementare la versione modificando la proprietà version nella proprietà tag nel file di module.json per il modulo che si sta modificando. Compilare e pubblicare quindi il modulo.
{ "$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" }
Compilare e pubblicare
Nella macchina virtuale di sviluppo avviare Docker se non è in esecuzione.
In Visual Studio Code avviare un nuovo terminale aprendo un prompt dei comandi e accedere al registro Azure Container (ACR).
È possibile trovare i valori necessari per nome utente, password e server di accesso nel portale di Azure. Il nome del registro contenitori ha il formato "turbofandemo<unique id>". Nel menu del riquadro a sinistra, in Impostazioni, selezionare Chiavi di accesso per visualizzarle.
docker login -u <ACR username> -p <ACR password> <ACR login server>
- In Visual Studio Code fare clic con il pulsante destro del mouse su deployment.template.json e scegliere Compila ed esegui il push della soluzione IoT Edge.
Visualizzare i moduli nel Registro di sistema
Al termine della compilazione, sarà possibile usare il portale di Azure per esaminare i moduli pubblicati.
Apri il Registro dei contenitori di Azure per questa esercitazione. Il nome del registro contenitori ha il formato "turbofandemo<unique id>".
Nel menu del riquadro sinistro, in Servizi, selezionare Repository.
Si noti che entrambi i moduli creati, avrofilewriter e turbofanrouter, vengono visualizzati come repository.
Selezionare turbofanrouter e notare che è stata pubblicata un'immagine contrassegnata come 0.0.1-amd64.
Distribuire moduli nel dispositivo IoT Edge
Sono stati compilati e configurati i moduli nella soluzione, ora i moduli verranno distribuiti nel dispositivo IoT Edge.
In Visual Studio Code fare clic con il pulsante destro del mouse sul file deployment.amd64.json nella cartella config.
Scegliere Crea distribuzione per un singolo dispositivo.
Scegli il tuo dispositivo IoT Edge, aaTurboFanEdgeDevice.
Aggiorna il pannello Dispositivi dell'hub IoT di Azure nell'esploratore di Visual Studio Code. Si noterà che i tre nuovi moduli vengono distribuiti ma non ancora in esecuzione.
Eseguire di nuovo l'aggiornamento dopo alcuni minuti e verranno visualizzati i moduli in esecuzione.
Annotazioni
Possono volerci diversi minuti perché i moduli si avviino e raggiungano uno stato di funzionamento stabile. Durante questo periodo, è possibile che i moduli vengano avviati e interrotti quando tentano di stabilire una connessione con il modulo hub IoT Edge.
Diagnosi degli errori
In questa sezione, condividiamo alcune tecniche per comprendere cosa è andato storto con un modulo o dei moduli. Spesso è possibile individuare un errore dallo stato in Visual Studio Code.
Identificare i moduli non riusciti
Visual Studio Code: Esaminare il pannello Dispositivi dell'hub IoT di Azure. Se la maggior parte dei moduli è in esecuzione ma ne viene arrestata una, è necessario analizzare ulteriormente il modulo arrestato. Se tutti i moduli si trovano in uno stato arrestato per un lungo periodo di tempo, può anche indicare un errore.
Portale di Azure: Navigando al tuo hub IoT nel portale e quindi trovando la pagina dei dettagli del dispositivo (in IoT Edge, esplorare il dispositivo) è possibile che un modulo abbia riportato un errore o che non abbia mai segnalato nulla all'hub IoT.
Diagnosi dal dispositivo
Accedendo al dispositivo IoT Edge (la macchina virtuale Linux in questo caso), è possibile accedere a una buona quantità di informazioni sullo stato dei moduli. Il meccanismo principale usato sono i comandi Docker che consentono di esaminare i contenitori e le immagini nel dispositivo.
Accedere al dispositivo IoT Edge:
ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.comElenca tutti i contenitori in esecuzione. Si prevede di visualizzare un contenitore per ogni modulo con un nome che corrisponde al modulo. Questo comando elenca anche l'immagine esatta per il contenitore, inclusa la versione, in modo da poter corrispondere alle aspettative. È anche possibile elencare le immagini sostituendo "image" per "container" nel comando .
sudo docker container lsOttenere i log per un contenitore. Questo comando restituisce qualsiasi elemento scritto in StdErr e StdOut nel contenitore. Questo comando funziona per i contenitori che sono stati avviati e quindi sono morti per qualche motivo. È anche utile per comprendere cosa sta accadendo con i contenitori edgeAgent o edgeHub.
sudo docker container logs <container id>Esaminare un contenitore. Questo comando fornisce un tonno di informazioni sull'immagine. I dati possono essere filtrati a seconda di ciò che si sta cercando. Ad esempio, se si desidera verificare se le associazioni in avroFileWriter sono corrette, è possibile usare il comando :
sudo docker container inspect -f "{{ json .Mounts }}" avroFileWriter | python -m json.toolConnettersi a un container in esecuzione. Questo comando può essere utile se si vuole esaminare il contenitore durante l'esecuzione:
sudo docker exec -it avroFileWriter bash
Pulire le risorse
Questa esercitazione fa parte di un set in cui ogni articolo si basa sul lavoro svolto nei precedenti. Attendere di pulire tutte le risorse fino a quando non si completa l'esercitazione finale.
Passaggi successivi
In questo articolo è stata creata una soluzione IoT Edge in Visual Studio Code con tre moduli: un classificatore, un router e un writer/uploader di file. Sono stati configurati i percorsi per consentire ai moduli di comunicare tra loro nel dispositivo perimetrale. È stata modificata la configurazione del dispositivo perimetrale e sono stati aggiornati i Dockerfile per installare le dipendenze e aggiungere montaggi di binding ai contenitori dei moduli.
Successivamente, è stata aggiornata la configurazione dell'hub IoT per instradare i messaggi in base al tipo e per gestire i caricamenti dei file. Con tutti gli elementi disponibili, i moduli sono stati distribuiti nel dispositivo IoT Edge e sono stati verificati che i moduli siano stati eseguiti correttamente.
Passare all'articolo successivo per iniziare a inviare dati e visualizzare la soluzione in azione.