共用方式為


教學課程:建立和部署自定義IoT Edge模組

適用於:勾選圖示 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 三個模組架構圖表

本文中的步驟通常是由雲端開發人員執行。

在本教學課程的本節中,您將瞭解如何:

  • 從自定義程式代碼建立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 發佈的映射。

  1. 開啟開發 VM 的遠端桌面會話。

  2. 在 Visual Studio Code 中開啟資料夾 C:\source\IoTEdgeAndMlSample

  3. 以滑鼠右鍵點選檔案總管面板(在空白處),然後選取新增IoT Edge 解決方案

    建立新的IoT Edge解決方案

  4. 接受預設解決方案名稱 EdgeSolution

  5. 選擇 [Azure Machine Learning ] 作為模組範本。

  6. 將模組命名為 turbofanRulClassifier

  7. 選擇您的機器學習工作區。 此工作區是您在教學課程:定型和部署 Azure Machine Learning 模型中所建立的 turboFanDemo 工作區

  8. 選取您在執行 Azure Notebook 時建立的映像。

  9. 檢視解決方案,並注意已建立的檔案:

    • 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 使用系統管理員登入認證,可便於開發和測試案例使用。 當您準備好進入生產環境時,我們建議使用最低權限的身份驗證選項,例如服務主體帳戶。 如需詳細資訊,請參閱管理您容器登錄的存取權

  10. 以滑鼠右鍵按兩下 Visual Studio Code 總管中的 deployment.template.json 檔案,然後選取 [建置 IoT Edge 解決方案]。

  11. 請注意,此命令會建立具有 deployment.amd64.json 檔案的 config 資料夾。 此檔案是解決方案的具體部署範本。

新增路由器模組

接下來,我們會將路由器模組新增至解決方案。 路由器模組會處理解決方案的數個責任:

  • 從下游裝置接收訊息:當訊息從下游裝置 送達 IoT Edge 裝置時,路由器模組會收到訊息並開始協調訊息的路由。
  • 將訊息傳送至 RUL 分類器模組: 從下游裝置接收新訊息時,路由器模組會將訊息轉換成 RUL 分類器預期的格式。 路由器會將訊息傳送至 RUL 分類器以進行 RUL 預測。 分類器進行預測之後,它會將訊息傳迴路由器模組。
  • 將 RUL 訊息傳送至 IoT 中樞: 當路由器從分類器接收訊息時,它會將訊息轉換成只包含基本資訊、裝置識別碼和 RUL,並將縮寫的訊息傳送至 IoT 中樞。 在這裡,我們尚未完成的進一步優化是僅在 RUL 預測低於某個閾值時才將訊息發送至 IoT 中樞(例如,當 RUL 少於 100 個周期時)。 如此一來篩選會減少訊息數量,並減少IoT中樞的成本。
  • 將訊息傳送至 Avro 寫入器模組: 為了保留下游裝置傳送的所有數據,路由器模組會將從分類器接收的整個訊息傳送至 Avro 寫入器模組,這會使用 IoT 中樞檔案上傳來保存和上傳數據。

路由器模組是解決方案的重要部分,可確保訊息會以正確的順序處理。

建立模組並複製檔案

  1. 以滑鼠右鍵按兩下 Visual Studio Code 中的 modules 資料夾,然後選擇 [ 新增 IoT Edge 模組]。

  2. 選擇模組範本的 C# 模組

  3. 將模組命名為 turbofanRouter

  4. 當系統提示您輸入 Docker 映像存放庫時,請使用機器學習工作區中的登錄(您可以在 deployment.template.json 檔案的 registryCredentials 節點中找到登錄)。 此值是登錄的完整位址,例如<您的 registry.azurecr.io/turbofanrouter>

    備註

    在本文中,我們會使用 Azure Machine Learning 工作區所建立的 Azure Container Registry。 這純粹是為了方便起見。 我們可以建立新的容器登錄,並在該處發佈模組。

  5. 在終端機中使用命令提示字元介面,將範例模組中的檔案複製到方案。

    copy c:\source\IoTEdgeAndMlSample\EdgeModules\modules\turbofanRouter\*.cs c:\source\IoTEdgeAndMlSample\EdgeSolution\modules\turbofanRouter\
    
  6. 接受提示以覆寫program.cs檔案。

