[newbie] How to improve this flow?

Can anyone here tell me how the "on_or_off function-node" could be merged with the "ChangeLightState template-node", leaving the ChangeLightState-node in its current position.
Here is my flow:

[{"id":"85f4e1c9.1710d8","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"dfd0784a.77a588","type":"websocket in","z":"85f4e1c9.1710d8","name":"rhasspywebsocket","server":"9b8318ef.a6f0e8","client":"","x":110,"y":140,"wires":[["b66dec54.3e3128"]]},{"id":"b66dec54.3e3128","type":"json","z":"85f4e1c9.1710d8","name":"","property":"payload","action":"","pretty":false,"x":230,"y":260,"wires":[["4d244953.608ed","5bc73af1.edfa94"]]},{"id":"b29d42d5.d4aef8","type":"change","z":"85f4e1c9.1710d8","name":"Unknown intent","rules":[{"t":"set","p":"payload","pt":"msg","to":"Wat zei u?","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":620,"y":260,"wires":[["41f4b7d8.caec38"]]},{"id":"41f4b7d8.caec38","type":"http request","z":"85f4e1c9.1710d8","name":"text to speech","method":"POST","ret":"txt","paytoqs":"ignore","url":"http://rhasspy:12101/api/text-to-speech","tls":"","persist":false,"proxy":"","authType":"","x":900,"y":280,"wires":[[]]},{"id":"b7e7def1.8a264","type":"template","z":"85f4e1c9.1710d8","name":"ChangeLightState","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"Ik zet de {{ payload.slots.name }} {{ payload.slots.state}}","output":"str","x":630,"y":320,"wires":[["41f4b7d8.caec38"]]},{"id":"4c3f90e6.23fdf8","type":"mosca in","z":"85f4e1c9.1710d8","mqtt_port":"1883","mqtt_ws_port":8080,"name":"","username":"","password":"","dburl":"","x":110,"y":60,"wires":[[]]},{"id":"8007f30c.a1c978","type":"inject","z":"85f4e1c9.1710d8","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":220,"y":3240,"wires":[["be9d9f76.d76508"]]},{"id":"be9d9f76.d76508","type":"http request","z":"85f4e1c9.1710d8","name":"Relay off","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.85/cm?cmnd=POWER OFF","tls":"","persist":false,"proxy":"","authType":"","x":420,"y":3240,"wires":[[]]},{"id":"3619cc3a.ffdf8c","type":"inject","z":"85f4e1c9.1710d8","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":220,"y":3280,"wires":[["bd20226d.2f788"]]},{"id":"bd20226d.2f788","type":"http request","z":"85f4e1c9.1710d8","name":"Relay on","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.85/cm?cmnd=POWER ON","tls":"","persist":false,"proxy":"","authType":"","x":420,"y":3280,"wires":[[]]},{"id":"9f674c76.a2fc78","type":"http request","z":"85f4e1c9.1710d8","name":"Relay toggle","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.85/cm?cmnd=POWER TOGGLE","tls":"","persist":false,"proxy":"","authType":"","x":430,"y":3320,"wires":[[]]},{"id":"aa85d8be.d8afa8","type":"inject","z":"85f4e1c9.1710d8","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":220,"y":3320,"wires":[["9f674c76.a2fc78"]]},{"id":"59d12f94.53baa8","type":"http request","z":"85f4e1c9.1710d8","name":"Status","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.85/cm?cmnd=STATUS","tls":"","persist":false,"proxy":"","authType":"","x":410,"y":3380,"wires":[["62373e0f.750f4"]]},{"id":"8e69f1fc.ea425","type":"inject","z":"85f4e1c9.1710d8","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":220,"y":3380,"wires":[["59d12f94.53baa8"]]},{"id":"62373e0f.750f4","type":"debug","z":"85f4e1c9.1710d8","name":"","active":false,"console":"false","complete":"false","x":610,"y":3380,"wires":[]},{"id":"d3ea82e7.1fef7","type":"comment","z":"85f4e1c9.1710d8","name":"HTTP control","info":"Controlling the relay via HTTP\nHTTP API in the admin page need to be turned off\nCopy the api key from the admin page\n\nURL http://<ip>/api/relay/0?apikey=<api key>&value=0\naccepted values (at the end):\n0: off\n1: on\n2: toggle","x":170,"y":3200,"wires":[]},{"id":"4d244953.608ed","type":"switch","z":"85f4e1c9.1710d8","name":"","property":"payload.intent.name","propertyType":"msg","rules":[{"t":"eq","v":"","vt":"str"},{"t":"eq","v":"ChangeLightState","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":400,"y":300,"wires":[["b29d42d5.d4aef8"],["b7e7def1.8a264"]]},{"id":"28237f32.3292f","type":"mqtt out","z":"85f4e1c9.1710d8","name":"","topic":"cmnd/sonoffsalon/power","qos":"0","retain":"","broker":"f56d1a7c.e35768","x":770,"y":600,"wires":[]},{"id":"3db4e9f7.6e8086","type":"inject","z":"85f4e1c9.1710d8","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"off","payloadType":"str","x":410,"y":720,"wires":[["28237f32.3292f"]]},{"id":"fc34bb30.af20c","type":"inject","z":"85f4e1c9.1710d8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"on","payloadType":"str","x":410,"y":760,"wires":[["28237f32.3292f"]]},{"id":"1accfeb0.f4c2a9","type":"comment","z":"85f4e1c9.1710d8","name":"MQTT control","info":"Controlling the relay via MQTT\n\nroot topic followed by relay/0/set\naccepted messages:\n0: off\n1: on\n2: toggle","x":410,"y":680,"wires":[]},{"id":"5bc73af1.edfa94","type":"function","z":"85f4e1c9.1710d8","name":"on_or_off","func":"\n if ((msg.payload.slots.state==\"aan\") && (msg.payload.slots.name==\"salonverlichting\"))\n  {\n      msg.payload=\"on\";\n  } else {\n      if ((msg.payload.slots.state==\"uit\") && (msg.payload.slots.name==\"salonverlichting\"))\n      {\n        msg.payload=\"off\";\n      }\n  }  \n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":600,"wires":[["28237f32.3292f"]]},{"id":"9b8318ef.a6f0e8","type":"websocket-listener","z":"","path":"ws://rhasspy:12101/api/events/intent","wholemsg":"false"},{"id":"f56d1a7c.e35768","type":"mqtt-broker","z":"","name":"localhost:1883","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

kind regards,
Hugo

Hugo when posting a flow, please include it in your post (I've done that for you)
It's also helpful to tell people what 'extra' nodes you are using in your flow

You are testing two different variables in the two different nodes. In addition, in your function node there are three possible outcomes.

Write out in - psuedo code - what you want to do - i.e.

  1. if msg.payload.intent.name is 'xxxxx' then do yyyyy
  2. if msg.payload.slots.state is 'zzz' and .....

But my main question is why do you want to combine them?

Thanks for the remarks. I am trying to make a Rhasspy-system with a node-red flow. Rhasspy functions correctly, i.e. it produces the correct intent when I say something to it.
As an example:
When I say:
"zet de salonverlichting aan"
(translated in bad English: put the restroomlight on)
The following json-code is produced:

{
"entities": [
{
"end": 23,
"entity": "name",
"raw_end": 23,
"raw_start": 7,
"raw_value": "salonverlichting",
"start": 7,
"value": "salonverlichting",
"value_details": {
"kind": "Unknown",
"value": "salonverlichting"
}
},
{
"end": 27,
"entity": "state",
"raw_end": 27,
"raw_start": 24,
"raw_value": "aan",
"start": 24,
"value": "aan",
"value_details": {
"kind": "Unknown",
"value": "aan"
}
}
],
"intent": {
"confidence": 1,
"name": "ChangeLightState"
},
"raw_text": "zet de salonverlichting aan",
"raw_tokens": [
"zet",
"de",
"salonverlichting",
"aan"
],
"recognize_seconds": 0.1270836799958488,
"slots": {
"name": "salonverlichting",
"state": "aan"
},
"speech_confidence": 1,
"text": "zet de salonverlichting aan",
"tokens": [
"zet",
"de",
"salonverlichting",
"aan"
],
"wakeword_id": null
}

The three parts of information which are important in this json-code are:
"ChangeLightState" which is the intent for which further actions should happen
"name" which is the name of the light for which the intent should be performed, e.g. salonverlichting which means "restroomlight"
"state" which is either "aan" (on) or "uit" (off)

Because the idea is to have a lot of different intents in the future (e.g GetTemperature, CheckInternetConnection...), the switch-node is used. For simplicity I have now reduced it to two possibilites: intent = "ChangeLightState" and intent not recognized.
As you can see, the switch is used to filter out the correct intent. If the correct intent is recognized (in this case: ChangeLightState) then the following should happen:
The light in the salon should be put on or off
and
I should hear a message from the system produced by the texttospeach-node which says:
Ik zet de {{ payload.slots.name }} {{ payload.slots.state}}
(In English; I put the {{payload.slots.name}} {{ payload.slots.state}})
e.g
Ik zet de salonverlichting aan
(In English: I put the restroomlight on)

The reason why I want the two nodes I mentioned in my original posting merged is, that if I leave the system like it is now, chances are when another intent is triggered the on_off-function node could also be activated, it should only be triggered when the correct intent is recognized.

Hopefully this makes things clearer.

ps.
I know there are a lot more considerations: e.g. the state of the light could be checked after the on_off action has been executed, but I don't care at this moment. In the example there is currently only one sonoff called esp001, in reality there will also be other ones like esp002 which resides in another room,
again it doesn't matter at this very moment. If I only could merge those two nodes in the first place.

Sorry I took so long to get back to you, yard work called while the weather was good, but it is raining now (yeah! we really need it - plus I can't do anymore yare work today!!!)

First off I would change the flow so the json node connects to the switch node only. In the switch node I would do this:


this way you can spin off each command. Note there is an 'otherwise' test at the end to pickup any commands that are not accounted for. In addition, change the bottom option from 'check all rules' to 'stopping after first match'. If you want to keep rhings neat, have each output of the switch node connect to a link-out node and then have a link-in node start the processing for that command. The link-in node could be on the same or a different tab like this:

Here is a start for you to get the idea. Note I added sysmessage node for my testing and I added an inject node with the json data you provided and debug nodes (debug nodes are very helpful to see what is going on.

[{"id":"9a45101c.7396c8","type":"tab","label":"Main Process","disabled":false,"info":""},{"id":"14c7c29e.fd0d95","type":"websocket in","z":"9a45101c.7396c8","name":"rhasspywebsocket","server":"c088685e.819f78","client":"","x":110,"y":140,"wires":[["dce2c00.0282ec"]]},{"id":"dce2c00.0282ec","type":"json","z":"9a45101c.7396c8","name":"","property":"payload","action":"","pretty":false,"x":150,"y":220,"wires":[["1d78ba60.09128e","e69ea5da.140508"]]},{"id":"a7feaacc.ce00f","type":"change","z":"9a45101c.7396c8","name":"Unknown intent","rules":[{"t":"set","p":"payload","pt":"msg","to":"Wat zei u?","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":280,"wires":[["115f79c5.fc8f6e","391bb16c.719696"]]},{"id":"391bb16c.719696","type":"http request","z":"9a45101c.7396c8","name":"text to speech","method":"POST","ret":"txt","paytoqs":"ignore","url":"http://rhasspy:12101/api/text-to-speech","tls":"","persist":false,"proxy":"","authType":"","x":880,"y":300,"wires":[[]]},{"id":"7da06eb3.99ae9","type":"mosca in","z":"9a45101c.7396c8","mqtt_port":"1883","mqtt_ws_port":8080,"name":"","username":"","password":"","dburl":"","x":110,"y":60,"wires":[[]]},{"id":"15442ef2.a33ba9","type":"inject","z":"9a45101c.7396c8","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":220,"y":3240,"wires":[["251484e0.7dfde4"]]},{"id":"251484e0.7dfde4","type":"http request","z":"9a45101c.7396c8","name":"Relay off","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.85/cm?cmnd=POWER OFF","tls":"","persist":false,"proxy":"","authType":"","x":420,"y":3240,"wires":[[]]},{"id":"dd9ff9c1.1294d","type":"inject","z":"9a45101c.7396c8","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":220,"y":3280,"wires":[["eb9d705b.bf926"]]},{"id":"eb9d705b.bf926","type":"http request","z":"9a45101c.7396c8","name":"Relay on","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.85/cm?cmnd=POWER ON","tls":"","persist":false,"proxy":"","authType":"","x":420,"y":3280,"wires":[[]]},{"id":"535e3a28.3a472c","type":"http request","z":"9a45101c.7396c8","name":"Relay toggle","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.85/cm?cmnd=POWER TOGGLE","tls":"","persist":false,"proxy":"","authType":"","x":430,"y":3320,"wires":[[]]},{"id":"865278ba.f4b36","type":"inject","z":"9a45101c.7396c8","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":220,"y":3320,"wires":[["535e3a28.3a472c"]]},{"id":"e8d0446c.223ff8","type":"http request","z":"9a45101c.7396c8","name":"Status","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.85/cm?cmnd=STATUS","tls":"","persist":false,"proxy":"","authType":"","x":410,"y":3380,"wires":[["b4287cec.e76058"]]},{"id":"5e3dc78.b3c3738","type":"inject","z":"9a45101c.7396c8","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":220,"y":3380,"wires":[["e8d0446c.223ff8"]]},{"id":"b4287cec.e76058","type":"debug","z":"9a45101c.7396c8","name":"","active":false,"console":"false","complete":"false","x":610,"y":3380,"wires":[]},{"id":"5b2c6004.0ff118","type":"comment","z":"9a45101c.7396c8","name":"HTTP control","info":"Controlling the relay via HTTP\nHTTP API in the admin page need to be turned off\nCopy the api key from the admin page\n\nURL http://<ip>/api/relay/0?apikey=<api key>&value=0\naccepted values (at the end):\n0: off\n1: on\n2: toggle","x":170,"y":3200,"wires":[]},{"id":"1d78ba60.09128e","type":"switch","z":"9a45101c.7396c8","name":"","property":"payload.intent.name","propertyType":"msg","rules":[{"t":"eq","v":"ChangeLightState","vt":"str"},{"t":"eq","v":"intent-2","vt":"str"},{"t":"eq","v":"intent-3","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":4,"x":370,"y":220,"wires":[["22511653.a235aa"],["c16ef32c.3af3f"],["4d5fed79.7bcc1c"],["a7feaacc.ce00f"]]},{"id":"55058b19.42b414","type":"inject","z":"9a45101c.7396c8","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"entities\":[{\"end\":23,\"entity\":\"name\",\"raw_end\":23,\"raw_start\":7,\"raw_value\":\"salonverlichting\",\"start\":7,\"value\":\"salonverlichting\",\"value_details\":{\"kind\":\"Unknown\",\"value\":\"salonverlichting\"}},{\"end\":27,\"entity\":\"state\",\"raw_end\":27,\"raw_start\":24,\"raw_value\":\"aan\",\"start\":24,\"value\":\"aan\",\"value_details\":{\"kind\":\"Unknown\",\"value\":\"aan\"}}],\"intent\":{\"confidence\":1,\"name\":\"ChangeLightState\"},\"raw_text\":\"zet de salonverlichting aan\",\"raw_tokens\":[\"zet\",\"de\",\"salonverlichting\",\"aan\"],\"recognize_seconds\":0.1270836799958488,\"slots\":{\"name\":\"salonverlichting\",\"state\":\"aan\"},\"speech_confidence\":1,\"text\":\"zet de salonverlichting aan\",\"tokens\":[\"zet\",\"de\",\"salonverlichting\",\"aan\"],\"wakeword_id\":null}","payloadType":"json","x":230,"y":100,"wires":[["9357d956.0c1f98","1d78ba60.09128e"]]},{"id":"115f79c5.fc8f6e","type":"sysmessage","z":"9a45101c.7396c8","command":"osxsay","title":"","subtitle":"","op1":"","op1type":"pay","receiver":"","name":"","x":860,"y":260,"wires":[[]]},{"id":"9357d956.0c1f98","type":"debug","z":"9a45101c.7396c8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":530,"y":100,"wires":[]},{"id":"6663fdc1.05103c","type":"catch","z":"9a45101c.7396c8","name":"","scope":null,"uncaught":false,"x":700,"y":40,"wires":[["98734f41.5a76e"]]},{"id":"98734f41.5a76e","type":"debug","z":"9a45101c.7396c8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":850,"y":40,"wires":[]},{"id":"e69ea5da.140508","type":"debug","z":"9a45101c.7396c8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":150,"y":260,"wires":[]},{"id":"22511653.a235aa","type":"link out","z":"9a45101c.7396c8","name":"to ChangeLightState","links":["fdbd5fb1.94a9a","121b5b54.e31465"],"x":580,"y":160,"wires":[],"l":true},{"id":"c16ef32c.3af3f","type":"link out","z":"9a45101c.7396c8","name":"to Command 2","links":[],"x":560,"y":200,"wires":[],"l":true},{"id":"4d5fed79.7bcc1c","type":"link out","z":"9a45101c.7396c8","name":"to Command 3","links":["fdbd5fb1.94a9a","121b5b54.e31465"],"x":560,"y":240,"wires":[],"l":true},{"id":"1c3ac4f3.1a1da3","type":"tab","label":"Change Light Status","disabled":false,"info":""},{"id":"aacfa480.0a09f","type":"template","z":"1c3ac4f3.1a1da3","name":"ChangeLightState","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"Ik zet de {{ payload.slots.name }} {{ payload.slots.state}}","output":"str","x":450,"y":160,"wires":[["d55dd98b.24a048","ca8cbd60.0af828"]]},{"id":"1637d207.3bc356","type":"mqtt out","z":"1c3ac4f3.1a1da3","name":"","topic":"cmnd/sonoffsalon/power","qos":"0","retain":"","broker":"21cda8c2.c80df","x":730,"y":240,"wires":[]},{"id":"98c0bf18.bfbf28","type":"inject","z":"1c3ac4f3.1a1da3","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"off","payloadType":"str","x":130,"y":260,"wires":[["1637d207.3bc356"]]},{"id":"7e4e494d.052e8","type":"inject","z":"1c3ac4f3.1a1da3","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"on","payloadType":"str","x":130,"y":300,"wires":[["1637d207.3bc356"]]},{"id":"b7164ff9.19c9b","type":"comment","z":"1c3ac4f3.1a1da3","name":"MQTT control","info":"Controlling the relay via MQTT\n\nroot topic followed by relay/0/set\naccepted messages:\n0: off\n1: on\n2: toggle","x":130,"y":220,"wires":[]},{"id":"7fa7f986.e0a83","type":"function","z":"1c3ac4f3.1a1da3","name":"on_or_off","func":"\n if ((msg.payload.slots.state==\"aan\") && (msg.payload.slots.name==\"salonverlichting\"))\n  {\n      msg.payload=\"on\";\n  } else {\n      if ((msg.payload.slots.state==\"uit\") && (msg.payload.slots.name==\"salonverlichting\"))\n      {\n        msg.payload=\"off\";\n      }\n  }  \n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":420,"y":200,"wires":[["1637d207.3bc356","cad5791d.529658"]]},{"id":"cad5791d.529658","type":"debug","z":"1c3ac4f3.1a1da3","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":670,"y":200,"wires":[]},{"id":"121b5b54.e31465","type":"link in","z":"1c3ac4f3.1a1da3","name":"ChangeLightState","links":["22511653.a235aa","4d5fed79.7bcc1c"],"x":150,"y":160,"wires":[["7fa7f986.e0a83","aacfa480.0a09f"]],"l":true},{"id":"d55dd98b.24a048","type":"sysmessage","z":"1c3ac4f3.1a1da3","command":"osxsay","title":"","subtitle":"","op1":"","op1type":"pay","receiver":"","name":"","x":700,"y":120,"wires":[[]]},{"id":"ca8cbd60.0af828","type":"http request","z":"1c3ac4f3.1a1da3","name":"text to speech","method":"POST","ret":"txt","paytoqs":"ignore","url":"http://rhasspy:12101/api/text-to-speech","tls":"","persist":false,"proxy":"","authType":"","x":720,"y":160,"wires":[[]]},{"id":"ea72546d.3f9358","type":"comment","z":"1c3ac4f3.1a1da3","name":"Change Light Status","info":"","x":150,"y":100,"wires":[]},{"id":"c088685e.819f78","type":"websocket-listener","z":"","path":"ws://rhasspy:12101/api/events/intent","wholemsg":"false"},{"id":"21cda8c2.c80df","type":"mqtt-broker","z":"","name":"localhost:1883","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
1 Like

Dear Zeno,
Thank you very much for helping me. What I meant by "merging the two nodes" in my previous mails is exactly what you wrote now: "I would change the flow so the json node connects to the switch node only". I'll modify my original flow now according to all your suggestions for improvement.

kind regards and thanks
hugo

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.