Reusing the part of the code (or even the node) in many places - or is there any easier way to repeat similar tasks?

I think you should think about strategy whether the macs are automatically obtained or set once manually. Manual once setting provides safety against dead devices if they are not appearing for some reason. Then you can trigger alarm that is not present.
Macs nor commands are not needed to specify in full if they are stored in the array. That is the beauty of arrays. Full macs and command numbers are passed by code.
You can use buttons, dropdowns, checkboxes etc. to select desired action plan. Using it in a such manner you can also use human readable meanings for all those ESPXXXX and MacXXXX an commands XX.

@E1cid we are getting there!!! :wink:


commands list has to be preprogrammed here - no issue as neither HA nor NR know which command means what
but now, if MAC addresses can be filled automatically, based on... exactly I am not sure based on what
because I have kind of 200+ devices in my network and all have "xxx_mac" sensor
but, devices we are talking about, have always in their device name, the word "ESPNow" i.e. here:
see below: 1st device is not espnow, others are:

I could also redo the xxx_mac sensor to i.e. include xxx_espnow_mac

You can feed msg.options into the dropdowns, read help text. You should be able create msg.options automatically from your HA devices, I do not use HA so can not help there. If you can query HA for mac's and names then you can create msg.options and feed that to the dropdown.

let me read your message 10 times, I shall then ... digest it :wink:
but honestly speaking @E1cid , you helped me already like crazy - thank you!

@Vilnis_R with regards to dead devices: I already have a measure: if rssi is not visible for 3 sleeping periods, then pushover message is sent, for gateways it is being generated if gateway is not visible for 30s already - and this works ok

@E1cid with multiple devices to be chosen I am "close to done"

is there such option like: "all marked by default"?
because now it is "all UN-marked" by default

@Vilnis_R setting macs automatically makes sense as well because now I can see it will be done ONLY in 1 place

You can use ui-control to monitor load and tab or group change or you can add a select all button. You can then feed a payload array containing all values you want to be selected by default.
e.g.