建置路由器模組

  1. 在 Visual Studio Code 中,選取 [終端機>設定預設建置工作]。

  2. 選擇「從範本建立 tasks.json 檔案」

  3. 選取 [.NET Core]。

  4. 使用下列程式代碼取代 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"
        }
      ]
    }
    
  5. 儲存並關閉 tasks.json。

  6. 使用 Ctrl + Shift + B終端機>執行建置工作

設定模組路由

如上所述,IoT Edge 運行時間會使用 deployment.template.json 檔案中設定的路由來管理鬆散結合模組之間的通訊。 在本節中,我們會深入探討如何設定 turbofanRouter 模組的路由。 我們會先涵蓋輸入路徑,接著再談輸出。

輸入

  1. 在 Program.cs 檔案的 Init() 方法中,我們註冊了模組的兩個回呼函數:

    await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromLeafDevice, LeafDeviceInputMessageHandler, ioTHubModuleClient);
    await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromClassifier, ClassifierCallbackMessageHandler, ioTHubModuleClient);
    
  2. 第一個回呼會監聽傳送至 deviceInput 匯入的訊息。 在上圖中,我們看到我們想要將訊息從任何下游裝置路由傳送至此輸入。 在 deployment.template.json 檔案中,新增一個路由,指示邊緣中樞將所有由 IoT Edge 裝置接收到但非由 IoT Edge 模組發送的訊息,路由到 turbofanRouter 模組上名為“deviceInput”的輸入端。

    "leafMessagesToRouter": "FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/deviceInput\")"
    
  3. 接下來,將來自 rulClassifier 模組的訊息路由新增至 turbofanRouter 模組:

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

輸出

將四個額外的路由新增至 $edgeHub 路由參數,以處理路由器模組的輸出。

  1. Program.cs會定義 SendMessageToClassifier()方法,此方法會使用模組用戶端使用路由將訊息傳送至 RUL 分類器:

    "routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")"
    
  2. SendRulMessageToIotHub() 會使用模組用戶端,透過路由將裝置的 RUL 數據只傳送至 IoT 中樞:

    "routerToIoTHub": "FROM /messages/modules/turboFanRouter/outputs/hubOutput INTO $upstream"
    
  3. SendMessageToAvroWriter() 會使用模組用戶端來傳送訊息,並將 RUL 數據新增至 avroFileWriter 模組。

    "routerToAvro": "FROM /messages/modules/turbofanRouter/outputs/avroOutput INTO BrokeredEndpoint(\"/modules/avroFileWriter/inputs/avroModuleInput\")"
    
  4. 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 記憶體帳戶。 成功上傳檔案之後,模組會從磁碟刪除檔案

建立模組和複製檔案

  1. 在 Visual Studio Code 中,選取 [ 檢視>命令選擇區],然後搜尋並選取 [Python:選取解釋器]。

  2. 選取已安裝的 Python 3.7 版或更新版本。

  3. 以滑鼠右鍵按兩下 Visual Studio Code 中的 modules 資料夾,然後選擇 [ 新增 IoT Edge 模組]。

  4. 選擇 [Python 模組]

  5. 將模組 avroFileWriter命名為 。

  6. 當系統提示您輸入 Docker 映像存放庫時,請使用與新增路由器模組時所使用的相同登錄。

  7. 將範例模組中的檔案複製到解決方案。

    copy C:\source\IoTEdgeAndMlSample\EdgeModules\modules\avroFileWriter\*.py C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avroFileWriter\
    
  8. 接受覆寫(替換)main.py。

  9. 請注意,已將 filemanager.py 和 schema.py 新增至解決方案,並已更新 main.py。

