Samouczek: tworzenie i wdrażanie niestandardowych modułów usługi IoT Edge
Dotyczy: IoT Edge 1.1
Ważne
Data zakończenia wsparcia usługi IoT Edge 1.1 wynosiła 13 grudnia 2022 r. Zapoznaj się z cyklem życia produktów firmy Microsoft, aby uzyskać informacje na temat sposobu obsługi tego produktu lub interfejsu API albo tej usługi lub technologii. Aby uzyskać więcej informacji na temat aktualizowania do najnowszej wersji usługi IoT Edge, zobacz Aktualizowanie usługi IoT Edge.
W tym artykule utworzymy trzy moduły usługi IoT Edge, które odbierają komunikaty z podrzędnych urządzeń IoT, uruchamiają dane za pośrednictwem modelu uczenia maszynowego, a następnie przekazują szczegółowe informacje do usługi IoT Hub.
Centrum usługi IoT Edge ułatwia komunikację modułów. Używanie centrum usługi IoT Edge jako brokera komunikatów utrzymuje moduły niezależne od siebie. Moduły muszą tylko określić dane wejściowe, na których akceptują komunikaty i dane wyjściowe, do których zapisują komunikaty.
Chcemy, aby urządzenie usługi IoT Edge wykonało dla nas cztery czynności:
- Odbieranie danych z urządzeń podrzędnych.
- Przewidywanie pozostałego okresu eksploatacji (RUL) dla urządzenia, które wysłało dane.
- Wyślij komunikat z żądaniem RUL dla urządzenia do usługi IoT Hub. Tę funkcję można zmodyfikować w celu wysyłania danych tylko wtedy, gdy poziom RUL spadnie poniżej określonego poziomu.
- Zapisz dane urządzenia podrzędnego w pliku lokalnym na urządzeniu usługi IoT Edge. Ten plik danych jest okresowo przekazywany do usługi IoT Hub w celu uściślenia trenowania modelu uczenia maszynowego. Korzystanie z przekazywania plików zamiast ciągłego przesyłania strumieniowego komunikatów jest bardziej ekonomiczne.
Aby wykonać te zadania, użyjemy trzech modułów niestandardowych:
Klasyfikator RUL: moduł turboFanRulClassifier utworzony w module Train and deploy an Azure Machine Learning model to standardowy moduł uczenia maszynowego, który uwidacznia dane wejściowe o nazwie "amlInput" i dane wyjściowe o nazwie "amlOutput". Wyrażenie "amlInput" oczekuje, że dane wejściowe będą wyglądać dokładnie tak, jak dane wejściowe wysyłane do usługi internetowej opartej na usłudze ACI. Podobnie wyrażenie "amlOutput" zwraca te same dane co usługa internetowa.
Składnik zapisywania Avro: ten moduł odbiera komunikaty w danych wejściowych "avroModuleInput" i utrwala komunikat w formacie Avro na dysku w celu późniejszego przekazania do usługi IoT Hub.
Moduł routera: moduł routera odbiera komunikaty z urządzeń podrzędnych, a następnie formatuje i wysyła komunikaty do klasyfikatora. Następnie moduł odbiera komunikaty z klasyfikatora i przekazuje komunikat do modułu zapisywania Avro. Na koniec moduł wysyła tylko przewidywanie RUL do usługi IoT Hub.
Wejścia:
- deviceInput: odbiera komunikaty z urządzeń podrzędnych
- rulInput: odbiera komunikaty z "amlOutput"
Wyjść:
- classify: wysyła komunikaty do "amlInput"
- writeAvro: wysyła komunikaty do "avroModuleInput"
- toIotHub: wysyła komunikaty do $upstream, które przekazują komunikaty do połączonego centrum IoT Hub
Na poniższym diagramie przedstawiono moduły, dane wejściowe, dane wyjściowe i trasy usługi IoT Edge Hub dla pełnego rozwiązania:
Kroki opisane w tym artykule są zwykle wykonywane przez dewelopera rozwiązań w chmurze.
W tej sekcji samouczka dowiesz się, jak wykonywać następujące działania:
- Utwórz moduł usługi IoT Edge na podstawie kodu niestandardowego.
- Wygeneruj obraz platformy Docker na podstawie modułu niestandardowego.
- Skonfiguruj ponownie routing usługi IoT Hub w celu obsługi modułów niestandardowych.
- Kompilowanie, publikowanie i wdrażanie modułów niestandardowych.
Wymagania wstępne
Ten artykuł jest częścią serii samouczka dotyczącego korzystania z usługi Azure Machine Learning w usłudze IoT Edge. Każdy artykuł z serii opiera się na pracy w poprzednim artykule. Jeśli dotarłeś bezpośrednio do tego artykułu, odwiedź pierwszy artykuł z serii.
Tworzenie nowego rozwiązania usługi IoT Edge
Podczas wykonywania drugiego z naszych dwóch notesów platformy Azure utworzyliśmy i opublikowaliśmy obraz kontenera zawierający nasz model RUL. Usługa Azure Machine Learning, w ramach procesu tworzenia obrazu, spakował ten model, aby obraz był wdrażany jako moduł usługi Azure IoT Edge.
W tym kroku utworzymy rozwiązanie usługi Azure IoT Edge przy użyciu modułu "Azure Machine Learning" i wskażemy moduł do obrazu opublikowanego przy użyciu usługi Azure Notebooks.
Otwórz sesję pulpitu zdalnego na maszynie wirtualnej dewelopera.
Otwórz folder C:\source\IoTEdgeAndMlSample w programie Visual Studio Code.
Kliknij prawym przyciskiem myszy panel eksploratora (w pustym miejscu) i wybierz pozycję Nowe rozwiązanie usługi IoT Edge.
Zaakceptuj domyślną nazwę rozwiązania EdgeSolution.
Wybierz usługę Azure Machine Learning jako szablon modułu.
Nadaj modułowi nazwę turbofanRulClassifier.
Wybierz obszar roboczy uczenia maszynowego. Ten obszar roboczy to obszar roboczy turboFanDemo utworzony w artykule Samouczek: trenowanie i wdrażanie modelu usługi Azure Machine Learning
Wybierz obraz utworzony podczas uruchamiania usługi Azure Notebook.
Przyjrzyj się rozwiązaniu i zwróć uwagę na pliki, które zostały utworzone:
deployment.template.json: ten plik zawiera definicję poszczególnych modułów w rozwiązaniu. W tym pliku należy zwrócić uwagę na trzy sekcje:
Poświadczenia rejestru: definiuje zestaw niestandardowych rejestrów kontenerów używanych w rozwiązaniu. W tej chwili powinien zawierać rejestr z obszaru roboczego uczenia maszynowego, czyli miejsce przechowywania obrazu usługi Azure Machine Learning. Można mieć dowolną liczbę rejestrów kontenerów, ale dla uproszczenia użyjemy tego rejestru dla wszystkich modułów.
"registryCredentials": { "<your registry>": { "username": "$CONTAINER_REGISTRY_USERNAME_<your registry>", "password": "$CONTAINER_REGISTRY_PASSWORD_<your registry>", "address": "<your registry>.azurecr.io" } }
Moduły: ta sekcja zawiera zestaw modułów zdefiniowanych przez użytkownika, które są dostępne w tym rozwiązaniu. Definicja modułu turbofanRulClassifier wskazuje obraz w rejestrze kontenerów. W miarę dodawania kolejnych modułów do rozwiązania będą one wyświetlane w tej sekcji.
"modules": { "turbofanRulClassifier": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "turbofandemo2cd74296.azurecr.io/edgemlsample:1", "createOptions": {} } } }
Trasy: będziemy pracować z trasami dość sporo w tym samouczku. Trasy definiują sposób komunikowania się modułów ze sobą. Istniejąca trasa zdefiniowana przez szablon nie jest zgodna z potrzebnym routingiem.
turbofanRulClassifierToIoTHub
Usuń trasę."$edgeHub": { "properties.desired": { "schemaVersion": "1.0", "routes": { "turbofanRulClassifierToIoTHub": "FROM /messages/modules/turbofanRulClassifier/outputs/* INTO $upstream" }, "storeAndForwardConfiguration": { "timeToLiveSecs": 7200 } } }
deployment.debug.template.json: ten plik jest wersją debugowania deployment.template.json. Zazwyczaj należy zachować synchronizację tego pliku z zawartością pliku deployment.template.json, ale nie jest to wymagane w tym samouczku.
.env: ten plik to miejsce, w którym należy podać nazwę użytkownika i hasło na potrzeby uzyskiwania dostępu do rejestru.
CONTAINER_REGISTRY_USERNAME_<your registry name>=<ACR username> CONTAINER_REGISTRY_PASSWORD_<your registry name>=<ACR password>
Uwaga
W tym samouczku są używane poświadczenia logowania administratora dla usługi Azure Container Registry, które są wygodne w scenariuszach tworzenia i testowania. Gdy wszystko będzie gotowe do scenariuszy produkcyjnych, zalecamy opcję uwierzytelniania z najmniejszymi uprawnieniami, taką jak jednostki usługi. Aby uzyskać więcej informacji, zobacz Zarządzanie dostępem do rejestru kontenerów.
Kliknij prawym przyciskiem myszy plik deployment.template.json w Eksploratorze programu Visual Studio Code i wybierz pozycję Kompiluj rozwiązanie usługi IoT Edge.
Zwróć uwagę, że to polecenie tworzy folder konfiguracji z plikiem deployment.amd64.json. Ten plik jest konkretnym szablonem wdrożenia dla rozwiązania.
Dodawanie modułu routera
Następnie dodamy moduł Router do naszego rozwiązania. Moduł Router obsługuje kilka obowiązków związanych z naszym rozwiązaniem:
- Odbieranie komunikatów z urządzeń podrzędnych: gdy komunikaty docierają do urządzenia usługi IoT Edge z urządzeń podrzędnych, moduł Router odbiera komunikat i rozpoczyna organizowanie routingu komunikatu.
- Wysyłanie komunikatów do modułu klasyfikatora RUL: po odebraniu nowego komunikatu z urządzenia podrzędnego moduł Router przekształca komunikat w format oczekiwany przez klasyfikator RUL. Router wysyła komunikat do klasyfikatora RUL na potrzeby przewidywania RUL. Po dokonaniu przewidywania klasyfikator wysyła komunikat z powrotem do modułu Router.
- Wysyłanie komunikatów RUL do usługi IoT Hub: gdy router odbiera komunikaty z klasyfikatora, przekształca komunikat tak, aby zawierał tylko podstawowe informacje, identyfikator urządzenia i RUL oraz wysyła skrócony komunikat do centrum IoT. Dalsze uściślenie, którego nie zrobiliśmy w tym miejscu, spowoduje wysłanie komunikatów do usługi IoT Hub tylko wtedy, gdy przewidywanie RUL spadnie poniżej progu (na przykład wtedy, gdy wartość RUL jest mniejsza niż 100 cykli). Filtrowanie w ten sposób zmniejszy ilość komunikatów i zmniejszy koszty centrum IoT Hub.
- Wyślij komunikat do modułu zapisywania Avro: aby zachować wszystkie dane wysyłane przez urządzenie podrzędne, moduł Router wysyła cały komunikat odebrany z klasyfikatora do modułu zapisywania Avro, który będzie utrwalać i przekazywać dane przy użyciu przekazywania pliku usługi IoT Hub.
Moduł Router jest ważnym elementem rozwiązania, który zapewnia przetwarzanie komunikatów w odpowiedniej kolejności.
Tworzenie modułu i kopiowanie plików
Kliknij prawym przyciskiem myszy folder modules w programie Visual Studio Code i wybierz polecenie Dodaj moduł usługi IoT Edge.
Wybierz moduł języka C# dla szablonu modułu.
Nadaj modułowi nazwę turbofanRouter.
Po wyświetleniu monitu o repozytorium obrazów platformy Docker użyj rejestru z obszaru roboczego uczenia maszynowego (rejestr można znaleźć w węźle registryCredentials pliku deployment.template.json ). Ta wartość jest w pełni kwalifikowanym adresem rejestru, takim jak rejestr.azurecr.io/turbofanrouter>.<
Uwaga
W tym artykule użyjemy usługi Azure Container Registry utworzonej przez obszar roboczy usługi Azure Machine Learning. Jest to wyłącznie dla wygody. Mogliśmy utworzyć nowy rejestr kontenerów i opublikować tam nasze moduły.
W terminalu przy użyciu powłoki wiersza polecenia skopiuj pliki z przykładowego modułu do rozwiązania.
copy c:\source\IoTEdgeAndMlSample\EdgeModules\modules\turbofanRouter\*.cs c:\source\IoTEdgeAndMlSample\EdgeSolution\modules\turbofanRouter\
Zaakceptuj monit o zastąpienie pliku program.cs.
Moduł routera kompilacji
W programie Visual Studio Code wybierz pozycję Terminal>Skonfiguruj domyślne zadanie kompilacji.
Wybierz pozycję Utwórz plik tasks.json z szablonu.
Wybierz pozycję .NET Core.
Zastąp zawartość tasks.json następującym kodem.
{ "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" } ] }
Zapisz i zamknij tasks.json.
Uruchom kompilację za pomocą polecenia lub uruchom zadanie kompilacji terminalu>.
Ctrl + Shift + B
Konfigurowanie tras modułów
Jak wspomniano powyżej, środowisko uruchomieniowe usługi IoT Edge używa tras skonfigurowanych w pliku deployment.template.json do zarządzania komunikacją między luźno powiązanymi modułami. W tej sekcji dowiesz się, jak skonfigurować trasy dla modułu turbofanRouter. Najpierw omówimy trasy wejściowe, a następnie przejdziemy do danych wyjściowych.
Dane wejściowe
W metodzie Init() Program.cs rejestrujemy dwa wywołania zwrotne dla modułu:
await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromLeafDevice, LeafDeviceInputMessageHandler, ioTHubModuleClient); await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromClassifier, ClassifierCallbackMessageHandler, ioTHubModuleClient);
Pierwsze wywołanie zwrotne nasłuchuje komunikatów wysyłanych do ujścia urządzeniaInput . Na powyższym diagramie widać, że chcemy kierować komunikaty z dowolnego urządzenia podrzędnego do tych danych wejściowych. W pliku deployment.template.json dodaj trasę, która nakazuje centrum brzegowemu kierowanie jakichkolwiek komunikatów odebranych przez urządzenie usługi IoT Edge, które nie zostało wysłane przez moduł usługi IoT Edge do danych wejściowych o nazwie "deviceInput" w module turbofanRouter:
"leafMessagesToRouter": "FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/deviceInput\")"
Następnie dodaj trasę dla komunikatów z modułu rulClassifier do modułu turbofanRouter:
"classifierToRouter": "FROM /messages/modules/turbofanRulClassifier/outputs/amloutput INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/rulInput\")"
Dane wyjściowe
Dodaj cztery dodatkowe trasy do parametru trasy $edgeHub, aby obsługiwać dane wyjściowe z modułu Router.
Program.cs definiuje metodę SendMessageToClassifier(), która używa klienta modułu do wysyłania komunikatu do klasyfikatora RUL przy użyciu trasy:
"routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")"
Funkcja SendRulMessageToIotHub() używa klienta modułu do wysyłania tylko danych RUL dla urządzenia do usługi IoT Hub za pośrednictwem trasy:
"routerToIoTHub": "FROM /messages/modules/turboFanRouter/outputs/hubOutput INTO $upstream"
Funkcja SendMessageToAvroWriter() używa klienta modułu do wysyłania komunikatu z danymi RUL dodanymi do modułu avroFileWriter.
"routerToAvro": "FROM /messages/modules/turbofanRouter/outputs/avroOutput INTO BrokeredEndpoint(\"/modules/avroFileWriter/inputs/avroModuleInput\")"
Funkcja HandleBadMessage() wysyła komunikaty, które zakończyły się niepowodzeniem, nadrzędnie przesyłają do usługi IoT Hub, gdzie można je kierować później.
"deadLetter": "FROM /messages/modules/turboFanRouter/outputs/deadMessages INTO $upstream"
Po połączeniu wszystkich tras węzeł "$edgeHub" powinien wyglądać podobnie do następującego kodu 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
}
}
}
Uwaga
Dodanie modułu turbofanRouter spowodowało utworzenie następującej dodatkowej trasy: turbofanRouterToIoTHub": "FROM /messages/modules/turbofanRouter/outputs/* INTO $upstream
. Usuń tę trasę, pozostawiając tylko trasy wymienione powyżej w pliku deployment.template.json.
Dodawanie modułu zapisywania Avro
Moduł zapisywania Avro ma dwie obowiązki w naszym rozwiązaniu do przechowywania komunikatów i przekazywania plików.
Przechowuj komunikaty: gdy moduł zapisywania Avro odbiera komunikat, zapisuje komunikat w lokalnym systemie plików w formacie Avro. Używamy instalacji powiązania, która instaluje katalog (w tym przypadku /data/avrofiles) do ścieżki w kontenerze modułu. Ta instalacja umożliwia modułowi zapisywanie w ścieżce lokalnej (/avrofiles) i udostępnienie tych plików bezpośrednio z urządzenia usługi IoT Edge.
Przekazywanie plików: moduł zapisywania Avro używa funkcji przekazywania plików usługi Azure IoT Hub do przekazywania plików na konto usługi Azure Storage. Po pomyślnym przekazaniu pliku moduł usuwa plik z dysku
Tworzenie modułu i kopiowanie plików
W programie Visual Studio Code wybierz pozycję Wyświetl>paletę poleceń, a następnie wyszukaj i wybierz pozycję Python: Wybierz interpreter.
Wybierz zainstalowaną wersję języka Python w wersji 3.7 lub nowszej.
Kliknij prawym przyciskiem myszy folder modules w programie Visual Studio Code i wybierz polecenie Dodaj moduł usługi IoT Edge.
Wybierz pozycję Moduł Python.
Nadaj modułowi
avroFileWriter
nazwę .Po wyświetleniu monitu o repozytorium obrazów platformy Docker użyj tego samego rejestru, który był używany podczas dodawania modułu Router.
Skopiuj pliki z przykładowego modułu do rozwiązania.
copy C:\source\IoTEdgeAndMlSample\EdgeModules\modules\avroFileWriter\*.py C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avroFileWriter\
Zaakceptuj zastąpienie main.py.
Zwróć uwagę, że filemanager.py i schema.py zostały dodane do rozwiązania i main.py zostały zaktualizowane.
Uwaga
Po otwarciu pliku języka Python może zostać wyświetlony monit o zainstalowanie narzędzia pylint. Aby ukończyć ten samouczek, nie trzeba instalować narzędzia linter.
Wiązanie instalacji dla plików danych
Jak wspomniano wcześniej, moduł zapisywania opiera się na obecności instalacji powiązanej, aby zapisywać pliki Avro w systemie plików urządzenia.
Dodawanie katalogu do urządzenia
W witrynie Azure Portal uruchom maszynę wirtualną urządzenia usługi IoT Edge, jeśli nie jest uruchomiona. Połącz się z nim przy użyciu protokołu SSH. Połączenie wymaga nazwy DNS, którą można skopiować ze strony przeglądu maszyny wirtualnej w witrynie Azure Portal.
ssh -l <user>@<vm name>.<region>.cloudapp.azure.com
Po zalogowaniu utwórz katalog, w ramach którego będą przechowywane zapisane komunikaty urządzenia podrzędnego.
sudo mkdir -p /data/avrofiles
Zaktualizuj uprawnienia katalogu, aby umożliwić zapisywanie go przez kontener.
sudo chmod ugo+rw /data/avrofiles
Sprawdź, czy katalog ma teraz uprawnienie do zapisu (w) dla użytkownika, grupy i właściciela.
ls -la /data
Dodawanie katalogu do modułu
Aby dodać katalog do kontenera modułu, zmodyfikujemy pliki Dockerfile skojarzone z modułem avroFileWriter. Istnieją trzy pliki Dockerfile skojarzone z modułem: Dockerfile.amd64, Dockerfile.amd64.debug i Dockerfile.arm32v7. Te pliki powinny być synchronizowane w przypadku, gdy chcemy debugować lub wdrażać na urządzeniu arm32. W tym artykule skoncentruj się tylko na pliku Dockerfile.amd64.
Na maszynie wirtualnej dewelopera otwórz plik C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\Dockerfile.amd64 .
Zmodyfikuj plik tak, aby wyglądał jak w poniższym przykładzie:
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" ]
Polecenia
mkdir
ichown
instruują proces kompilacji platformy Docker, aby utworzyć katalog najwyższego poziomu o nazwie /avrofiles na obrazie, a następnie, aby użytkownik modułu był właścicielem tego katalogu. Ważne jest, aby te polecenia były wstawiane po dodaniu użytkownika modułu do obrazu zauseradd
pomocą polecenia i przed przełączenia kontekstu do użytkownika modułu (USER moduleuser).W razie potrzeby wprowadź odpowiednie zmiany w plikach Dockerfile.amd64.debug i Dockerfile.arm32v7.
Dodawanie konfiguracji powiązania do elementu avroFileWriter
Ostatnim krokiem tworzenia powiązania jest zaktualizowanie plików deployment.template.json (i deployment.debug.template.json) przy użyciu informacji o powiązaniu.
Otwórz deployment.template.json.
Zmodyfikuj definicję modułu avroFileWriter, dodając
Binds
parametr wskazujący katalog kontenera /avrofiles do katalogu lokalnego na urządzeniu brzegowym. Definicja modułu powinna być zgodna z tym przykładem:"avroFileWriter": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "${MODULES.avroFileWriter}", "createOptions": { "HostConfig": { "Binds": [ "/data/avrofiles:/avrofiles" ] } } } }
Wiązanie instalacji w celu uzyskania dostępu do pliku config.yaml
Musimy dodać jeszcze jedno powiązanie dla modułu zapisywania. To powiązanie zapewnia modułowi dostęp do odczytu parametry połączenia z pliku /etc/iotedge/config.yaml na urządzeniu usługi IoT Edge. Potrzebujemy parametry połączenia, aby utworzyć obiekt IoTHubClient, aby umożliwić wywołanie metody upload_blob_async w celu przekazania plików do centrum IoT. Kroki dodawania tego powiązania są podobne do tych w poprzedniej sekcji.
Aktualizowanie uprawnień do katalogu
Nawiąż połączenie z urządzeniem usługi IoT Edge przy użyciu protokołu SSH.
ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
Dodaj uprawnienie do odczytu do pliku config.yaml.
sudo chmod +r /etc/iotedge/config.yaml
Sprawdź, czy uprawnienia są ustawione poprawnie.
ls -la /etc/iotedge/
Upewnij się, że uprawnienia dla pliku config.yaml to -r--r--r--.
Dodawanie katalogu do modułu
Na komputerze deweloperskim otwórz plik Dockerfile.amd64 .
Dodaj dodatkowy zestaw
mkdir
poleceń ichown
do pliku, aby wyglądał następująco: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"]
Wprowadź odpowiednie zmiany w plikach Dockerfile.amd64.debug i Dockerfile.arm32v7.
Aktualizowanie konfiguracji modułu
Otwórz plik deployment.template.json.
Zmodyfikuj definicję modułu avroFileWriter, dodając drugi wiersz do
Binds
parametru, który wskazuje katalog kontenera (/app/iotconfig) do katalogu lokalnego na urządzeniu (/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" ] } } } }
Wprowadź odpowiednie zmiany w deployment.debug.template.json.
Instalowanie zależności
Moduł zapisywania przyjmuje zależność od dwóch bibliotek języka Python, fastavro i PyYAML. Musimy zainstalować zależności na maszynie deweloperskiej i poinstruować proces kompilacji platformy Docker, aby zainstalować je na obrazie naszego modułu.
PyYAML
Na maszynie deweloperów otwórz
C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\requirements.txt
plik i dodaj "pyaml" w nowym wierszu w pliku.azure-iothub-device-client~=1.4.3 pyyaml
Otwórz plik Dockerfile.amd64 i dodaj
pip install
polecenie , aby uaktualnić narzędzia 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" ]
W wierszu polecenia zainstaluj plik pyyaml na maszynie dewelopera.
pip install pyyaml
Fastavro
W requirements.txt dodaj fastavro po pyaml.
azure-iothub-device-client~=1.4.3 pyyaml fastavro
Zainstaluj program fastavro na maszynie deweloperów.
pip install fastavro
Ponowne konfigurowanie usługi IoT Hub
Wprowadzając urządzenie i moduły usługi IoT Edge do systemu, zmieniliśmy nasze oczekiwania dotyczące tego, jakie dane będą wysyłane do centrum i w jakim celu. Musimy ponownie skonfigurować routing w centrum, aby poradzić sobie z naszą nową rzeczywistością.
Uwaga
Ponownie skonfigurujemy centrum przed wdrożeniem modułów, ponieważ niektóre ustawienia centrum, w szczególności przekazywanie plików, muszą być poprawnie skonfigurowane, aby moduł avroFileWriter działał poprawnie
Konfigurowanie trasy dla komunikatów RUL w usłudze IoT Hub
W przypadku routera i klasyfikatora spodziewamy się otrzymywać regularne komunikaty zawierające tylko identyfikator urządzenia i przewidywanie RUL dla urządzenia. Chcemy kierować dane RUL do własnej lokalizacji przechowywania, w której możemy monitorować stan urządzeń, tworzyć raporty i wyzwalać alerty zgodnie z potrzebami. Jednocześnie chcemy, aby wszystkie dane urządzenia, które są nadal wysyłane bezpośrednio przez urządzenie podrzędne, które nie zostało jeszcze dołączone do naszego urządzenia usługi IoT Edge, nadal będą kierowane do bieżącej lokalizacji magazynu.
Tworzenie trasy komunikatów RUL
W witrynie Azure Portal przejdź do usługi IoT Hub.
Z menu w okienku po lewej stronie w obszarze Ustawienia centrum wybierz pozycję Routing komunikatów.
Na karcie Trasy wybierz pozycję Dodaj.
Nadaj trasie nazwę RulMessageRoute.
Wybierz pozycję Dodaj punkt końcowy z prawej strony selektora punktów końcowych i wybierz pozycję Magazyn.
Na stronie Dodawanie punktu końcowego magazynu nadaj punktowi końcowego nazwę ruldata punktu końcowego.
Wybierz pozycję Wybierz kontener.
Na stronie Konta magazynu znajdź konto magazynu używane w tym samouczku, które nosi nazwę iotedgeandml <unikatową sufiks>.
Wybierz kontener ruldata i kliknij pozycję Wybierz.
Po powrocie na stronę Dodawanie punktu końcowego magazynu wybierz pozycję Utwórz , aby utworzyć punkt końcowy magazynu.
Po powrocie na stronę Dodawanie trasy dla zapytania routingu zastąp
true
ciąg następującym zapytaniem:IS_DEFINED($body.PredictedRul) AND NOT IS_DEFINED($body.OperationalSetting1)
Rozwiń sekcję Test, a następnie sekcję Treść komunikatu. Zastąp treść wiadomości tym przykładem naszych oczekiwanych komunikatów:
{ "ConnectionDeviceId": "aaLeafDevice_1", "CorrelationId": "b27e97bb-06c5-4553-a064-e9ad59c0fdd3", "PredictedRul": 132.62721409309165, "CycleTime": 64.0 }
Wybierz pozycję Testuj trasę. Jeśli test zakończy się pomyślnie, zostanie wyświetlony komunikat "Komunikat pasował do zapytania".
Kliknij przycisk Zapisz.
Aktualizowanie trasy turbofanDeviceDataToStorage
Nie chcemy kierować nowych danych przewidywania do naszej starej lokalizacji przechowywania, więc zaktualizuj trasę, aby jej zapobiec.
Na stronie Routing komunikatów usługi IoT Hub wybierz kartę Trasy.
Wybierz pozycję turbofanDeviceDataToStorage lub dowolną nazwę nadaną początkowej trasie danych urządzenia.
Aktualizowanie zapytania routingu do
IS_DEFINED($body.OperationalSetting1)
Rozwiń sekcję Test, a następnie sekcję Treść komunikatu. Zastąp komunikat tym przykładem naszych oczekiwanych komunikatów:
{ "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 }
Wybierz pozycję Testuj trasę. Jeśli test zakończy się pomyślnie, zostanie wyświetlony komunikat "Komunikat pasował do zapytania".
Wybierz pozycję Zapisz.
Konfigurowanie przekazywania plików
Skonfiguruj funkcję przekazywania plików usługi IoT Hub, aby umożliwić modułowi zapisywania plików przekazywanie plików do magazynu.
W menu okienka po lewej stronie w usłudze IoT Hub w obszarze Ustawienia centrum wybierz pozycję Przekaż plik.
Wybierz pozycję Kontener usługi Azure Storage.
Wybierz konto magazynu z listy.
Wybierz kontener rozpoczynający się od usługi azureml-blobstore z dołączonym identyfikatorem GUID, a następnie kliknij pozycję Wybierz.
Wybierz pozycję Zapisz. Portal powiadamia o zakończeniu zapisywania.
Uwaga
Nie włączamy powiadomienia o przekazaniu dla tego samouczka, ale zobacz Odbieranie powiadomienia o przekazaniu pliku, aby uzyskać szczegółowe informacje na temat obsługi powiadomień dotyczących przekazywania plików.
Kompilowanie, publikowanie i wdrażanie modułów
Teraz, gdy wprowadziliśmy zmiany konfiguracji, możemy przystąpić do kompilowania obrazów i publikowania ich w rejestrze kontenerów platformy Azure. Proces kompilacji używa pliku deployment.template.json do określenia, które moduły należy skompilować. Ustawienia dla każdego modułu, w tym wersji, znajdują się w pliku module.json w folderze modułu. Proces kompilacji najpierw uruchamia kompilację platformy Docker na plikach Dockerfile pasujących do bieżącej konfiguracji znajdującej się w pliku module.json w celu utworzenia obrazu. Następnie publikuje obraz w rejestrze z pliku module.json z tagiem wersji pasującym do tego w pliku module.json. Na koniec tworzy manifest wdrożenia specyficzny dla konfiguracji (na przykład deployment.amd64.json), który zostanie wdrożony na urządzeniu usługi IoT Edge. Urządzenie usługi IoT Edge odczytuje informacje z manifestu wdrożenia, a na podstawie instrukcji pobierze moduły, skonfiguruje trasy i ustawi wszelkie żądane właściwości. Ta metoda wdrażania ma dwa skutki uboczne, o których należy pamiętać:
Opóźnienie wdrożenia: ponieważ środowisko uruchomieniowe usługi IoT Edge musi rozpoznać zmianę żądanych właściwości przed rozpoczęciem ponownej konfiguracji, może upłynąć trochę czasu po wdrożeniu modułów, dopóki środowisko uruchomieniowe nie uruchomi ich i zacznie aktualizować urządzenie usługi IoT Edge.
Wersje modułów mają znaczenie: jeśli opublikujesz nową wersję kontenera modułu w rejestrze kontenerów przy użyciu tych samych tagów wersji co poprzedni moduł, środowisko uruchomieniowe nie pobierze nowej wersji modułu. Wykonuje porównanie tagu wersji obrazu lokalnego i żądanego obrazu z manifestu wdrożenia. Jeśli te wersje są zgodne, środowisko uruchomieniowe nie podejmuje żadnej akcji. Dlatego ważne jest, aby zwiększać wersję modułu za każdym razem, gdy chcesz wdrożyć nowe zmiany. Zwiększ wersję, zmieniając właściwość version we właściwości tagu w pliku module.json dla zmienianych modułów. Następnie skompiluj i opublikuj moduł.
{ "$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" }
Kompilowanie i publikowanie
Na maszynie wirtualnej dewelopera uruchom platformę Docker, jeśli nie jest uruchomiona.
W programie Visual Studio Code uruchom nowy terminal z wierszem polecenia i zaloguj się do rejestru kontenerów platformy Azure (ACR).
Wymagane wartości nazwy użytkownika, hasła i serwera logowania można znaleźć w witrynie Azure Portal. Nazwa rejestru kontenerów ma format "turbofandemo<unique id>". W menu okienka po lewej stronie w obszarze Ustawienia wybierz pozycję Klucze dostępu, aby je wyświetlić.
docker login -u <ACR username> -p <ACR password> <ACR login server>
- W programie Visual Studio Code kliknij prawym przyciskiem myszy pozycję deployment.template.json i wybierz pozycję Kompiluj i wypychaj rozwiązanie usługi IoT Edge.
Wyświetlanie modułów w rejestrze
Po pomyślnym zakończeniu kompilacji będziemy mogli przejrzeć opublikowane moduły za pomocą witryny Azure Portal.
Otwórz usługę Azure Container Registry na potrzeby tego samouczka. Nazwa rejestru kontenerów ma format "turbofandemo<unique id>".
W menu okienka po lewej stronie w obszarze Usługi wybierz pozycję Repozytoria.
Pamiętaj, że oba utworzone moduły avrofilewriter i turbofanrouter są wyświetlane jako repozytoria.
Wybierz turbofanrouter i zwróć uwagę, że opublikowano jeden obraz oznaczony jako 0.0.1-amd64.
Wdrażanie modułów na urządzeniu usługi IoT Edge
Skompilowaliśmy i skonfigurowaliśmy moduły w naszym rozwiązaniu, a teraz wdrożymy moduły na urządzeniu usługi IoT Edge.
W programie Visual Studio Code kliknij prawym przyciskiem myszy plik deployment.amd64.json w folderze konfiguracji.
Wybierz pozycję Utwórz wdrożenie dla pojedynczego urządzenia.
Wybierz urządzenie usługi IoT Edge, aaTurboFanEdgeDevice.
Odśwież panel urządzenia usługi Azure IoT Hub w Eksploratorze programu Visual Studio Code. Powinny zostać wyświetlone trzy nowe moduły, ale nie są jeszcze uruchomione.
Odśwież ponownie po kilku minutach i zobaczysz uruchomione moduły.
Uwaga
Uruchomienie modułów i osiedlenie się w stanie stabilnego działania może potrwać kilka minut. W tym czasie moduły mogą być uruchamiane i zatrzymywane podczas próby nawiązania połączenia z modułem centrum usługi IoT Edge.
Diagnozowanie błędów
W tej sekcji udostępniamy kilka technik zrozumienia, co poszło nie tak z modułem lub modułami. Często można najpierw wykryć błąd ze stanu w programie Visual Studio Code.
Identyfikowanie modułów, które zakończyły się niepowodzeniem
Visual Studio Code: zapoznaj się z panelem urządzeń usługi Azure IoT Hub. Jeśli większość modułów jest w stanie uruchomienia, ale jeden został zatrzymany, należy dokładniej zbadać ten zatrzymany moduł. Jeśli wszystkie moduły są w stanie zatrzymanym przez długi czas, może również wskazywać na awarię.
Witryna Azure Portal: przechodząc do centrum IoT Hub w portalu, a następnie wyszukując stronę szczegółów urządzenia (w obszarze usługi IoT Edge przejdź do szczegółów urządzenia), możesz stwierdzić, że moduł zgłosił błąd lub nigdy nie zgłosił niczego w centrum IoT Hub.
Diagnozowanie z urządzenia
Logując się do urządzenia usługi IoT Edge (maszyna wirtualna z systemem Linux w naszym przypadku), możesz uzyskać dostęp do dużej ilości informacji o stanie modułów. Głównym mechanizmem, którego używamy, są polecenia platformy Docker, które pozwalają nam badać kontenery i obrazy na urządzeniu.
Zaloguj się do urządzenia usługi IoT Edge:
ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
Wyświetl listę wszystkich uruchomionych kontenerów. Oczekujemy, że kontener dla każdego modułu będzie mieć nazwę odpowiadającą modułowi. Ponadto to polecenie wyświetla dokładny obraz kontenera, w tym wersję, aby można było dopasować je do oczekiwań. Możesz również wyświetlić listę obrazów, podstawiając ciąg "image" dla "kontenera" w poleceniu .
sudo docker container ls
Pobierz dzienniki dla kontenera. To polecenie generuje dane wyjściowe dowolnego zapisu w plikach StdErr i StdOut w kontenerze. To polecenie działa w przypadku kontenerów, które zostały uruchomione, a następnie zmarły z jakiegoś powodu. Warto również zrozumieć, co dzieje się z kontenerami edgeAgent lub edgeHub.
sudo docker container logs <container id>
Sprawdzanie kontenera. To polecenie udostępnia mnóstwo informacji o obrazie. Dane można filtrować w zależności od tego, czego szukasz. Jeśli na przykład chcesz sprawdzić, czy powiązania w pliku avroFileWriter są poprawne, możesz użyć polecenia :
sudo docker container inspect -f "{{ json .Mounts }}" avroFileWriter | python -m json.tool
Nawiąż połączenie z uruchomionym kontenerem. To polecenie może być przydatne, jeśli chcesz zbadać kontener podczas jego działania:
sudo docker exec -it avroFileWriter bash
Czyszczenie zasobów
Ten samouczek jest częścią zestawu, w którym każdy artykuł opiera się na pracy wykonanej w poprzednich. Poczekaj, aż ukończysz ostatni samouczek, zaczekaj na wyczyszczenie wszystkich zasobów.
Następne kroki
W tym artykule utworzyliśmy rozwiązanie usługi IoT Edge w programie Visual Studio Code z trzema modułami: klasyfikatorem, routerem i modułem zapisywania/przekazywania plików. Skonfigurujemy trasy, aby umożliwić modułom komunikowanie się ze sobą na urządzeniu brzegowym. Zmodyfikowaliśmy konfigurację urządzenia brzegowego i zaktualizowaliśmy pliki Dockerfile w celu zainstalowania zależności i dodania powiązań instalacji do kontenerów modułów.
Następnie zaktualizowaliśmy konfigurację usługi IoT Hub, aby kierować komunikaty na podstawie typu i obsługiwać przekazywanie plików. Po wdrożeniu wszystkich modułów na urządzeniu usługi IoT Edge upewniliśmy się, że moduły działają prawidłowo.
Przejdź do następnego artykułu, aby rozpocząć wysyłanie danych i zobaczyć rozwiązanie w działaniu.