[{"id":"8033d897c74cc0f3","type":"ui_ui_control","z":"da8a6ef0b3c9a5c8","name":"","events":"all","x":240,"y":4560,"wires":[["a7e7d8cc96f44c34"]]},{"id":"a7e7d8cc96f44c34","type":"change","z":"da8a6ef0b3c9a5c8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"[\"xx:01:01:01:zz:yy\",\"xx:01:01:01:zz:xx\",\"xx:01:01:01:zz:zz\"]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":4620,"wires":[["40af0b19a53969e3"]]},{"id":"c1d68a7dd7be5b9f","type":"ui_button","z":"da8a6ef0b3c9a5c8","name":"","group":"2d4fe667.28f8ba","order":22,"width":0,"height":0,"passthru":false,"label":"select all","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":220,"y":4660,"wires":[["a7e7d8cc96f44c34"]]},{"id":"40af0b19a53969e3","type":"ui_dropdown","z":"da8a6ef0b3c9a5c8","name":"","label":"Mac's","tooltip":"","place":"Select option","group":"2d4fe667.28f8ba","order":19,"width":0,"height":0,"passthru":false,"multiple":true,"options":[{"label":"xx:01:01:01:zz:yy","value":"xx:01:01:01:zz:yy","type":"str"},{"label":"xx:01:01:01:zz:xx","value":"xx:01:01:01:zz:xx","type":"str"},{"label":"xx:01:01:01:zz:zz","value":"xx:01:01:01:zz:zz","type":"str"}],"payload":"","topic":"mac","topicType":"str","className":"","x":310,"y":4720,"wires":[["b5abf9ac49ebd729"]]},{"id":"b5abf9ac49ebd729","type":"join","z":"da8a6ef0b3c9a5c8","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":490,"y":4720,"wires":[["75a8cdcb7a2943f5"]]},{"id":"f993227bc94e2cd7","type":"ui_dropdown","z":"da8a6ef0b3c9a5c8","name":"","label":"commands","tooltip":"","place":"Select option","group":"2d4fe667.28f8ba","order":20,"width":0,"height":0,"passthru":true,"multiple":false,"options":[{"label":"ota","value":"1","type":"str"},{"label":"restart","value":"2","type":"str"},{"label":"captive","value":"3","type":"str"}],"payload":"","topic":"command","topicType":"str","className":"","x":350,"y":4780,"wires":[["b5abf9ac49ebd729"]]},{"id":"3d5993380e3ca2a9","type":"ui_button","z":"da8a6ef0b3c9a5c8","name":"","group":"2d4fe667.28f8ba","order":21,"width":0,"height":0,"passthru":false,"label":"send","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"send","topicType":"str","x":350,"y":4820,"wires":[["b5abf9ac49ebd729"]]},{"id":"75a8cdcb7a2943f5","type":"switch","z":"da8a6ef0b3c9a5c8","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"send","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":530,"y":4660,"wires":[["bf5fbbafd94a885f"]]},{"id":"bf5fbbafd94a885f","type":"function","z":"da8a6ef0b3c9a5c8","name":"function 20","func":"const topics =[\n    \"esp32027/cmd/cmd_for_sender\",\n    \"esp32029/cmd/cmd_for_sender\",\n    \"esp32030/cmd/cmd_for_sender\"\n];\nmsg.payload = {\n    command: msg.payload.command, \n    mac: msg.payload.mac\n};\n    \ntopics.forEach(str => {\n    msg.topic = str;\n    node.send(msg);\n})\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":650,"y":4720,"wires":[["eb74b20280fde506"]]},{"id":"eb74b20280fde506","type":"debug","z":"da8a6ef0b3c9a5c8","name":"debug 231","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":810,"y":4720,"wires":[]},{"id":"2d4fe667.28f8ba","type":"ui_group","name":"demo","tab":"1caa8458.b17814","order":2,"disp":true,"width":"12","collapse":false},{"id":"1caa8458.b17814","type":"ui_tab","name":"Demo","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

I have not updated function to handle array of mac's so ignore function

there is a small problem: in the message the mac parts comes with the square brackets so it is not recognized by the ESP because I did not anticipate brackets - where do I need to change to remove them?

when only 1 mac chosen (not allowing multiple), all is ok:

How have you edited the function node to handle multi selection from dropdown. When allowing multi selection the payload will be an array. You will need to export your flow so we are on same page.

[{"id":"2874231a956d91c4","type":"ui_ui_control","z":"6a7765e6961ddd1b","name":"","events":"all","x":640,"y":160,"wires":[["d857f6b32b1fec80"]]},{"id":"d857f6b32b1fec80","type":"change","z":"6a7765e6961ddd1b","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"[\"xx:01:01:01:zz:yy\",\"xx:01:01:01:zz:xx\",\"xx:01:01:01:zz:zz\"]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":860,"y":180,"wires":[["857675e6f60221ce"]]},{"id":"4566ca6d2a718384","type":"ui_button","z":"6a7765e6961ddd1b","name":"","group":"49e360b91903ebf4","order":22,"width":0,"height":0,"passthru":false,"label":"select all","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":640,"y":260,"wires":[["d857f6b32b1fec80"]]},{"id":"d68b847bfb62bb25","type":"join","z":"6a7765e6961ddd1b","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1250,"y":240,"wires":[["b4aed460e239a72a","a5225dbbc3952547"]]},{"id":"fc46d00ad86fbfd4","type":"ui_dropdown","z":"6a7765e6961ddd1b","name":"","label":"commands","tooltip":"","place":"Select option","group":"49e360b91903ebf4","order":20,"width":0,"height":0,"passthru":true,"multiple":false,"options":[{"label":"nothing","value":"0","type":"str"},{"label":"restart","value":"2","type":"str"},{"label":"captive","value":"3","type":"str"}],"payload":"","topic":"command","topicType":"str","className":"","x":1070,"y":260,"wires":[["d68b847bfb62bb25"]]},{"id":"ffcb33cb636e87e9","type":"ui_button","z":"6a7765e6961ddd1b","name":"","group":"49e360b91903ebf4","order":21,"width":0,"height":0,"passthru":false,"label":"send","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"send","topicType":"str","x":1050,"y":320,"wires":[["d68b847bfb62bb25"]]},{"id":"b4aed460e239a72a","type":"switch","z":"6a7765e6961ddd1b","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"send","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1370,"y":140,"wires":[["3ebc8a59788d9b10"]]},{"id":"b7d9728a67ec626a","type":"debug","z":"6a7765e6961ddd1b","name":"debug 231","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1730,"y":140,"wires":[]},{"id":"3ebc8a59788d9b10","type":"function","z":"6a7765e6961ddd1b","name":"function 21","func":"const topics =[\n    \"esp32027/cmd/cmd_for_sender\",\n    \"esp32029/cmd/cmd_for_sender\",\n    \"esp32030/cmd/cmd_for_sender\"\n];\nmsg.payload = {\n    command: msg.payload.command, \n    mac: msg.payload.mac\n};\n    \ntopics.forEach(str => {\n    msg.topic = str;\n    node.send(msg);\n})\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1530,"y":140,"wires":[["b7d9728a67ec626a","f7addc5933be25de"]]},{"id":"857675e6f60221ce","type":"ui_dropdown","z":"6a7765e6961ddd1b","name":"","label":"Choose device","tooltip":"","place":"Select option","group":"49e360b91903ebf4","order":19,"width":0,"height":0,"passthru":false,"multiple":true,"options":[{"label":"garage","value":"2a:01:01:01:00:28","type":"str"},{"label":"kitchen","value":"2a:01:01:01:00:49","type":"str"}],"payload":"","topic":"mac","topicType":"str","className":"","x":1060,"y":180,"wires":[["d68b847bfb62bb25"]]},{"id":"f7addc5933be25de","type":"mqtt out","z":"6a7765e6961ddd1b","name":"","topic":"","qos":"2","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"dab2e4d677f055f8","x":1670,"y":80,"wires":[]},{"id":"a5225dbbc3952547","type":"debug","z":"6a7765e6961ddd1b","name":"debug 232","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1470,"y":260,"wires":[]},{"id":"49e360b91903ebf4","type":"ui_group","name":"demo 2","tab":"26280e3e928de854","order":2,"disp":true,"width":"12","collapse":false,"className":""},{"id":"dab2e4d677f055f8","type":"mqtt-broker","name":"HA MQTT","broker":"192.168.1.43","port":"1883","tls":"","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"26280e3e928de854","type":"ui_tab","name":"Demo 14","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

this will not work, because commands come to MQTT as array on mac side:

I anticipated in my code: 1 mqtt message = 1 mac with 1 command
here we have: 1 mqtt message, multiple macs with 1 command

You will need to loop throught the msg.payload.mac strings.
e.g.

const topics =[
    "esp32027/cmd/cmd_for_sender",
    "esp32029/cmd/cmd_for_sender",
    "esp32030/cmd/cmd_for_sender"
];

 msg.payload.mac.forEach(mac => {  
    topics.forEach(str => {
        msg.topic = str;
        msg.payload = {command: msg.payload.command, mac: mac};
        node.send(msg);
    })
 })
return null;

Depending how many messages are going to be sent to the mqtt node, you may want to add a delay node set to rate limit, as not to overwhelm.

1 Like

Guys, you are really awesome!
I ended up with this:

[{"id":"d68b847bfb62bb25","type":"join","z":"6a7765e6961ddd1b","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":870,"y":200,"wires":[["b4aed460e239a72a","a5225dbbc3952547"]]},{"id":"ffcb33cb636e87e9","type":"ui_button","z":"6a7765e6961ddd1b","name":"","group":"49e360b91903ebf4","order":21,"width":0,"height":0,"passthru":false,"label":"send","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"send","topicType":"str","x":650,"y":280,"wires":[["d68b847bfb62bb25"]]},{"id":"b4aed460e239a72a","type":"switch","z":"6a7765e6961ddd1b","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"send","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1010,"y":200,"wires":[["3ebc8a59788d9b10"]]},{"id":"b7d9728a67ec626a","type":"debug","z":"6a7765e6961ddd1b","name":"debug 231","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1570,"y":120,"wires":[]},{"id":"3ebc8a59788d9b10","type":"function","z":"6a7765e6961ddd1b","name":"make mqtt message from mac and command","func":"const topics = [\n    \"esp32027/cmd/cmd_for_sender\",\n    \"esp32029/cmd/cmd_for_sender\",\n    \"esp32030/cmd/cmd_for_sender\"\n];\n\nmsg.payload.mac.forEach(mac => {\n    topics.forEach(str => {\n        msg.topic = str;\n        msg.payload = { command: msg.payload.command, mac: mac };\n        node.send(msg);\n    })\n})\nreturn null;\n\n\n// const topics = [\n//     \"esp32027/cmd/cmd_for_sender\",\n//     \"esp32029/cmd/cmd_for_sender\",\n//     \"esp32030/cmd/cmd_for_sender\"\n// ];\n// msg.payload = {\n//     command: msg.payload.command,\n//     mac: msg.payload.mac\n// };\n\n// topics.forEach(str => {\n//     msg.topic = str;\n//     node.send(msg);\n// })\n// return null;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1280,"y":200,"wires":[["b7d9728a67ec626a","557e35959a16f4ab"]]},{"id":"857675e6f60221ce","type":"ui_dropdown","z":"6a7765e6961ddd1b","name":"","label":"Choose device","tooltip":"","place":"Select option","group":"49e360b91903ebf4","order":19,"width":0,"height":0,"passthru":false,"multiple":true,"options":[{"label":"TRV5 Lidia","value":"2a:01:01:01:00:21","type":"str"},{"label":"TRV6 Kids","value":"2a:01:01:01:00:22","type":"str"},{"label":"TRV2 toilet b.","value":"2a:01:01:01:00:23","type":"str"},{"label":"TRV4 Printers","value":"2a:01:01:01:00:26","type":"str"},{"label":"Garage","value":"2a:01:01:01:00:28","type":"str"},{"label":"Printers","value":"2a:01:01:01:00:31","type":"str"},{"label":"Living room","value":"2a:01:01:01:00:33","type":"str"},{"label":"Tailor","value":"2a:01:01:01:00:35","type":"str"},{"label":"Lidia","value":"2a:01:01:01:00:36","type":"str"},{"label":"TRV1 Bedroom","value":"2a:01:01:01:00:37","type":"str"},{"label":"Toilet b.","value":"2a:01:01:01:00:38","type":"str"},{"label":"Kitchen","value":"2a:01:01:01:00:49","type":"str"},{"label":"TRV3 Toilet up","value":"2a:01:01:01:00:55","type":"str"},{"label":"TRV7 Tailor","value":"2a:01:01:01:00:56","type":"str"},{"label":"Office","value":"2a:01:01:01:01:00","type":"str"},{"label":"Dining","value":"2a:01:01:01:01:01","type":"str"},{"label":"Toilet up","value":"2a:01:01:01:01:02","type":"str"},{"label":"Kids","value":"2a:01:01:01:01:04","type":"str"},{"label":"Garden","value":"2a:01:01:01:01:05","type":"str"},{"label":"Bedroom m.","value":"2a:01:01:01:00:32","type":"str"},{"label":"Garage front m.","value":"2a:01:01:01:00:39","type":"str"}],"payload":"","topic":"mac","topicType":"str","className":"","x":680,"y":120,"wires":[["d68b847bfb62bb25"]]},{"id":"f7addc5933be25de","type":"mqtt out","z":"6a7765e6961ddd1b","name":"","topic":"","qos":"2","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"dab2e4d677f055f8","x":1570,"y":300,"wires":[]},{"id":"a5225dbbc3952547","type":"debug","z":"6a7765e6961ddd1b","name":"debug 232","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1110,"y":320,"wires":[]},{"id":"557e35959a16f4ab","type":"delay","z":"6a7765e6961ddd1b","name":"","pauseType":"rate","timeout":"10","timeoutUnits":"milliseconds","rate":"10","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1580,"y":200,"wires":[["f7addc5933be25de"]]},{"id":"89cbad3574e585e9","type":"ui_dropdown","z":"6a7765e6961ddd1b","name":"","label":"Choose Action","tooltip":"","place":"Select option","group":"49e360b91903ebf4","order":20,"width":0,"height":0,"passthru":true,"multiple":false,"options":[{"label":"OTA","value":"1","type":"str"},{"label":"Restart","value":"2","type":"str"},{"label":"Captive Portal","value":"3","type":"str"},{"label":"Factory Reset","value":"4","type":"str"},{"label":"Motion DISABLED","value":"10","type":"str"},{"label":"Motion ENABLED","value":"11","type":"str"},{"label":"LED OFF","value":"200","type":"str"},{"label":"LED ON","value":"201","type":"str"},{"label":"TEST","value":"0","type":"str"}],"payload":"","topic":"command","topicType":"str","className":"","x":680,"y":200,"wires":[["d68b847bfb62bb25"]]},{"id":"49e360b91903ebf4","type":"ui_group","name":"Send MQTT to GW","tab":"26280e3e928de854","order":2,"disp":true,"width":"12","collapse":true,"className":""},{"id":"dab2e4d677f055f8","type":"mqtt-broker","name":"HA MQTT","broker":"192.168.1.43","port":"1883","tls":"","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"26280e3e928de854","type":"ui_tab","name":"Send MQTT to GW tab","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

It looks nice, and works flawlessly. I implemented delay but also gateway has implemented queueing so all commands ended up on HA and will be sent to sensor devices.
Thank you for your help.

Screenshot 2023-02-14 at 15.59.58




2 Likes

Also instead of your NxN connections. It's much easier to run them through a change node with no rules.

image

Or since v3 a junction -
image

1 Like

thank you @dceejay
I have implemented such block node in case I want to i.e. turn ON/OFF motion sensor (or anything else).
There will be always a need to specify:

  1. mac address of the target
  2. command

but for the bulk changes I used the proposed by @E1cid gui approach

You could always map the mac to a friendly name. I do that with ring events.

that is what I did:

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