備註

當您開啟 Python 檔案時,系統可能會提示您安裝 pylint。 您不需要安裝linter來完成本教學課程。

資料檔的系結掛載

如先前所述,寫入器模組依賴系結掛接的存在,將Avro檔案寫入裝置的文件系統。

將目錄新增至裝置

  1. 在 Azure 入口網站中,如果 IoT Edge 裝置的 VM 尚未啟動,請加以啟動。 使用 SSH 連線到它。 連線需要您從 Azure 入口網站的 VM 概觀頁面複製的 DNS 名稱。

    ssh -l <user>@<vm name>.<region>.cloudapp.azure.com
    
  2. 登入之後,請建立將保存已儲存下游裝置訊息的目錄。

    sudo mkdir -p /data/avrofiles
    
  3. 更新目錄許可權,使其可供容器寫入。

    sudo chmod ugo+rw /data/avrofiles
    
  4. 驗證目錄現在對使用者、群組和所有者具有寫入(w)許可權。

    ls -la /data
    

    avrofiles 的目錄許可權

將目錄新增至模組

若要將目錄新增至模組的容器,我們將修改與avroFileWriter模組相關聯的Dockerfiles。 模組有三個相關聯的 Dockerfile:Dockerfile.amd64、Dockerfile.amd64.debug 和 Dockerfile.arm32v7。 如果我們想要對arm32裝置進行偵錯或部署,這些檔案應該保持同步。 在本文中,僅著重於 Dockerfile.amd64。

  1. 在您的開發 VM 上,開啟 C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\Dockerfile.amd64 檔案。

  2. 修改檔案,使其看起來像下列範例:

    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" ]
    

    mkdirchown 命令會指示 Docker 建置程式在映像中建立名為 /avrofiles 的最上層目錄,然後讓模組使用者成為該目錄的擁有者。 在使用 useradd 命令將模組使用者新增到映像檔之後,以及在內容切換至模組使用者 (USER moduleuser) 之前,插入這些命令非常重要。

  3. 如有需要,請對 Dockerfile.amd64.debug 和 Dockerfile.arm32v7 進行對應的變更。

將系結組態新增至avroFileWriter

建立系結的最後一個步驟是使用系結資訊來更新 deployment.template.json (和 deployment.debug.template.json) 檔案。

  1. 開啟 deployment.template.json。

  2. 透過添加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中樞。 新增此系結的步驟類似於上一節中的步驟。

更新目錄許可權

  1. 使用 SSH 連線到 IoT Edge 裝置。

    ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
    
  2. 將讀取許可權新增至 config.yaml 檔案。

    sudo chmod +r /etc/iotedge/config.yaml
    
  3. 驗證許可權已正確設定。

    ls -la /etc/iotedge/
    
  4. 確定 config.yaml 的許可權為 -r--r--r--。

將目錄新增至模組

  1. 在您的開發計算機上,開啟 Dockerfile.amd64 檔案。

  2. 將一組 mkdirchown 命令新增至檔案,如下所示:

    FROM ubuntu:xenial
    
    WORKDIR /app
    
    RUN apt-get update && apt-get install -y --no-install-recommends libcurl4-openssl-dev
    python3-pip libboost-python1.58-dev libpython3-dev && rm -rf /var/lib/apt/lists/\*
    
    RUN pip3 install --upgrade pip
    COPY requirements.txt ./
    RUN pip install -r requirements.txt
    
    COPY . .
    
    RUN useradd -ms /bin/bash moduleuser
    RUN mkdir /avrofiles && chown moduleuser /avrofiles
    RUN mkdir -p /app/iotconfig && chown moduleuser /app/iotconfig
    
    USER moduleuser
    
    CMD "python3", "-u", "./main.py"]
    
  3. 對 Dockerfile.amd64.debug 和 Dockerfile.arm32v7 進行對應的變更。

