概述
該文章描述瞭如何在 EdgeX 中使用 Kuiper 規則引擎,根據分析結果來實現對設備的控制。爲了便於理解,該文章使用 device-virtual示例,它對device-virtual服務發送的數據進行分析,而後根據由Kuiper規則引擎生成的分析結果來控制物聯網設備 。git
場景
在本文中,將建立並運行如下兩條規則。github
- 監視
Random-UnsignedInteger-Device
設備的規則,若是uint8
值大於20
,則向Random-Boolean-Device
設備發送命令,並開啓布爾值的隨機生成 。 - 監視
Random-Integer-Device
設備的規則,若是每20秒int8
的平均值大於0,則向Random-Boolean-Device
設備服務發送命令以關閉 布爾值的隨機生成。
該場景不含任何真實的業務邏輯,而只是爲了演示EdgeX Kuiper規則引擎的功能。 您能夠根據咱們的演示制定合理的業務規則。golang
預備知識
本文檔將不涉及 EdgeX 和 EMQ X Kuiper 的基本操做,所以讀者應具備如下基本知識:sql
- 瞭解 EdgeX 的基礎知識,最好完成快速入門。
- 閱讀 EdgeX Kuiper 規則引擎入門教程:您最好閱讀此入門教程,並開始在EdgeX中試用規則引擎。
- Go 模板:EMQ X Kuiper 使用Go模板從分析結果中提取數據。 瞭解 Go 模板能夠幫助您從分析結果中提取所需的數據。
開始使用
請務必遵循文檔 EdgeX Kuiper規則引擎入門教程,確保教程可以成功運行。docker
建立 EdgeX 流
在建立規則以前,應建立一個流,該流可使用來自 EdgeX 應用程序服務的流數據。 若是您已經完成 EdgeX Kuiper 規則引擎入門教程,則不須要此步驟。json
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
能夠獲取該設備的可用命令列表。它將打印相似的輸出,以下所示。api
{ "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,則將忽略第一個參數。
所以,示例控制命令將相似於以下命令:app
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
設備發送命令,並開啓布爾值的隨機生成 。 如下是規則定義,請注意:dom
- 當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