Command device with EdgeX eKuiper rules engine

Overview

This document describes how to actuate a device with rules trigger by the eKuiper rules engine. To make the example simple, the virtual device device-virtual is used as the actuated device. The eKuiper rules engine analyzes the data sent from device-virtual services, and then sends a command to virtual device based a rule firing in eKuiper based on that analysis. It should be noted that an application service is used to route core data through the rules engine.

Use Case Scenarios

Rules will be created in eKuiper to watch for two circumstances:

  1. monitor for events coming from the Random-UnsignedInteger-Device device (one of the default virtual device managed devices), and if a uint8 reading value is found larger than 20 in the event, then send a command to Random-Boolean-Device device to start generating random numbers (specifically - set random generation bool to true).
  2. monitor for events coming from the Random-Integer-Device device (another of the default virtual device managed devices), and if the average for int8 reading values (within 20 seconds) is larger than 0, then send a command to Random-Boolean-Device device to stop generating random numbers (specifically - set random generation bool to false).

These use case scenarios do not have any real business meaning, but easily demonstrate the features of EdgeX automatic actuation accomplished via the eKuiper rule engine.

Prerequisite Knowledge

This document will not cover basic operations of EdgeX or LF Edge eKuiper. Readers should have basic knowledge of:

  • Get and start EdgeX. Refer to Quick Start for how to get and start EdgeX with the virtual device service.
  • Run the eKuiper Rules Engine. Refer to EdgeX eKuiper Rule Engine Tutorial to understand the basics of eKuiper and EdgeX.

Start eKuiper and Create an EdgeX Stream

Make sure you read the EdgeX eKuiper Rule Engine Tutorial and successfully run eKuiper with EdgeX.

First create a stream that can consume streaming data from the EdgeX application service (rules engine profile). This step is not required if you already finished the EdgeX eKuiper Rule Engine Tutorial .

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

Get and Test the Command URL

Since both use case scenario rules will send commands to the Random-Boolean-Device virtual device, use the curl request below to get a list of available commands for this device.

  1. curl http://127.0.0.1:59882/api/v2/device/name/Random-Boolean-Device | jq

It should print results like those below.

  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. }

From this output, look for the URL associated to the PUT command (the first URL listed). This is the command eKuiper will use to call on the device. There are two parameters for this command:

  • Bool: Set the returned value when other services want to get device data. The parameter will be used only when EnableRandomization_Bool is set to false.
  • EnableRandomization_Bool: Enable/disable the randomization generation of bool values. If this value is set to true, then the 1st parameter will be ignored.

You can test calling this command with its parameters using curl as shown below.

  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"}'

Create rules

Now that you have EdgeX and eKuiper running, the EdgeX stream defined, and you know the command to actuate Random-Boolean-Device, it is time to build the eKuiper rules.

The first rule

Again, the 1st rule is to monitor for events coming from the Random-UnsignedInteger-Device device (one of the default virtual device managed devices), and if a uint8 reading value is found larger than 20 in the event, then send the command to Random-Boolean-Device device to start generating random numbers (specifically - set random generation bool to true). Given the URL and parameters to the command, below is the curl command to declare the first rule in eKuiper.

  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. }'

The second rule

The 2nd rule is to monitor for events coming from the Random-Integer-Device device (another of the default virtual device managed devices), and if the average for int8 reading values (within 20 seconds) is larger than 0, then send a command to Random-Boolean-Device device to stop generating random numbers (specifically - set random generation bool to false). Here is the curl request to setup the second rule in eKuiper. The same command URL is used as the same device action (Random-Boolean-Device's PUT bool command) is being actuated, but with different parameters.

  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. }'

Watch the eKuiper Logs

Both rules are now created in eKuiper. eKuiper is busy analyzing the event data coming for the virtual devices looking for readings that match the rules you created. You can watch the edgex-kuiper container logs for the rule triggering and command execution.

  1. docker logs edgex-kuiper

Explore the Results

You can also explore the eKuiper analysis that caused the commands to be sent to the service. To see the the data from the analysis, use the SQL below to query eKuiper filtering data.

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

The output of the SQL should look similar to the results below.

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

Let’s suppose a service need following data format, while value field is read from field int8, and EnableRandomization_Bool is read from field randomization.

  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 uses Go template to extract data from analysis result, and the dataTemplate should be similar as following.

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

In some cases, you probably need to iterate over returned array values, or set different values with if conditions, then refer to this link for writing more complex data template expressions.

Extended readings

If you want to explore more features of eKuiper, please refer to below resources.