@ -0,0 +1,132 @@ |
|||
#### Fields templatization |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
{% include rulenode/common_node_fields_templatization %} |
|||
|
|||
##### Examples |
|||
|
|||
Let's assume that we have a moisture meter device(message originator) that publishes a telemetry messages that includes the following data readings: |
|||
|
|||
- `soilMoisture` |
|||
- `windSpeed` |
|||
- `windDirection` |
|||
- `temperature` |
|||
- `humidity` |
|||
|
|||
Depending on certain conditions, we might need to fetch additional server-side attributes from the moisture meter device. |
|||
|
|||
Specifically, if the soil moisture reading drops below a certain threshold, let's say 30%, this is considered critical as it directly impacts crop health and growth. |
|||
In this case, we need to fetch the `lastIrrigationTime` attribute. |
|||
This additional information can help us understand when the field was last watered and take necessary action, such as activating the irrigation system. |
|||
However, if the soil moisture is above this critical threshold, then we need to check another condition. |
|||
If the wind speed is above a certain level, say 8 m/s, we need to fetch the `lastWindSpeedAlarmTime` attribute. |
|||
This additional information can help us to understand when the last significant wind event occurred, |
|||
which might be indicative of an approaching storm or damaging winds. |
|||
|
|||
Consider that you write a script that depending on a conditions written above will add to the message metadata additional key: `keyToFetch` with one of the next values: |
|||
|
|||
- `lastIrrigationTime` |
|||
- `lastWindSpeedAlarmTime` |
|||
|
|||
In order to fetch value of one of the following keys for the further message processing you can define next node configuration: |
|||
|
|||
 |
|||
|
|||
- message definition that match first condition after processing in the script node: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 26.5, |
|||
"humidity": 75.2, |
|||
"soilMoisture": 28.9, |
|||
"windSpeed": 8.2, |
|||
"windDirection": "NNE" |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "default", |
|||
"deviceName": "SN-001", |
|||
"ts": "1685379440000", |
|||
"keyToFetch": "lastIrrigationTime" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
- message definition that match second condition after processing in the script node: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 26.5, |
|||
"humidity": 75.2, |
|||
"soilMoisture": 32.5, |
|||
"windSpeed": 10.4, |
|||
"windDirection": "NNE" |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "default", |
|||
"deviceName": "SN-001", |
|||
"ts": "1685379440000", |
|||
"keyToFetch": "lastWindSpeedAlarmTime" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
Rule node configuration set to fetch data to the message metadata. In the following way: |
|||
|
|||
- outgoing message for the first condition would be updated to: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 26.5, |
|||
"humidity": 75.2, |
|||
"soilMoisture": 28.9, |
|||
"windSpeed": 8.2, |
|||
"windDirection": "NNE" |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "default", |
|||
"deviceName": "SN-001", |
|||
"ts": "1685379440000", |
|||
"keyToFetch": "lastIrrigationTime", |
|||
"ss_lastIrrigationTime": "1685369440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
- outgoing message for the second condition would be updated to: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 26.5, |
|||
"humidity": 75.2, |
|||
"soilMoisture": 32.5, |
|||
"windSpeed": 10.4, |
|||
"windDirection": "NNE" |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "default", |
|||
"deviceName": "MM-001", |
|||
"ts": "1685379440000", |
|||
"keyToFetch": "lastWindSpeedAlarmTime", |
|||
"ss_lastWindSpeedAlarmTime": "1685359440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
These examples showcases using the **originator attributes** node with dynamic configuration based on the substitution of metadata fields. |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,106 @@ |
|||
#### Fields templatization |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
{% include rulenode/common_node_fields_templatization %} |
|||
|
|||
##### Examples |
|||
|
|||
Let's assume that we have two device types in our use case: |
|||
|
|||
- `smart_door_lock` |
|||
- `motion_detector` |
|||
|
|||
Let's assume that device of type `dock_lock_sensor` and name `SDL-001` publish next type of messages to the system: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"status": "locked" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "SDL-001", |
|||
"deviceType": "smart_door_lock", |
|||
"ts": "1685379440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
and device of type `motion_detector` and name `MD-001` publish next type of messages to the system: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"motionDetected": "true" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "MD-001", |
|||
"deviceType": "motion_detector", |
|||
"ts": "1685379440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
Imagine that you send the messages received from the devices to the external systems |
|||
and depending on the device type you need add to the message the human-readable label |
|||
of the device with field name equal to the `deviceType` value from the message metadata. |
|||
|
|||
Let's assume that devices have next labels: |
|||
|
|||
- *Grocery warehouse door* for `SDL-001` device. |
|||
- *Grocery Warehouse motion detector* for `MD-001` device. |
|||
|
|||
In order to fetch labels and add them to the message with the appropriate field name |
|||
you can define the next node configuration: |
|||
|
|||
 |