更新模組組態

  1. 開啟 deployment.template.json 檔案。

  2. 請將模組定義 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"
            ]
          }
        }
      }
    }
    
  3. 對 deployment.debug.template.json進行對應的變更。

安裝依賴項

寫入器模組依賴於兩個 Python 程式庫:fastavro 和 PyYAML。 我們需要在開發計算機上安裝相依性,並指示 Docker 建置程式在模組的映像中加以安裝。

PyYAML

  1. 在您的開發機器上,開啟C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\requirements.txt檔案,並在檔案中新的一行新增「pyyaml」。

    azure-iothub-device-client~=1.4.3
    pyyaml
    
  2. 開啟 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" ]
    
  3. 在命令提示字元中,將 pyyaml 安裝到您的開發計算機。

    pip install pyyaml
    

Fastavro

  1. 在 requirements.txt中,在 pyyaml 後面新增 fastavro。

    azure-iothub-device-client~=1.4.3
    pyyaml
    fastavro
    
  2. 將fastavro安裝到您的開發電腦。

    pip install fastavro
    

重新設定IoT中樞

藉由將IoT Edge裝置和模組介紹至系統,我們已變更對將數據傳送至中樞和用途的預期。 我們需要重新設定中樞中的路由,以處理新的現實。

備註

我們會在部署模組之前重新設定中樞,因為某些中樞設定,特別是檔案上傳,必須正確設定avroFileWriter模組才能正確執行

在 IoT 中樞中配置 RUL 訊息的路由

有了路由器和分類器,我們預期會收到只包含裝置標識碼和裝置 RUL 預測的一般訊息。 我們希望將 RUL 數據導入其專屬的儲存位置,在那裡我們可以監控裝置的狀態、生成報告並根據需要觸發警報。 同時,我們希望尚未連結至我們的 IoT Edge 裝置的下游裝置仍能直接傳送任何裝置數據,以繼續路由至目前的儲存位置。

建立 RUL 訊息路由

  1. 在 Azure 入口網站中,巡覽至您的 IoT 中樞。

  2. 從左窗格的功能表中,選取 [ 中樞設定] 底下的 [ 訊息路由]。

  3. 在 [ 路由] 索引標籤上,選取 [ 新增]。

  4. 將路由命名為 RulMessageRoute

  5. 選取 新增端點,然後在 端點 選取器的右側選擇 儲存空間

  6. 在 [ 新增記憶體端點] 頁面上,將端點命名為 ruldata

  7. 選擇挑選容器

  8. 在 [ 記憶體帳戶 ] 頁面上,尋找您在本教學課程中使用的記憶體帳戶,其名稱類似 iotedgeandml<唯一後綴>

  9. 選取 ruldata 容器,然後按兩下 [ 選取]。

  10. 回到 [ 新增記憶體端點 ] 頁面,選取 [ 建立 ] 以建立記憶體端點。

  11. 回到 新增路由 頁面的 路由查詢,將 true 替換為以下查詢:

    IS_DEFINED($body.PredictedRul) AND NOT IS_DEFINED($body.OperationalSetting1)
    
  12. 展開 [ 測試] 區段,然後展開 [ 訊息本文 ] 區段。 以我們預期的訊息範例取代訊息本文:

    {
      "ConnectionDeviceId": "aaLeafDevice_1",
      "CorrelationId": "b27e97bb-06c5-4553-a064-e9ad59c0fdd3",
      "PredictedRul": 132.62721409309165,
      "CycleTime": 64.0
    }
    
  13. 選取 [測試路由]。 如果測試成功,您會看到「訊息符合查詢」。

  14. 點選 [儲存]。

更新 turbofanDeviceDataToStorage 路由

