適用於:
IoT Edge 1.1
這很重要
IoT Edge 1.1 終止支援日期為 2022 年 12 月 13 日。 如需此產品、服務、技術或 API 的支援資訊,請參閱 Microsoft 產品生命週期。 如需更新至最新版 IoT Edge 的詳細資訊,請參閱 更新 IoT Edge。
在本文中,我們會建立三個IoT Edge模組,以接收來自下游IoT裝置的訊息、透過機器學習模型執行數據,然後將深入解析轉送至IoT中樞。
IoT Edge 中樞會促進模組與模組之間的通訊。 使用IoT Edge中樞作為訊息代理程式,讓模組彼此獨立。 模組只需要指定其接受訊息的輸入,以及其寫入訊息的輸出。
我們希望IoT Edge裝置為我們完成四項工作:
- 從下游裝置接收數據。
- 預測傳送數據之裝置的剩餘使用時間 (RUL)。
- 使用裝置的 RUL 將訊息傳送至 IoT 中樞。 只有在 RUL 低於指定的層級時,才能修改此函式以傳送數據。
- 將下游裝置數據儲存至IoT Edge裝置上的本機檔案。 此數據檔會定期上傳至IoT中樞,以精簡機器學習模型的定型。 使用檔案上傳而不是持續訊息串流會更具成本效益。
若要完成這些工作,我們會使用三個自定義模組:
RUL 分類器: 我們在 定型和部署 Azure Machine Learning 模型中 建立的 turboFanRulClassifier 模組是標準機器學習模組,其會公開名為 “amlInput” 的輸入,以及稱為 “amlOutput” 的輸出。 “amlInput” 預期其輸入看起來與我們傳送至 ACI 型 Web 服務的輸入完全相同。 同樣地,“amlOutput” 會傳回與 Web 服務相同的數據。
Avro 寫入器: 此模組會在 「avroModuleInput」 輸入上接收訊息,並將 Avro 格式的訊息保存至磁碟,以供稍後上傳至 IoT 中樞。
路由器模組: 路由器模組會接收來自下游裝置的訊息,然後將訊息格式化並傳送至分類器。 然後,模組會接收分類器的訊息,並將訊息轉送至 Avro 寫入器模組。 最後,模組只會將 RUL 預測傳送至 IoT 中樞。
輸入:
- deviceInput:接收來自下游裝置的訊息
- rulInput: 接收來自 “amlOutput” 的訊息
輸出:
- 分類: 將訊息傳送至「amlInput」
- writeAvro: 將訊息傳送至 “avroModuleInput”
- toIotHub: 將訊息傳送至$upstream,將訊息傳遞至連線的IoT中樞
下圖顯示完整解決方案的模組、輸入、輸出和 IoT Edge 中樞路由:
本文中的步驟通常是由雲端開發人員執行。
在本教學課程的本節中,您將瞭解如何:
- 從自定義程式代碼建立IoT Edge模組。
- 從您的自定義模組產生 Docker 映像。
- 重新設定IoT中樞路由以支援您的自訂模組。
- 建置、發佈及部署您的自定義模組。
先決條件
本文是一系列關於在 IoT Edge 上使用 Azure Machine Learning 的教學課程的一部分。 本系列中的每個文章都是以上一篇文章中的工作為基礎。 如果您已直接抵達本文,請瀏覽本系列的第一篇文章 。
建立新的IoT Edge解決方案
在執行我們的第二個 Azure Notebook 時,我們已建立並發佈包含 RUL 模型的容器映像檔。 Azure Machine Learning 是映像建立程式的一部分,已封裝該模型,讓映射可部署為 Azure IoT Edge 模組。
在此步驟中,我們將使用「Azure Machine Learning」模組建立 Azure IoT Edge 解決方案,並將模組指向我們使用 Azure Notebooks 發佈的映射。
開啟開發 VM 的遠端桌面會話。
在 Visual Studio Code 中開啟資料夾 C:\source\IoTEdgeAndMlSample 。
以滑鼠右鍵點選檔案總管面板(在空白處),然後選取新增IoT Edge 解決方案。
接受預設解決方案名稱 EdgeSolution。
選擇 [Azure Machine Learning ] 作為模組範本。
將模組命名為 turbofanRulClassifier。
選擇您的機器學習工作區。 此工作區是您在教學課程:定型和部署 Azure Machine Learning 模型中所建立的 turboFanDemo 工作區
選取您在執行 Azure Notebook 時建立的映像。
檢視解決方案,並注意已建立的檔案:
deployment.template.json: 此檔案包含解決方案中每個模組的定義。 此檔案中有三個要注意的區段:
登錄認證: 定義您在解決方案中所使用的自訂容器登錄集合。 現在,它應該會包含來自您機器學習工作區中的登錄檔,也就是 Azure Machine Learning 映像的儲存位置。 您可以擁有任意數目的容器登錄,但為了簡單起見,我們將針對所有模組使用此一個登錄。
"registryCredentials": { "<your registry>": { "username": "$CONTAINER_REGISTRY_USERNAME_<your registry>", "password": "$CONTAINER_REGISTRY_PASSWORD_<your registry>", "address": "<your registry>.azurecr.io" } }模組: 本節包含一組隨此解決方案一起使用的使用者定義模組。 turbofanRulClassifier 模組定義會指向容器登錄中的映像。 當我們將更多模組新增至解決方案時,這些模組會顯示在本節中。
"modules": { "turbofanRulClassifier": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "turbofandemo2cd74296.azurecr.io/edgemlsample:1", "createOptions": {} } } }路由: 在本教學課程中,我們將使用相當多的路由。 路由會定義模組彼此通訊的方式。 範本所定義的現有路由與我們需要的路由不符。 刪除
turbofanRulClassifierToIoTHub路由。"$edgeHub": { "properties.desired": { "schemaVersion": "1.0", "routes": { "turbofanRulClassifierToIoTHub": "FROM /messages/modules/turbofanRulClassifier/outputs/* INTO $upstream" }, "storeAndForwardConfiguration": { "timeToLiveSecs": 7200 } } }
deployment.debug.template.json: 此檔案是 deployment.template.json偵錯版本。 一般而言,我們應該將此檔案與 deployment.template.json 檔案的內容保持同步,但本教學課程不需要這麼做。
.env: 此檔案是您應該提供使用者名稱和密碼來存取登錄的位置。
CONTAINER_REGISTRY_USERNAME_<your registry name>=<ACR username> CONTAINER_REGISTRY_PASSWORD_<your registry name>=<ACR password>備註
本教學課程會針對 Azure Container Registry 使用系統管理員登入認證,可便於開發和測試案例使用。 當您準備好進入生產環境時,我們建議使用最低權限的身份驗證選項,例如服務主體帳戶。 如需詳細資訊,請參閱管理您容器登錄的存取權。
以滑鼠右鍵按兩下 Visual Studio Code 總管中的 deployment.template.json 檔案,然後選取 [建置 IoT Edge 解決方案]。
請注意,此命令會建立具有 deployment.amd64.json 檔案的 config 資料夾。 此檔案是解決方案的具體部署範本。
新增路由器模組
接下來,我們會將路由器模組新增至解決方案。 路由器模組會處理解決方案的數個責任:
- 從下游裝置接收訊息:當訊息從下游裝置 送達 IoT Edge 裝置時,路由器模組會收到訊息並開始協調訊息的路由。
- 將訊息傳送至 RUL 分類器模組: 從下游裝置接收新訊息時,路由器模組會將訊息轉換成 RUL 分類器預期的格式。 路由器會將訊息傳送至 RUL 分類器以進行 RUL 預測。 分類器進行預測之後,它會將訊息傳迴路由器模組。
- 將 RUL 訊息傳送至 IoT 中樞: 當路由器從分類器接收訊息時,它會將訊息轉換成只包含基本資訊、裝置識別碼和 RUL,並將縮寫的訊息傳送至 IoT 中樞。 在這裡,我們尚未完成的進一步優化是僅在 RUL 預測低於某個閾值時才將訊息發送至 IoT 中樞(例如,當 RUL 少於 100 個周期時)。 如此一來篩選會減少訊息數量,並減少IoT中樞的成本。
- 將訊息傳送至 Avro 寫入器模組: 為了保留下游裝置傳送的所有數據,路由器模組會將從分類器接收的整個訊息傳送至 Avro 寫入器模組,這會使用 IoT 中樞檔案上傳來保存和上傳數據。
路由器模組是解決方案的重要部分,可確保訊息會以正確的順序處理。
建立模組並複製檔案
以滑鼠右鍵按兩下 Visual Studio Code 中的 modules 資料夾,然後選擇 [ 新增 IoT Edge 模組]。
選擇模組範本的 C# 模組 。
將模組命名為 turbofanRouter。
當系統提示您輸入 Docker 映像存放庫時,請使用機器學習工作區中的登錄(您可以在 deployment.template.json 檔案的 registryCredentials 節點中找到登錄)。 此值是登錄的完整位址,例如<您的 registry.azurecr.io/turbofanrouter>。
備註
在本文中,我們會使用 Azure Machine Learning 工作區所建立的 Azure Container Registry。 這純粹是為了方便起見。 我們可以建立新的容器登錄,並在該處發佈模組。
在終端機中使用命令提示字元介面,將範例模組中的檔案複製到方案。
copy c:\source\IoTEdgeAndMlSample\EdgeModules\modules\turbofanRouter\*.cs c:\source\IoTEdgeAndMlSample\EdgeSolution\modules\turbofanRouter\接受提示以覆寫program.cs檔案。
建置路由器模組
在 Visual Studio Code 中,選取 [終端機>設定預設建置工作]。
選擇「從範本建立 tasks.json 檔案」。
選取 [.NET Core]。
使用下列程式代碼取代 tasks.json 的內容。
{ "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" } ] }儲存並關閉 tasks.json。
使用
Ctrl + Shift + B或 終端機>執行建置工作。
設定模組路由
如上所述,IoT Edge 運行時間會使用 deployment.template.json 檔案中設定的路由來管理鬆散結合模組之間的通訊。 在本節中,我們會深入探討如何設定 turbofanRouter 模組的路由。 我們會先涵蓋輸入路徑,接著再談輸出。
輸入
在 Program.cs 檔案的 Init() 方法中,我們註冊了模組的兩個回呼函數:
await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromLeafDevice, LeafDeviceInputMessageHandler, ioTHubModuleClient); await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromClassifier, ClassifierCallbackMessageHandler, ioTHubModuleClient);第一個回呼會監聽傳送至 deviceInput 匯入的訊息。 在上圖中,我們看到我們想要將訊息從任何下游裝置路由傳送至此輸入。 在 deployment.template.json 檔案中,新增一個路由,指示邊緣中樞將所有由 IoT Edge 裝置接收到但非由 IoT Edge 模組發送的訊息,路由到 turbofanRouter 模組上名為“deviceInput”的輸入端。
"leafMessagesToRouter": "FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/deviceInput\")"接下來,將來自 rulClassifier 模組的訊息路由新增至 turbofanRouter 模組:
"classifierToRouter": "FROM /messages/modules/turbofanRulClassifier/outputs/amloutput INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/rulInput\")"
輸出
將四個額外的路由新增至 $edgeHub 路由參數,以處理路由器模組的輸出。
Program.cs會定義 SendMessageToClassifier()方法,此方法會使用模組用戶端使用路由將訊息傳送至 RUL 分類器:
"routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")"SendRulMessageToIotHub() 會使用模組用戶端,透過路由將裝置的 RUL 數據只傳送至 IoT 中樞:
"routerToIoTHub": "FROM /messages/modules/turboFanRouter/outputs/hubOutput INTO $upstream"SendMessageToAvroWriter() 會使用模組用戶端來傳送訊息,並將 RUL 數據新增至 avroFileWriter 模組。
"routerToAvro": "FROM /messages/modules/turbofanRouter/outputs/avroOutput INTO BrokeredEndpoint(\"/modules/avroFileWriter/inputs/avroModuleInput\")"HandleBadMessage() 會在 IoT 中樞上游傳送失敗的訊息,以供稍後路由傳送。
"deadLetter": "FROM /messages/modules/turboFanRouter/outputs/deadMessages INTO $upstream"
結合所有路由時,您的「$edgeHub」節點應該看起來像下面的 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
}
}
}
備註
新增 turbofanRouter 模組會建立下列其他路由: turbofanRouterToIoTHub": "FROM /messages/modules/turbofanRouter/outputs/* INTO $upstream。 拿掉此路由,只保留上述 deployment.template.json 檔案中所列的路由。
新增 Avro 編寫模組
Avro Writer 模組在我們的解決方案中具有兩項責任,用來儲存訊息和上傳檔案。
儲存訊息:當 Avro 寫入器模組收到訊息時,它會以 Avro 格式將訊息寫入本機文件系統。 我們會使用綁定掛載,將一個目錄(在此案例中為 /data/avrofiles)掛載到模組容器的路徑中。 此掛接可讓模組寫入本機路徑 (/avrofiles),並讓這些檔案直接從 IoT Edge 裝置存取。
上傳檔案:Avro Writer 模組會使用 Azure IoT 中樞檔案上傳功能,將檔案上傳至 Azure 記憶體帳戶。 成功上傳檔案之後,模組會從磁碟刪除檔案
建立模組和複製檔案
在 Visual Studio Code 中,選取 [ 檢視>命令選擇區],然後搜尋並選取 [Python:選取解釋器]。
選取已安裝的 Python 3.7 版或更新版本。
以滑鼠右鍵按兩下 Visual Studio Code 中的 modules 資料夾,然後選擇 [ 新增 IoT Edge 模組]。
選擇 [Python 模組]。
將模組
avroFileWriter命名為 。當系統提示您輸入 Docker 映像存放庫時,請使用與新增路由器模組時所使用的相同登錄。
將範例模組中的檔案複製到解決方案。
copy C:\source\IoTEdgeAndMlSample\EdgeModules\modules\avroFileWriter\*.py C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avroFileWriter\接受覆寫(替換)main.py。
請注意,已將 filemanager.py 和 schema.py 新增至解決方案,並已更新 main.py。
備註
當您開啟 Python 檔案時,系統可能會提示您安裝 pylint。 您不需要安裝linter來完成本教學課程。
資料檔的系結掛載
如先前所述,寫入器模組依賴系結掛接的存在,將Avro檔案寫入裝置的文件系統。
將目錄新增至裝置
在 Azure 入口網站中,如果 IoT Edge 裝置的 VM 尚未啟動,請加以啟動。 使用 SSH 連線到它。 連線需要您從 Azure 入口網站的 VM 概觀頁面複製的 DNS 名稱。
ssh -l <user>@<vm name>.<region>.cloudapp.azure.com登入之後,請建立將保存已儲存下游裝置訊息的目錄。
sudo mkdir -p /data/avrofiles更新目錄許可權,使其可供容器寫入。
sudo chmod ugo+rw /data/avrofiles驗證目錄現在對使用者、群組和所有者具有寫入(w)許可權。
ls -la /data
將目錄新增至模組
若要將目錄新增至模組的容器,我們將修改與avroFileWriter模組相關聯的Dockerfiles。 模組有三個相關聯的 Dockerfile:Dockerfile.amd64、Dockerfile.amd64.debug 和 Dockerfile.arm32v7。 如果我們想要對arm32裝置進行偵錯或部署,這些檔案應該保持同步。 在本文中,僅著重於 Dockerfile.amd64。
在您的開發 VM 上,開啟 C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\Dockerfile.amd64 檔案。
修改檔案,使其看起來像下列範例:
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" ]mkdir和chown命令會指示 Docker 建置程式在映像中建立名為 /avrofiles 的最上層目錄,然後讓模組使用者成為該目錄的擁有者。 在使用useradd命令將模組使用者新增到映像檔之後,以及在內容切換至模組使用者 (USER moduleuser) 之前,插入這些命令非常重要。如有需要,請對 Dockerfile.amd64.debug 和 Dockerfile.arm32v7 進行對應的變更。
將系結組態新增至avroFileWriter
建立系結的最後一個步驟是使用系結資訊來更新 deployment.template.json (和 deployment.debug.template.json) 檔案。
開啟 deployment.template.json。
透過添加
Binds參數,將容器目錄/avrofiles指向邊緣裝置上的本地目錄,以修改avroFileWriter的模組定義。 您的模組定義應該符合此範例:"avroFileWriter": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "${MODULES.avroFileWriter}", "createOptions": { "HostConfig": { "Binds": [ "/data/avrofiles:/avrofiles" ] } } } }
綁定掛載以存取 config.yaml
我們需要為寫入器模組新增一個系結。 此系結可讓模組存取權從IoT Edge裝置上的 /etc/iotedge/config.yaml 檔案讀取連接字串。 我們需要連接字串來建立IoTHubClient,以便呼叫 upload_blob_async方法來將檔案上傳至IoT中樞。 新增此系結的步驟類似於上一節中的步驟。
更新目錄許可權
使用 SSH 連線到 IoT Edge 裝置。
ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com將讀取許可權新增至 config.yaml 檔案。
sudo chmod +r /etc/iotedge/config.yaml驗證許可權已正確設定。
ls -la /etc/iotedge/確定 config.yaml 的許可權為 -r--r--r--。
將目錄新增至模組
在您的開發計算機上,開啟 Dockerfile.amd64 檔案。
將一組
mkdir和chown命令新增至檔案,如下所示: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"]對 Dockerfile.amd64.debug 和 Dockerfile.arm32v7 進行對應的變更。
更新模組組態
開啟 deployment.template.json 檔案。
請將模組定義 avroFileWriter 修改,方法是於
Binds參數中新增第二行,使容器目錄(/app/iotconfig)指向裝置上的本機目錄(/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" ] } } } }對 deployment.debug.template.json進行對應的變更。
安裝依賴項
寫入器模組依賴於兩個 Python 程式庫:fastavro 和 PyYAML。 我們需要在開發計算機上安裝相依性,並指示 Docker 建置程式在模組的映像中加以安裝。
PyYAML
在您的開發機器上,開啟
C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\requirements.txt檔案,並在檔案中新的一行新增「pyyaml」。azure-iothub-device-client~=1.4.3 pyyaml開啟 Dockerfile.amd64 檔案,並新增
pip install命令以升級 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" ]在命令提示字元中,將 pyyaml 安裝到您的開發計算機。
pip install pyyaml
Fastavro
在 requirements.txt中,在 pyyaml 後面新增 fastavro。
azure-iothub-device-client~=1.4.3 pyyaml fastavro將fastavro安裝到您的開發電腦。
pip install fastavro
重新設定IoT中樞
藉由將IoT Edge裝置和模組介紹至系統,我們已變更對將數據傳送至中樞和用途的預期。 我們需要重新設定中樞中的路由,以處理新的現實。
備註
我們會在部署模組之前重新設定中樞,因為某些中樞設定,特別是檔案上傳,必須正確設定avroFileWriter模組才能正確執行
在 IoT 中樞中配置 RUL 訊息的路由
有了路由器和分類器,我們預期會收到只包含裝置標識碼和裝置 RUL 預測的一般訊息。 我們希望將 RUL 數據導入其專屬的儲存位置,在那裡我們可以監控裝置的狀態、生成報告並根據需要觸發警報。 同時,我們希望尚未連結至我們的 IoT Edge 裝置的下游裝置仍能直接傳送任何裝置數據,以繼續路由至目前的儲存位置。
建立 RUL 訊息路由
在 Azure 入口網站中,巡覽至您的 IoT 中樞。
從左窗格的功能表中,選取 [ 中樞設定] 底下的 [ 訊息路由]。
在 [ 路由] 索引標籤上,選取 [ 新增]。
將路由命名為 RulMessageRoute。
選取 新增端點,然後在 端點 選取器的右側選擇 儲存空間。
在 [ 新增記憶體端點] 頁面上,將端點命名為 ruldata。
選擇挑選容器。
在 [ 記憶體帳戶 ] 頁面上,尋找您在本教學課程中使用的記憶體帳戶,其名稱類似 iotedgeandml<唯一後綴>。
選取 ruldata 容器,然後按兩下 [ 選取]。
回到 [ 新增記憶體端點 ] 頁面,選取 [ 建立 ] 以建立記憶體端點。
回到 新增路由 頁面的 路由查詢,將
true替換為以下查詢:IS_DEFINED($body.PredictedRul) AND NOT IS_DEFINED($body.OperationalSetting1)展開 [ 測試] 區段,然後展開 [ 訊息本文 ] 區段。 以我們預期的訊息範例取代訊息本文:
{ "ConnectionDeviceId": "aaLeafDevice_1", "CorrelationId": "b27e97bb-06c5-4553-a064-e9ad59c0fdd3", "PredictedRul": 132.62721409309165, "CycleTime": 64.0 }選取 [測試路由]。 如果測試成功,您會看到「訊息符合查詢」。
點選 [儲存]。
更新 turbofanDeviceDataToStorage 路由
我們不想將新的預測數據路由至舊的儲存位置,因此請更新路由以防止它。
在 [IoT 中樞 訊息路由 ] 頁面中,選取 路由 標籤。
選取 turbofanDeviceDataToStorage,或您為初始裝置數據路由提供的任何名稱。
將路由查詢更新為
IS_DEFINED($body.OperationalSetting1)展開 [ 測試] 區段,然後展開 [ 訊息本文 ] 區段。 以我們預期的訊息範例取代訊息:
{ "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 }選取 [測試路由]。 如果測試成功,您會看到「訊息符合查詢」。
選取 [儲存]。
設定檔案上傳
設定IoT中樞檔案上傳功能,讓檔案寫入器模組將檔案上傳至記憶體。
從 IoT 中樞的左窗格選單,在 樞設定 底下,選擇 檔案上傳。
選取 [Azure 記憶體容器]。
從清單中選取您的記憶體帳戶。
選取開頭為 azureml-blobstore 且附加 guid 的容器,然後按兩下 [ 選取]。
選取 [儲存]。 入口網站會在儲存完成時通知您。
備註
我們不會開啟本教學課程的上傳通知,但如需如何處理檔案上傳通知的詳細資訊,請參閱 接收檔案上傳通知 。
建置、發佈和部署模組
既然我們已進行設定變更,即可建置映像,並將其發佈至我們的 Azure 容器登錄。 建置程式會使用 deployment.template.json 檔案來判斷需要建置哪些模組。 每個模組的設定,包括版本,都位於模組資料夾中的 module.json 檔案中。 建置程式會先在符合 module.json 檔案中找到的目前組態的 Docker 檔案上執行 Docker 組建,以建立映像。 然後,它會從 module.json 檔案將映像發佈至登錄,其版本標籤符合 module.json 檔案中的版本標籤。 最後,它會產生組態特定的部署指令清單(例如,deployment.amd64.json),我們將部署至IoT Edge裝置。 IoT Edge 裝置會從部署指令清單讀取資訊,並根據指示下載模組、設定路由,以及設定任何所需的屬性。 此部署方法有兩個副作用,您應該注意:
部署延遲: 由於IoT Edge運行時必須在開始重新配置之前識別其所需屬性的變更,因此在部署模組後,可能需要一段時間,直到運行時接收到這些變更並開始更新IoT Edge裝置。
模組版本很重要: 如果您使用與上一個模組相同的版本標籤,將模組的新版本容器發佈至容器登錄,運行時間將不會下載新版本的模組。 它會比較本地映像檔的版本標籤以及部署指令清單中期望的映像檔。 如果這些版本相符,執行階段不會有所動作。 因此,每次您想要部署新變更時,請務必遞增模組的版本。 在您要變更的模組的 module.json 檔案中,於 tag 屬性下變更 版本 屬性,以遞增版本。 然後建置併發佈模組。
{ "$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" }
建置並發布
在您的開發 VM 上,如果 Docker 尚未運行,請啟動 Docker。
在 Visual Studio Code 中,使用命令提示字元啟動新的終端機,然後登入您的 Azure 容器登錄 (ACR)。
您可以在 Azure 入口網站中找到必要的使用者名稱、密碼和登入伺服器值。 容器登錄名稱的格式為 「turbofandemo<unique id>」。。 從左窗格功能表的 [ 設定] 底下,選取 [存取金鑰 ] 以檢視它們。
docker login -u <ACR username> -p <ACR password> <ACR login server>
- 在 Visual Studio Code 中,以滑鼠右鍵按兩下 deployment.template.json,然後選擇 [建置和推送 IoT Edge 解決方案]。
檢視登錄中的模組
建置成功完成之後,我們將能夠使用 Azure 入口網站來檢閱已發佈的模組。
在此教學課程中開啟 Azure Container Registry。 容器登錄名稱的格式為 「turbofandemo<unique id>」。。
從左窗格功能表的 [ 服務] 底下,選取 [ 存放庫]。
請注意,您建立的兩個模組 avrofilewriter 和 turbofanrouter 都會顯示為存放庫。
選取 turbofanrouter 並注意您已發佈一個標記為 0.0.1-amd64 的影像。
將模組部署至IoT Edge裝置
我們已在解決方案中建置和設定模組,現在我們會將模組部署至IoT Edge裝置。
在 Visual Studio Code 中,以滑鼠右鍵按兩下 config 資料夾中 deployment.amd64.json 檔案。
選擇 [建立單一裝置的部署]。
選擇 IoT Edge 裝置 aaTurboFanEdgeDevice。
在 Visual Studio Code 總管中重新整理 Azure IoT 中樞裝置面板。 您應該會看到這三個新模組已部署,但尚未執行。
幾分鐘后再次重新整理,您會看到模組正在執行。
備註
模組可能需要幾分鐘的時間才能啟動並穩定執行狀態。 在此期間,您可能會看到模組在嘗試建立與 IoT Edge 中樞模組的連線時啟動和停止。
故障診斷
在本節中,我們分享了一些技術,以瞭解模組或模組發生什麼問題。 通常可以首次從 Visual Studio Code 中的狀態察覺故障。
識別失敗的模組
Visual Studio Code: 查看 Azure IoT 中樞裝置面板。 如果大部分的模組處於執行中狀態,但已停止,您必須進一步調查該已停止的模組。 如果所有模組都處於長時間停止狀態,也可能表示失敗。
Azure 入口網站: 在入口網站中流覽至您的 IoT 中樞,然後尋找裝置詳細數據頁面(在 IoT Edge 下,鑽研您的裝置),您可能會發現模組已回報錯誤,或從未向 IoT 中樞報告任何專案。
由裝置進行診斷
藉由登入 IoT Edge 裝置(在我們的案例中為 Linux VM),您可以存取模組狀態的相關信息。 我們使用的主要機制是 Docker 命令,讓我們檢查裝置上的容器和映像。
登入IoT Edge裝置:
ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com列出所有執行中的容器。 我們預期每個模組都會有一個名稱相符的容器。 此外,此命令會列出容器的確切映像,包括版本,讓您可以符合您的預期。 您也可以將命令中的「container」替換為「image」來列出圖片。
sudo docker container ls取得容器的記錄。 此命令會輸出容器中已寫入 StdErr 和 StdOut 的任何內容。 此命令適用於已啟動後因某種原因而終止的容器。 它也有助於瞭解edgeAgent或edgeHub容器所發生的情況。
sudo docker container logs <container id>檢查容器。 此命令會提供大量關於圖像的資訊。 可以根據您所尋找的內容來篩選數據。 例如,如果您想要查看 avroFileWriter 上的系結是否正確,您可以使用 命令:
sudo docker container inspect -f "{{ json .Mounts }}" avroFileWriter | python -m json.tool連接到執行中的容器。 如果您想在容器運行時進行檢查,此命令會很有幫助:
sudo docker exec -it avroFileWriter bash
清理資源
本教學課程是一組的一部分,其中每個文章都是以先前文章中完成的工作為基礎。 請等候清除任何資源,直到您完成最後一個教學課程為止。
後續步驟
在本文中,我們在Visual Studio Code 中建立了IoT Edge解決方案,其中包含三個模組:分類器、路由器和檔案寫入器/上傳器。 我們會設定路由,以允許模組在邊緣裝置上彼此通訊。 我們已修改邊緣裝置的組態,並更新 Dockerfiles 以安裝相依性,並將系結掛接新增至模組的容器。
接下來,我們已更新物聯網中樞的配置,以根據類型來路由訊息並處理檔案上傳。 一切就緒后,我們已將模組部署至 IoT Edge 裝置,並確保模組已正確執行。
繼續進行下一篇文章,開始傳送數據,並查看您的解決方案運作情形。