使用 eKuiper 规则引擎控制设备

概述

该文章描述了如何在 EdgeX 中使用 eKuiper 规则引擎,根据分析结果来实现对设备的控制。为了便于理解,该文章使用 device-virtual示例,它对device-virtual服务发送的数据进行分析,然后根据由Kuiper规则引擎生成的分析结果来控制设备 。

场景

在本文中,将创建并运行以下两条规则。

  1. 监视Random-UnsignedInteger-Device设备的规则,如果uint8值大于 20,则向Random-Boolean-Device设备发送命令,并开启布尔值的随机生成 。
  2. 监视Random-Integer-Device设备的规则,如果每20秒 int8的平均值大于0,则向Random-Boolean-Device 设备服务发送命令以关闭 布尔值的随机生成。

该场景不含任何真实的业务逻辑,而只是为了演示eKuiper规则引擎的功能。 您可以根据我们的演示制定合理的业务规则。

预备知识

本文档将不涉及EdgeX和eKuiper的基本操作,因此读者应具有以下基本知识:

  • 请通过此链接 以了解EdgeX的基础知识,最好完成快速入门
  • 请阅读EdgeX eKuiper规则引擎入门教程:您最好阅读此入门教程,并开始在EdgeX中试用规则引擎。
  • Go模板:eKuiper使用Go模板从分析结果中提取数据。 了解Go模板可以帮助您从分析结果中提取所需的数据。

开始使用

请务必遵循文档 EdgeX eKuiper规则引擎入门教程,确保教程能够成功运行。

创建EdgeX流

在创建规则之前,应创建一个流,该流可以使用来自EdgeX应用程序服务的流数据。 如果您已经完成 EdgeX eKuiper规则引擎入门教程,则不需要此步骤。

  1. curl -X POST \
  2. http://$ekuiper_docker:59720/streams \
  3. -H 'Content-Type: application/json' \
  4. -d '{
  5. "sql": "create stream demo() WITH (FORMAT=\"JSON\", TYPE=\"edgex\")"
  6. }'

由于这两个规则都会向设备Random-UnsignedInteger-Device 发送控制命令,通过运行命令curl http://127.0.0.1:59882/api/v2/device/name/Random-Boolean-Device | jq可以获取该设备的可用命令列表。它将打印类似的输出,如下所示。

  1. {
  2. "apiVersion": "v2",
  3. "statusCode": 200,
  4. "deviceCoreCommand": {
  5. "deviceName": "Random-Boolean-Device",
  6. "profileName": "Random-Boolean-Device",
  7. "coreCommands": [
  8. {
  9. "name": "WriteBoolValue",
  10. "set": true,
  11. "path": "/api/v2/device/name/Random-Boolean-Device/WriteBoolValue",
  12. "url": "http://edgex-core-command:59882",
  13. "parameters": [
  14. {
  15. "resourceName": "Bool",
  16. "valueType": "Bool"
  17. },
  18. {
  19. "resourceName": "EnableRandomization_Bool",
  20. "valueType": "Bool"
  21. }
  22. ]
  23. },
  24. {
  25. "name": "WriteBoolArrayValue",
  26. "set": true,
  27. "path": "/api/v2/device/name/Random-Boolean-Device/WriteBoolArrayValue",
  28. "url": "http://edgex-core-command:59882",
  29. "parameters": [
  30. {
  31. "resourceName": "BoolArray",
  32. "valueType": "BoolArray"
  33. },
  34. {
  35. "resourceName": "EnableRandomization_BoolArray",
  36. "valueType": "Bool"
  37. }
  38. ]
  39. },
  40. {
  41. "name": "Bool",
  42. "get": true,
  43. "set": true,
  44. "path": "/api/v2/device/name/Random-Boolean-Device/Bool",
  45. "url": "http://edgex-core-command:59882",
  46. "parameters": [
  47. {
  48. "resourceName": "Bool",
  49. "valueType": "Bool"
  50. }
  51. ]
  52. },
  53. {
  54. "name": "BoolArray",
  55. "get": true,
  56. "set": true,
  57. "path": "/api/v2/device/name/Random-Boolean-Device/BoolArray",
  58. "url": "http://edgex-core-command:59882",
  59. "parameters": [
  60. {
  61. "resourceName": "BoolArray",
  62. "valueType": "BoolArray"
  63. }
  64. ]
  65. }
  66. ]
  67. }
  68. }