我們不想將新的預測數據路由至舊的儲存位置,因此請更新路由以防止它。

  1. 在 [IoT 中樞 訊息路由 ] 頁面中,選取 路由 標籤。

  2. 選取 turbofanDeviceDataToStorage,或您為初始裝置數據路由提供的任何名稱。

  3. 將路由查詢更新為

    IS_DEFINED($body.OperationalSetting1)
    
  4. 展開 [ 測試] 區段,然後展開 [ 訊息本文 ] 區段。 以我們預期的訊息範例取代訊息:

    {
      "Sensor13": 2387.96,
      "OperationalSetting1": -0.0008,
      "Sensor6": 21.61,
      "Sensor11": 47.2,
      "Sensor9": 9061.45,
      "Sensor4": 1397.86,
      "Sensor14": 8140.39,
      "Sensor18": 2388.0,
      "Sensor12": 522.87,
      "Sensor2": 642.42,
      "Sensor17": 391.0,
      "OperationalSetting3": 100.0,
      "Sensor1": 518.67,
      "OperationalSetting2": 0.0002,
      "Sensor20": 39.03,
      "DeviceId": 19.0,
      "Sensor5": 14.62,
      "PredictedRul": 212.00132402791962,
      "Sensor8": 2388.01,
      "Sensor16": 0.03,
      "CycleTime": 42.0,
      "Sensor21": 23.3188,
      "Sensor15": 8.3773,
      "Sensor3": 1580.09,
      "Sensor10": 1.3,
      "Sensor7": 554.57,
      "Sensor19": 100.0
    }
    
  5. 選取 [測試路由]。 如果測試成功,您會看到「訊息符合查詢」。

  6. 選取 [儲存]。

設定檔案上傳

設定IoT中樞檔案上傳功能,讓檔案寫入器模組將檔案上傳至記憶體。

  1. 從 IoT 中樞的左窗格選單,在 樞設定 底下,選擇 檔案上傳

  2. 選取 [Azure 記憶體容器]。

  3. 從清單中選取您的記憶體帳戶。

  4. 選取開頭為 azureml-blobstore 且附加 guid 的容器,然後按兩下 [ 選取]。

  5. 選取 [儲存]。 入口網站會在儲存完成時通知您。

備註

我們不會開啟本教學課程的上傳通知,但如需如何處理檔案上傳通知的詳細資訊,請參閱 接收檔案上傳通知

建置、發佈和部署模組

既然我們已進行設定變更,即可建置映像,並將其發佈至我們的 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"
    }
    

建置並發布

  1. 在您的開發 VM 上,如果 Docker 尚未運行,請啟動 Docker。

  2. 在 Visual Studio Code 中,使用命令提示字元啟動新的終端機,然後登入您的 Azure 容器登錄 (ACR)。

您可以在 Azure 入口網站中找到必要的使用者名稱、密碼和登入伺服器值。 容器登錄名稱的格式為 「turbofandemo<unique id>」。。 從左窗格功能表的 [ 設定] 底下,選取 [存取金鑰 ] 以檢視它們。

docker login -u <ACR username> -p <ACR password> <ACR login server>
  1. 在 Visual Studio Code 中,以滑鼠右鍵按兩下 deployment.template.json,然後選擇 [建置和推送 IoT Edge 解決方案]。

檢視登錄中的模組

建置成功完成之後,我們將能夠使用 Azure 入口網站來檢閱已發佈的模組。

  1. 在此教學課程中開啟 Azure Container Registry。 容器登錄名稱的格式為 「turbofandemo<unique id>」。。

  2. 從左窗格功能表的 [ 服務] 底下,選取 [ 存放庫]。

  3. 請注意,您建立的兩個模組 avrofilewriterturbofanrouter 都會顯示為存放庫。

  4. 選取 turbofanrouter 並注意您已發佈一個標記為 0.0.1-amd64 的影像。

    檢視 turbofanrouter 的第一個被標記的版本