|||
|
|||
<br> |
|||
|
|||
Rule node configuration set to fetch data to the message. In the following way: |
|||
|
|||
- outgoing message for the `SDL-001` device would be updated to: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"status": "locked", |
|||
"smart_door_lock": "Grocery warehouse door" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "SDL-001", |
|||
"deviceType": "smart_door_lock", |
|||
"ts": "1685379440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
- outgoing message for the `MD-001` device would be updated to: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"motionDetected": "true", |
|||
"motion_detector": "Grocery Warehouse motion detector" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "MD-001", |
|||
"deviceType": "motion_detector", |
|||
"ts": "1685379440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
These examples showcases using the **originator fields** node with dynamic configuration based on the substitution of metadata fields. |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,292 @@ |
|||
#### Fields templatization |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
{% include rulenode/common_node_fields_templatization %} |
|||
|
|||
##### Examples |
|||
|
|||
Originator telemetry node support templatization for multiple configuration fields. Namely, you can specify the template in the |
|||
*Timeseries keys* list, and also there is an option to use the templatization for the fetch interval start and end if you are using *dynamic interval*. |
|||
|
|||
###### Example 1 |
|||
|
|||
Let's start with an example of using templatization for the *Timeseries keys* list. |
|||
Imagine that you have a GPS tracker device(message originator) that publishes a telemetry messages that includes the following data readings: |
|||
|
|||
- `latitude` - current device latitude value. |
|||
- `longitude` - current device longitude value. |
|||
- `event` - parameter that specifies the current state of the device. The value might be *parked* or *motion*. |
|||
|
|||
Additionally let's imagine that devices periodically publishes other telemetry messages that includes additional information such as: |
|||
|
|||
- `speed` - current speed value. |
|||
- `direction` - compass direction in which the device is moving. |
|||
- `acceleration` - how quickly the speed of the device is changing. |
|||
- `fuel_level` - current fuel level. |
|||
- `battery_level` - current battery level. |
|||
- `parked_location` - precise location where the device is parked. |
|||
- `parked_duration` - current park duration value. |
|||
- `parked_time` - timestamp when the device was parked. |
|||
|
|||
Let's imagine that we need to make some historical analysis by fetching 3 latest telemetry readings for the keys listed below if the `event` value is set to *motion*: |
|||
|
|||
- `speed` |
|||
- `direction` |
|||
- `acceleration` |
|||
- `fuel_level` |
|||
- `battery_level` |
|||
|
|||
Otherwise, if the `event` value is set to *parked* value we need to fetch 3 latest telemetry readings for the following data keys: |
|||
|
|||
- `parked_location` |
|||
- `parked_duration` |
|||
- `parked_time` |
|||
- `fuel_level` |
|||
- `battery_level` |
|||
|
|||
Imagine that you created a script node that depending on the `event` value adds to the message metadata appropriate keyToFetch fields. |
|||
|
|||
- message definition that match condition when `event` is set to *motion* value after processing in the script node: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"latitude": "40.730610", |
|||
"longitude": "-73.935242", |
|||
"event": "motion" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "GPS-001", |
|||
"deviceType": "GPS Tracker", |
|||
"ts": "1685479440000", |
|||
"keyToFetch1": "speed", |
|||
"keyToFetch2": "direction", |
|||
"keyToFetch3": "acceleration" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
- message definition that match condition when `event` is set to *parked* value after processing in the script node: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"latitude": "40.730610", |
|||
"longitude": "-73.935242", |
|||
"event": "parked" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "GPS-001", |
|||
"deviceType": "GPS Tracker", |
|||
"ts": "1685379440000", |
|||
"keyToFetch1": "parked_location", |
|||
"keyToFetch2": "parked_duration", |
|||
"keyToFetch3": "parked_time" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
In order to fetch the additional telemetry key values to make some historical analysis of the tracker's state you can define the next node configuration: |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
<br> |
|||
|
|||
Rule node configuration is set to retrieve the telemetry from the fetch interval with configurable query parameters that you can check above. |
|||
So let's imagine that 3 latest values for the keys that we are going to fetch are: |
|||
|
|||
- `speed` - 5.2, 15.7, 30.2 (mph). |
|||
- `direction` - N(North), NE(North-East), E(East). |
|||
- `acceleration` - 2.2, 2.4, 2.5 (m/s²). |
|||
- `fuel_level` - 61.5, 57.4, 55.6 (%). |
|||
- `battery_level` - 88.1, 87.8, 87.2 (%). |
|||
- `parked_location` - dr5rtwceb (geohash). Same value for 3 latest data readings. |
|||
- `parked_duration` - 6300000, 7300000, 8300000 (ms). |
|||
- `parked_time` - 1685339240000 (ms). Same value for 3 latest data readings. |
|||
|
|||
In the following way: |
|||
|
|||
- outgoing message for the case when the `event` has value *motion* would be look like this: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"latitude": "40.730610", |
|||
"longitude": "-73.935242", |
|||
"event": "motion" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "GPS-001", |
|||
"deviceType": "GPS Tracker", |
|||
"ts": "1685479440000", |
|||
"keyToFetch1": "speed", |
|||
"keyToFetch2": "direction", |
|||
"keyToFetch3": "acceleration", |
|||
"speed": "[{\"ts\":1685476840000,\"value\":5.2},{\"ts\":1685477840000,\"value\":15.7},{\"ts\":1685478840000,\"value\":30.2}]", |
|||
"direction": "[{\"ts\":1685476840000,\"value\":\"N\"},{\"ts\":1685477840000,\"value\":\"NE\"},{\"ts\":1685478840000,\"value\":\"N\"}]", |
|||
"acceleration": "[{\"ts\":1685476840000,\"value\":2.2},{\"ts\":1685477840000,\"value\":2.4},{\"ts\":1685478840000,\"value\":2.5}]", |
|||
"fuel_level": "[{\"ts\":1685476840000,\"value\":61.5},{\"ts\":1685477840000,\"value\":57.4},{\"ts\":1685478840000,\"value\":55.6}]", |
|||
"battery_level": "[{\"ts\":1685476840000,\"value\":88.1},{\"ts\":1685477840000,\"value\":87.8},{\"ts\":1685478840000,\"value\":87.2}]" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
- outgoing message for the case when the `event` has value *parked* would be look like this: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"latitude": "40.730610", |
|||
"longitude": "-73.935242", |
|||
"event": "parked" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "GPS-001", |
|||
"deviceType": "GPS Tracker", |
|||
"ts": "1685379440000", |
|||
"keyToFetch1": "parked_location", |
|||
"keyToFetch2": "parked_duration", |
|||
"keyToFetch3": "parked_time", |
|||
"parked_location": "[{\"ts\":1685376840000,\"value\":\"dr5rtwceb\"},{\"ts\":1685377840000,\"value\":\"dr5rtwceb\"},{\"ts\":1685378840000,\"value\":\"dr5rtwceb\"}]", |
|||
"parked_duration": "[{\"ts\":1685376840000,\"value\":6300000},{\"ts\":1685377840000,\"value\":7300000},{\"ts\":1685378840000,\"value\":8300000}]", |
|||
"parked_time": "[{\"ts\":1685376840000,\"value\":1685376840000},{\"ts\":1685377840000,\"value\":1685377840000},{\"ts\":1685378840000,\"value\":1685378840000}]", |
|||
"fuel_level": "[{\"ts\":1685376840000,\"value\":61.5},{\"ts\":1685377840000,\"value\":57.4},{\"ts\":1685378840000,\"value\":55.6}]", |
|||
"battery_level": "[{\"ts\":1685376840000,\"value\":88.1},{\"ts\":1685377840000,\"value\":87.8},{\"ts\":1685378840000,\"value\":87.2}]" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
###### Example 2 |
|||
|
|||
This example will extend the previous example with additional condition: |
|||
|
|||
Imagine that you need to specify the fetch interval dynamically from the 1 hour ago till the current time. |
|||
Additionally let's assume that the current time can be extracted from `ts` field that we have in the message metadata on each message received. |
|||
While the value of (1 hour ago) can be calculated in the script node that we use for adding keyToFetch fields into metadata. |
|||
|
|||
In the following way: |
|||
|
|||
- message definition that match condition when `event` is set to *motion* value after processing in the script node: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"latitude": "40.730610", |
|||
"longitude": "-73.935242", |
|||
"event": "motion" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "GPS-001", |
|||
"deviceType": "GPS Tracker", |
|||
"ts": "1685479440000", |
|||
"keyToFetch1": "speed", |
|||
"keyToFetch2": "direction", |
|||
"keyToFetch3": "acceleration", |
|||
"dynamicIntervalStart": "1685475840000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
- message definition that match condition when `event` is set to *parked* value after processing in the script node: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"latitude": "40.730610", |
|||
"longitude": "-73.935242", |
|||
"event": "parked" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "GPS-001", |
|||
"deviceType": "GPS Tracker", |
|||
"ts": "1685379440000", |
|||
"keyToFetch1": "parked_location", |
|||
"keyToFetch2": "parked_duration", |
|||
"keyToFetch3": "parked_time", |
|||
"dynamicIntervalStart": "1685375840000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
In order to fetch the data using dynamic interval we need enable *Use dynamic interval* option in the rule node configuration and specify the templates for the *Interval start* and *Interval end*: |
|||
|
|||
|
|||
 |
