Switch node
The Switch node and the Change node are standard Node-RED nodes that provide conditional routing (selection) and data manipulation respectively for flow messages. Many of the WebSocket nodes, when using JSONata, can provide some output property data manipulation, and a few nodes also offer simple binary output message routing. However, much more can be achieved using JSONata in Switch and Change nodes in combination with the WebSocket nodes.
This example shows how to use JSONata within the standard Switch node.
[{"id":"fcb0d3b1b8ed3478","type":"group","z":"776c027950fc8c3f","name":"Switch node - selection routing based on entity details","style":{"label":true,"color":"#000000"},"nodes":["7f01d6eef386f743","84b7ac3a7e469780","60331de530222f6f","e253c6a934a17919","76bb91be0ae4c7b4","52713f1b7157f1f0"],"x":34,"y":2159,"w":852,"h":262},{"id":"7f01d6eef386f743","type":"poll-state","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"","server":"","version":3,"exposeAsEntityConfig":"","updateInterval":"10","updateIntervalType":"num","updateIntervalUnits":"seconds","outputInitially":false,"outputOnChanged":true,"entityId":"switch.t1","stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputs":1,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":150,"y":2240,"wires":[["84b7ac3a7e469780"]]},{"id":"84b7ac3a7e469780","type":"switch","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"","property":"$round(data.timeSinceChangedMs/60000,0)","propertyType":"jsonata","rules":[{"t":"btwn","v":"2","vt":"num","v2":"3","v2t":"num"},{"t":"gt","v":"data.state=\"on\" ? 4 : 1","vt":"jsonata"},{"t":"jsonata_exp","v":"data.timeSinceChangedMs < 60000","vt":"jsonata"},{"t":"else"}],"checkall":"true","repair":false,"outputs":4,"x":350,"y":2240,"wires":[["60331de530222f6f"],["e253c6a934a17919"],["76bb91be0ae4c7b4"],["52713f1b7157f1f0"]]},{"id":"60331de530222f6f","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"Last changed between 2 and 3 minutes ago","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\"Is \" & payload & \" for \" & $round(data.timeSinceChangedMs/60000, 0) & \" minutes\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":670,"y":2200,"wires":[]},{"id":"e253c6a934a17919","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"If on > 4 mins or if off > 1 mins","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\"Is \" & payload & \" for \" & $round(data.timeSinceChangedMs/60000, 0) & \" minutes\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":630,"y":2260,"wires":[]},{"id":"76bb91be0ae4c7b4","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"Changed state < 1 minute ago","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\"Is \" & payload & \" for \" & $round(data.timeSinceChangedMs/60000, 0) & \" minutes\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":630,"y":2320,"wires":[]},{"id":"52713f1b7157f1f0","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"Otherwise","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\"Is \" & payload & \" for \" & $round(data.timeSinceChangedMs/60000, 0) & \" minutes\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":560,"y":2380,"wires":[]}]
Using JSONata in switch routing
A Poll State node has been set up to return the entity state of a light switch every 10 seconds. This will return the entity state ("on" or "off") as the msg.payload value. It will also return the fuller entity state details in msg.data, which includes the 'timeSinceChangedMs' field.
JSONata for the routing property
$round(data.timeSinceChangedMs/60000,0)
The routing rules will test against the given property. By default this would be the value held in msg.payload. Using a JSONata expression here allows for a computation on the time since changed field to convert this to minutes. Rounding is also being used, so 31 to 89 seconds would become 1 minute.
Note that the JSONata expression has access to the full incoming message. The value required was output from the Poll State node within the output property msg.data field, and this has to be used here since the $entity()
functions are not available outside of the WebSocket nodes.
JSONata for the rule value
In the first rule, the rule values to test against are given as literals.
In the second rule, the rule test value is provided by a JSONata expression. This will return either 4, if the light state is "on", or 1 if the light state is "off".
data.state="on" ? 4 : 1
Note that 'payload' contains the state value and could have been used rather than 'data.state'. Where the output of a WebSocket node is used later in the flow for routing or processing, care should be taken to generate the most appropriate output. For example, rather than generate the Property match value here, this JSONata expression could be used in the Poll State node to provide minutes since last changed in the output msg.payload directly.
JSONata expression for the routing match
- In the third rule, the evaluation Property is not used. The test condition is the Boolean result of a JSONata expression. The routing path is taken only if the JSONata expression evaluates as
true
.
data.timeSinceChangedMs < 60000
The example is simplistic, however it shows that any incoming message property can be used within the expression.
Note that, since the $entities()
function is not available in a Switch node, to obtain other entity values, JSONata can be used in the preceding Poll State node to generate an output property, for example by setting msg.time to $entities('sensor.time').state
to provide 'time' as an available value for use in the Switch node.
- For completeness in these notes, a last rule of 'Otherwise' has been included, and the matching rules set to 'checking all rules'. This will mean that more than one of the first three rules may match at the same time, but that the last route is only taken when no other rule matches.
JSONata expression in the Debug node
The Debug nodes also contain JSONata as a further demonstration of how versatile and applicable this language can be.
Also see: