使用 EdgeX Kuiper 規則引擎控制物聯網設備

概述

該文章描述瞭如何在 EdgeX 中使用 Kuiper 規則引擎,根據分析結果來實現對設備的控制。爲了便於理解,該文章使用 device-virtual示例,它對device-virtual服務發送的數據進行分析,然後根據由Kuiper規則引擎生成的分析結果來控制物聯網設備 。

場景

在本文中,將創建並運行以下兩條規則。

  1. 監視Random-UnsignedInteger-Device設備的規則,如果uint8值大於 20,則向Random-Boolean-Device設備發送命令,並開啓布爾值的隨機生成 。
  2. 監視Random-Integer-Device設備的規則,如果每20秒 int8的平均值大於0,則向Random-Boolean-Device 設備服務發送命令以關閉 布爾值的隨機生成。

該場景不含任何真實的業務邏輯,而只是爲了演示EdgeX Kuiper規則引擎的功能。 您可以根據我們的演示制定合理的業務規則。

預備知識

本文檔將不涉及 EdgeX 和 EMQ X Kuiper 的基本操作,因此讀者應具有以下基本知識:

  • 瞭解 EdgeX 的基礎知識,最好完成快速入門
  • 閱讀 EdgeX Kuiper 規則引擎入門教程:您最好閱讀此入門教程,並開始在EdgeX中試用規則引擎。
  • Go 模板:EMQ X Kuiper 使用Go模板從分析結果中提取數據。 瞭解 Go 模板可以幫助您從分析結果中提取所需的數據。

開始使用

請務必遵循文檔 EdgeX Kuiper規則引擎入門教程,確保教程能夠成功運行。

創建 EdgeX 流

在創建規則之前,應創建一個流,該流可以使用來自 EdgeX 應用程序服務的流數據。 如果您已經完成 EdgeX Kuiper 規則引擎入門教程,則不需要此步驟。

curl -X POST \
  http://$kuiper_docker:48075/streams \
  -H 'Content-Type: application/json' \
  -d '{
  "sql": "create stream demo() WITH (FORMAT=\"JSON\", TYPE=\"edgex\")"
}'

由於這兩個規則都會向設備Random-UnsignedInteger-Device發送控制命令,通過運行命令curl http://localhost:48082/api/v1/device/name/Random-Boolean-Device | jq可以獲取該設備的可用命令列表。它將打印類似的輸出,如下所示。

{
  "id": "9b051411-ca20-4556-bd3e-7f52475764ff",
  "name": "Random-Boolean-Device",
  "adminState": "UNLOCKED",
  "operatingState": "ENABLED",
  "labels": [
    "device-virtual-example"
  ],
  "commands": [
    {
      "created": 1589052044139,
      "modified": 1589052044139,
      "id": "28d88bb3-e280-46f7-949f-37cc411757f5",
      "name": "Bool",
      "get": {
        "path": "/api/v1/device/{deviceId}/Bool",
        "responses": [
          {
            "code": "200",
            "expectedValues": [
              "Bool"
            ]
          },
          {
            "code": "503",
            "description": "service unavailable"
          }
        ],
        "url": "http://edgex-core-command:48082/api/v1/device/bcd18c02-b187-4f29-8265-8312dc5d794d/command/d6d3007d-c4ce-472f-a117-820b5410e498"
      },
      "put": {
        "path": "/api/v1/device/{deviceId}/Bool",
        "responses": [
          {
            "code": "200"
          },
          {
            "code": "503",
            "description": "service unavailable"
          }
        ],
        "url": "http://edgex-core-command:48082/api/v1/device/bcd18c02-b187-4f29-8265-8312dc5d794d/command/d6d3007d-c4ce-472f-a117-820b5410e498",
        "parameterNames": [
          "Bool",
          "EnableRandomization_Bool"
        ]
      }
    }
  ]
}

從輸出中,您能看出有兩個命令,第二個命令用於更新設備的配置。 此設備有兩個參數:

  • Bool:當其他服務想要獲取設備數據時,設置返回值。 僅當EnableRandomization_Bool設置爲false時,才使用該參數。
  • EnableRandomization_Bool:是否啓用Bool的隨機生成。 如果將此值設置爲true,則將忽略第一個參數。