|||
|
|||
<br> |
|||
|
|||
Other configuration wasn't change from our previous example. |
|||
In the following way: |
|||
|
|||
- outgoing message for the case when the `event` has value *motion* would be look like this: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"latitude": "40.730610", |
|||
"longitude": "-73.935242", |
|||
"event": "motion" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "GPS-001", |
|||
"deviceType": "GPS Tracker", |
|||
"ts": "1685479440000", |
|||
"keyToFetch1": "speed", |
|||
"keyToFetch2": "direction", |
|||
"keyToFetch3": "acceleration", |
|||
"dynamicIntervalStart": "1685475840000", |
|||
"speed": "[{\"ts\":1685476840000,\"value\":5.2},{\"ts\":1685477840000,\"value\":15.7},{\"ts\":1685478840000,\"value\":30.2}]", |
|||
"direction": "[{\"ts\":1685476840000,\"value\":\"N\"},{\"ts\":1685477840000,\"value\":\"NE\"},{\"ts\":1685478840000,\"value\":\"N\"}]", |
|||
"acceleration": "[{\"ts\":1685476840000,\"value\":2.2},{\"ts\":1685477840000,\"value\":2.4},{\"ts\":1685478840000,\"value\":2.5}]", |
|||
"fuel_level": "[{\"ts\":1685476840000,\"value\":61.5},{\"ts\":1685477840000,\"value\":57.4},{\"ts\":1685478840000,\"value\":55.6}]", |
|||
"battery_level": "[{\"ts\":1685476840000,\"value\":88.1},{\"ts\":1685477840000,\"value\":87.8},{\"ts\":1685478840000,\"value\":87.2}]" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
- outgoing message for the case when the `event` has value *parked* would be look like this: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"latitude": "40.730610", |
|||
"longitude": "-73.935242", |
|||
"event": "parked" |
|||
}, |
|||
"metadata": { |
|||
"deviceName": "GPS-001", |
|||
"deviceType": "GPS Tracker", |
|||
"ts": "1685379440000", |
|||
"keyToFetch1": "parked_location", |
|||
"keyToFetch2": "parked_duration", |
|||
"keyToFetch3": "parked_time", |
|||
"dynamicIntervalStart": "1685375840000", |
|||
"parked_location": "[{\"ts\":1685376840000,\"value\":\"dr5rtwceb\"},{\"ts\":1685377840000,\"value\":\"dr5rtwceb\"},{\"ts\":1685378840000,\"value\":\"dr5rtwceb\"}]", |
|||
"parked_duration": "[{\"ts\":1685376840000,\"value\":6300000},{\"ts\":1685377840000,\"value\":7300000},{\"ts\":1685378840000,\"value\":8300000}]", |
|||
"parked_time": "[{\"ts\":1685376840000,\"value\":1685376840000},{\"ts\":1685377840000,\"value\":1685377840000},{\"ts\":1685378840000,\"value\":1685378840000}]", |
|||
"fuel_level": "[{\"ts\":1685376840000,\"value\":61.5},{\"ts\":1685377840000,\"value\":57.4},{\"ts\":1685378840000,\"value\":55.6}]", |
|||
"battery_level": "[{\"ts\":1685376840000,\"value\":88.1},{\"ts\":1685377840000,\"value\":87.8},{\"ts\":1685378840000,\"value\":87.2}]" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
These examples showcases using the **originator telemetry** node with dynamic configuration based on the substitution of metadata fields. |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,132 @@ |
|||
#### Fields templatization |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
{% include rulenode/common_node_fields_templatization %} |
|||
|
|||
##### Examples |
|||
|
|||
Let's assume that we have a moisture meter device(message originator) that publishes a telemetry messages that includes the following data readings: |
|||
|
|||
- `soilMoisture` |
|||
- `windSpeed` |
|||
- `windDirection` |
|||
- `temperature` |
|||
- `humidity` |
|||
|
|||
Depending on certain conditions, we might need to fetch additional server-side attributes from the related irrigation controller device. |
|||
|
|||
Specifically, if the soil moisture reading drops below a certain threshold, let's say 30%, this is considered critical as it directly impacts crop health and growth. |
|||
In this case, we need to fetch the `lastIrrigationTime` attribute. |
|||
This additional information can help us understand when the field was last watered and take necessary action, such as activating the irrigation system. |
|||
However, if the soil moisture is above this critical threshold, then we need to check another condition. |
|||
If the wind speed is above a certain level, say 8 m/s, we might need to fetch the `lastIrrigationPauseTime` attribute. |
|||
This additional information can help us understand when the last time the irrigation system was paused due to high wind conditions, |
|||
which might help to make more informed decisions about when and how to irrigate, considering both current and historical weather conditions. |
|||
|
|||
Consider that you write a script that depending on a conditions written above will add to the message metadata additional key: `keyToFetch` with one of the next values: |
|||
|
|||
- `lastIrrigationTime` |
|||
- `lastIrrigationPauseTime` |
|||
|
|||
In order to fetch value of one of the following keys for the further message processing you can define next node configuration: |
|||
|
|||
 |
|||
|
|||
- message definition that match first condition after processing in the script node: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 26.5, |
|||
"humidity": 75.2, |
|||
"soilMoisture": 28.9, |
|||
"windSpeed": 8.2, |
|||
"windDirection": "NNE" |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "default", |
|||
"deviceName": "MM-001", |
|||
"ts": "1685379440000", |
|||
"keyToFetch": "lastIrrigationTime" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
- message definition that match second condition after processing in the script node: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 26.5, |
|||
"humidity": 75.2, |
|||
"soilMoisture": 32.5, |
|||
"windSpeed": 10.4, |
|||
"windDirection": "NNE" |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "default", |
|||
"deviceName": "MM-001", |
|||
"ts": "1685379440000", |
|||
"keyToFetch": "lastIrrigationPauseTime" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
Rule node configuration set to fetch data to the message metadata. In the following way: |
|||
|
|||
- outgoing message for the first condition would be updated to: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 26.5, |
|||
"humidity": 75.2, |
|||
"soilMoisture": 28.9, |
|||
"windSpeed": 8.2, |
|||
"windDirection": "NNE" |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "default", |
|||
"deviceName": "MM-001", |
|||
"ts": "1685379440000", |
|||
"keyToFetch": "lastIrrigationTime", |
|||
"ss_lastIrrigationTime": "1685369440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
- outgoing message the second condition would be updated to: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 26.5, |
|||
"humidity": 75.2, |
|||
"soilMoisture": 32.5, |
|||
"windSpeed": 10.4, |
|||
"windDirection": "NNE" |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "default", |
|||
"deviceName": "MM-001", |
|||
"ts": "1685379440000", |
|||
"keyToFetch": "lastIrrigationPauseTime", |
|||
"ss_lastIrrigationPauseTime": "1685359440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
These examples showcases using the **related device attributes** node with dynamic configuration based on the substitution of metadata fields. |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,111 @@ |
|||
#### Fields templatization |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
{% include rulenode/common_node_fields_templatization %} |
|||
|
|||
##### Examples |
|||
|
|||
Let's consider a scenario where we possess an asset that serves as a warehouse |
|||
and is responsible for overseeing two categories of devices: |
|||
|
|||
- sensors measuring `temperature`. |
|||
- sensors measuring `humidity`. |
|||
|
|||
Additionally, let's assume that this asset has configured thresholds set as attributes for each device type: |
|||
|
|||
- *temperature_min_threshold* and *temperature_max_threshold* for temperature sensor with values set to *10* and *30* accordingly. |
|||
- *humidity_min_threshold* and *humidity_max_threshold* for humidity sensor with values set to *70* and *85* accordingly. |
|||
|
|||
Each message received from device includes `deviceType` property in the message metadata |
|||
with either `temperature` or `humidity` value according to the sensor type. |
|||
|
|||
In order to fetch the threshold value for the further message processing you can define next node configuration: |
|||
|
|||
 |
|||
 |
|||
|
|||
Imagine that you receive message defined below from the `temperature` sensor |
|||
and forwarded it to the **related entity data** node with configuration added above. |
|||
|
|||
- incoming message definition: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 32 |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "temperature", |
|||
"deviceName": "TH-001", |
|||
"ts": "1685379440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
The same example for the `humidity` sensor: |
|||
|
|||
- incoming message definition: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"humidity": 77 |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "humidity", |
|||
"deviceName": "HM-001", |
|||
"ts": "1685379440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
Rule node configuration set to fetch data to the message metadata. In the following way: |
|||
|
|||
- outgoing message for the `temperature` sensor would be updated to: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 32 |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "temperature", |
|||
"deviceName": "TH-001", |
|||
"ts": "1685379440000", |
|||
"min_threshold": "10", |
|||
"max_threshold": "30" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
- outgoing message for the `humidity` sensor would be updated to: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"humidity": 77 |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "humidity", |
|||
"deviceName": "HM-001", |
|||
"ts": "1685379440000", |
|||
"min_threshold": "70", |
|||
"max_threshold": "85" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
These examples showcases using the **related entity data** node with dynamic configuration based on the substitution of metadata fields. |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,107 @@ |
|||
#### Fields templatization |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
{% include rulenode/common_node_fields_templatization %} |
|||
|
|||
##### Examples |
|||
|
|||
Let's assume that tenant manage two type of devices: `temperature` and `humidity` sensors. |
|||
Additionally, let's assume that tenant configured the thresholds settings for each device type. |
|||
Threshold settings stored as an attributes on a tenant level: |
|||
|
|||
- *temperature_min_threshold* and *temperature_max_threshold* for temperature sensor with values set to *10* and *30* accordingly. |
|||
- *humidity_min_threshold* and *humidity_max_threshold* for humidity sensor with values set to *70* and *85* accordingly. |
|||
|
|||
Each message received from device includes `deviceType` property in the message metadata |
|||
with either `temperature` or `humidity` value according to the sensor type. |
|||
|
|||
In order to fetch the threshold value for the further message processing you can define next node configuration: |
|||
|
|||
 |
|||
|
|||
Imagine that you receive message defined below from the `temperature` sensor |
|||
and forwarded it to the **tenant attributes** node with configuration added above. |
|||
|
|||
- incoming message definition: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 32 |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "temperature", |
|||
"deviceName": "TH-001", |
|||
"ts": "1685379440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
The same example for the `humidity` sensor: |
|||
|
|||
- incoming message definition: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"humidity": 77 |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "humidity", |
|||
"deviceName": "HM-001", |
|||
"ts": "1685379440000" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
Rule node configuration set to fetch data to the message metadata. In the following way: |
|||
|
|||
- outgoing message for the `temperature` sensor would be updated to: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"temperature": 32 |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "temperature", |
|||
"deviceName": "TH-001", |
|||
"ts": "1685379440000", |
|||
"min_threshold": "10", |
|||
"max_threshold": "30" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
- outgoing message for the `humidity` sensor would be updated to: |
|||
|
|||
```json |
|||
{ |
|||
"msg": { |
|||
"humidity": 77 |
|||
}, |
|||
"metadata": { |
|||
"deviceType": "humidity", |
|||
"deviceName": "HM-001", |
|||
"ts": "1685379440000", |
|||
"min_threshold": "70", |
|||
"max_threshold": "85" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
<br> |
|||
|
|||
These examples showcases using the **tenant attributes** node with dynamic configuration based on the substitution of metadata fields. |
|||
|
|||
<br> |
|||
<br> |
|||
|
|||
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 81 KiB |