將模組部署至IoT Edge裝置

我們已在解決方案中建置和設定模組,現在我們會將模組部署至IoT Edge裝置。

  1. 在 Visual Studio Code 中,以滑鼠右鍵按兩下 config 資料夾中 deployment.amd64.json 檔案。

  2. 選擇 [建立單一裝置的部署]。

  3. 選擇 IoT Edge 裝置 aaTurboFanEdgeDevice

  4. 在 Visual Studio Code 總管中重新整理 Azure IoT 中樞裝置面板。 您應該會看到這三個新模組已部署,但尚未執行。

  5. 幾分鐘后再次重新整理,您會看到模組正在執行。

    在 Visual Studio Code 中檢視執行中的模組

備註

模組可能需要幾分鐘的時間才能啟動並穩定執行狀態。 在此期間,您可能會看到模組在嘗試建立與 IoT Edge 中樞模組的連線時啟動和停止。

故障診斷

在本節中,我們分享了一些技術,以瞭解模組或模組發生什麼問題。 通常可以首次從 Visual Studio Code 中的狀態察覺故障。

識別失敗的模組

  • Visual Studio Code: 查看 Azure IoT 中樞裝置面板。 如果大部分的模組處於執行中狀態,但已停止,您必須進一步調查該已停止的模組。 如果所有模組都處於長時間停止狀態,也可能表示失敗。

  • Azure 入口網站: 在入口網站中流覽至您的 IoT 中樞,然後尋找裝置詳細數據頁面(在 IoT Edge 下,鑽研您的裝置),您可能會發現模組已回報錯誤,或從未向 IoT 中樞報告任何專案。

由裝置進行診斷

藉由登入 IoT Edge 裝置(在我們的案例中為 Linux VM),您可以存取模組狀態的相關信息。 我們使用的主要機制是 Docker 命令,讓我們檢查裝置上的容器和映像。

  1. 登入IoT Edge裝置:

    ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
    
  2. 列出所有執行中的容器。 我們預期每個模組都會有一個名稱相符的容器。 此外,此命令會列出容器的確切映像,包括版本,讓您可以符合您的預期。 您也可以將命令中的「container」替換為「image」來列出圖片。

    sudo docker container ls
    
  3. 取得容器的記錄。 此命令會輸出容器中已寫入 StdErr 和 StdOut 的任何內容。 此命令適用於已啟動後因某種原因而終止的容器。 它也有助於瞭解edgeAgent或edgeHub容器所發生的情況。

    sudo docker container logs <container id>
    
  4. 檢查容器。 此命令會提供大量關於圖像的資訊。 可以根據您所尋找的內容來篩選數據。 例如,如果您想要查看 avroFileWriter 上的系結是否正確,您可以使用 命令:

    sudo docker container inspect -f "{{ json .Mounts }}" avroFileWriter | python -m json.tool
    
  5. 連接到執行中的容器。 如果您想在容器運行時進行檢查,此命令會很有幫助:

    sudo docker exec -it avroFileWriter bash
    

清理資源

本教學課程是一組的一部分,其中每個文章都是以先前文章中完成的工作為基礎。 請等候清除任何資源,直到您完成最後一個教學課程為止。

後續步驟

在本文中,我們在Visual Studio Code 中建立了IoT Edge解決方案,其中包含三個模組:分類器、路由器和檔案寫入器/上傳器。 我們會設定路由,以允許模組在邊緣裝置上彼此通訊。 我們已修改邊緣裝置的組態,並更新 Dockerfiles 以安裝相依性,並將系結掛接新增至模組的容器。

接下來,我們已更新物聯網中樞的配置,以根據類型來路由訊息並處理檔案上傳。 一切就緒后,我們已將模組部署至 IoT Edge 裝置,並確保模組已正確執行。

繼續進行下一篇文章,開始傳送數據,並查看您的解決方案運作情形。