因此,示例控制命令將類似於如下命令:

curl -X PUT \
  http://edgex-core-command:48082/api/v1/device/c1459444-79bd-46c8-8b37-d6e1418f2a3a/command/fe202437-236d-41c5-845e-3e6013b928cd \
  -H 'Content-Type: application/json' \
  -d '{"Bool":"true", "EnableRandomization_Bool": "true"}'

創建規則

第一條規則

第一條規則是監視Random-UnsignedInteger-Device設備的規則,如果uint8值大於“ 20”,則向Random-Boolean-Device設備發送命令,並開啓布爾值的隨機生成 。 以下是規則定義,請注意:

  • 當uint8的值大於20時將觸發該動作。由於uint8的值不用於向Random-Boolean-Device發送控制命令,因此在rest操作的dataTemplate屬性中不使用uint8值。
curl -X POST \
  http://$kuiper_server:48075/rules \
  -H 'Content-Type: application/json' \
  -d '{
  "id": "rule1",
  "sql": "SELECT uint8 FROM demo WHERE uint8 > 20",
  "actions": [
    {
      "rest": {
        "url": "http://edgex-core-command:48082/api/v1/device/bcd18c02-b187-4f29-8265-8312dc5d794d/command/d6d3007d-c4ce-472f-a117-820b5410e498",
        "method": "put",
        "retryInterval": -1,
        "dataTemplate": "{\"Bool\":\"true\", \"EnableRandomization_Bool\": \"true\"}",
        "sendSingle": true
      }
    },
    {
      "log":{}
    }
  ]
}'

第二條規則

第二條規則監視Random-Integer-Device設備,如果每20秒 int8的平均值大於0,則向Random-Boolean-Device 設備服務發送命令以關閉 布爾值的隨機生成。

  • uint8的平均值每20秒計算一次,如果平均值大於0,則向 Random-Boolean-Device 服務發送控制命令。
curl -X POST \
  http://$kuiper_server:48075/rules \
  -H 'Content-Type: application/json' \
  -d '{
  "id": "rule2",
  "sql": "SELECT avg(int8) AS avg_int8 FROM demo WHERE int8 != nil GROUP BY  TUMBLINGWINDOW(ss, 20) HAVING avg(int8) > 0",
  "actions": [
    {
      "rest": {
        "url": "http://edgex-core-command:48082/api/v1/device/bcd18c02-b187-4f29-8265-8312dc5d794d/command/d6d3007d-c4ce-472f-a117-820b5410e498",
        "method": "put",
        "retryInterval": -1,
        "dataTemplate": "{\"Bool\":\"false\", \"EnableRandomization_Bool\": \"false\"}",
        "sendSingle": true
      }
    },
    {
      "log":{}
    }
  ]
}'

現在創建了兩個規則,您可以查看edgex-kuiper的日誌以獲取規則執行結果。

# docker logs edgex-kuiper

如何從分析結果中提取數據?

由於分析結果也需要發送到command rest服務,如何從分析結果中提取數據?通過SQL過濾數據的示例如下所示:

SELECT int8, "true" AS randomization FROM demo WHERE uint8 > 20

SQL的輸出內容如下:

[{"int8":-75, "randomization":"true"}]

當從字段int8讀取value字段,從字段randomization讀取EnableRandomization_Bool時,假設服務需要以下數據格式:

curl -X PUT \
  http://edgex-core-command:48082/api/v1/device/${deviceId}/command/xyz \
  -H 'Content-Type: application/json' \
  -d '{"value":-75, "EnableRandomization_Bool": "true"}'

Kuiper 使用 Go模板 從分析結果中提取數據,並且dataTemplate 內容如下:

"dataTemplate": "{\"value\": {{.int8}}, \"EnableRandomization_Bool\": \"{{.randomization}}\"}"

在某些情況下,您可能需要迭代返回的數組值,或使用if條件設置不同的值,然後參考此鏈接寫入更復雜的數據模板表達式。

補充閱讀材料

如果您想了解EMQ X Kuiper的更多特性,請閱讀下面的參考資料:

版權聲明: 本文爲 EMQ 原創,轉載請註明出處。

原文鏈接:https://www.emqx.io/cn/blog/control-iot-device-with-kuiper-rules-engine

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章