从输出中,您能看出有两个命令,第二个命令用于更新设备的配置。 此设备有两个参数:

  • Bool:当其他服务想要获取设备数据时,设置返回值。 仅当EnableRandomization_Bool设置为false时,才使用该参数。
  • EnableRandomization_Bool:是否启用Bool的随机生成。 如果将此值设置为true,则将忽略第一个参数。

因此,示例控制命令将类似于如下命令:

  1. curl -X PUT \
  2. http://edgex-core-command:59882/api/v2/device/name/Random-Boolean-Device/WriteBoolValue \
  3. -H 'Content-Type: application/json' \
  4. -d '{"Bool":"true", "EnableRandomization_Bool": "true"}'

创建规则

第一条规则

第一条规则是监视Random-UnsignedInteger-Device设备的规则,如果uint8值大于“ 20”,则向Random-Boolean-Device设备发送命令,并开启布尔值的随机生成 。 以下是规则定义,请注意:

  • 当uint8的值大于20时将触发该动作。由于uint8的值不用于向Random-Boolean-Device发送控制命令,因此在rest操作的dataTemplate属性中不使用uint8值。
  1. curl -X POST \
  2. http://$eKuiper_server:59720/rules \
  3. -H 'Content-Type: application/json' \
  4. -d '{
  5. "id": "rule1",
  6. "sql": "SELECT uint8 FROM demo WHERE uint8 > 20",
  7. "actions": [
  8. {
  9. "rest": {
  10. "url": "http://edgex-core-command:59882/api/v2/device/name/Random-Boolean-Device/WriteBoolValue",
  11. "method": "put",
  12. "dataTemplate": "{\"Bool\":\"true\", \"EnableRandomization_Bool\": \"true\"}",
  13. "sendSingle": true
  14. }
  15. },
  16. {
  17. "log":{}
  18. }
  19. ]
  20. }'

第二条规则

第二条规则监视Random-Integer-Device设备,如果每20秒 int8的平均值大于0,则向Random-Boolean-Device 设备服务发送命令以关闭 布尔值的随机生成。

  • uint8的平均值每20秒计算一次,如果平均值大于0,则向 Random-Boolean-Device 服务发送控制命令。
  1. curl -X POST \
  2. http://$eKuiper_server:59720/rules \
  3. -H 'Content-Type: application/json' \
  4. -d '{
  5. "id": "rule2",
  6. "sql": "SELECT avg(int8) AS avg_int8 FROM demo WHERE int8 != nil GROUP BY TUMBLINGWINDOW(ss, 20) HAVING avg(int8) > 0",
  7. "actions": [
  8. {
  9. "rest": {
  10. "url": "http://edgex-core-command:59882/api/v2/device/name/Random-Boolean-Device/WriteBoolValue",
  11. "method": "put",
  12. "dataTemplate": "{\"Bool\":\"false\", \"EnableRandomization_Bool\": \"false\"}",
  13. "sendSingle": true
  14. }
  15. },
  16. {
  17. "log":{}
  18. }
  19. ]
  20. }'

现在创建了两个规则,您可以查看edgex-kuiper的日志以获取规则执行结果。

  1. # docker logs edgex-kuiper

如何从分析结果中提取数据?

由于分析结果也需要发送到command rest服务,如何从分析结果中提取数据?通过SQL过滤数据的示例如下所示:

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

SQL的输出内容如下:

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

当从字段int8读取value字段,从字段randomization读取EnableRandomization_Bool时,假设服务需要以下数据格式:

  1. curl -X PUT \
  2. http://edgex-core-command:59882/api/v2/device/name/${deviceName}/command \
  3. -H 'Content-Type: application/json' \
  4. -d '{"value":-75, "EnableRandomization_Bool": "true"}'

eKuiper使用Go模板 从分析结果中提取数据,并且dataTemplate 内容如下:

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

在某些情况下,您可能需要迭代返回的数组值,或使用if条件设置不同的值,然后参考此链接写入更复杂的数据模板表达式。

补充阅读材料

如果您想了解LF Edge eKuiper的更多特性,请阅读下面的参考资料: