Trouble with MQTT automation creating endless loops

qualification: I'm super new to node-red

I have some MQTT/Tasmota devices which I'm attempting to automate for the purpose of stateful mirroring. this particular use-case is using smart switches to replace ALL switches in three and four way lighting applications. I have only one switch wired to the lamp on each circuit, and the other "dummy" switches are only connected to mains power (no LOUT). If one switch is activated, I'm using node-red to send identical activation commands to the other switches in the group, so that all switches are always in the same state as the "master" switch.

When creating this logic for a group of standard on/off switches, I was able to defeat the infinite loop by using a rate-limiting node, and this worked beautifully.

Now I'm creating similar logic for a three way setup with dimmer switches. I have successfully linked the dimmers together, but when I complete the "circuit" I get another endless loop as before. introducing the rate-limiting node breaks my ability to use local dimming as they have sliders, and only the very first adjustment is distributed leaving all subsequent adjustments unmirrored on the child devices. Here is a screenshot of my nodular config:

yes, I have the connection between the lower MQTT node and switch node removed, to keep the switches from spazzing.

being relatively wet behind the ears, I'm hoping somebody can explain to me whether I'm going about this all wrong, or how to combat this endless logic loop. it's very important to me to be able to adjust the dimming locally on switch A and have the LED display on switches B (and C) mirror.

Thanks in advance!

Are the values oscillating in the loop or repeatedly sending the same values? If the same values then put an RBE node in the loop and it will stop.

thank you for your answer. the commands seem to oscillate between the previous dimmer value (of both switches) and then the new locally specified value:

1/13/2021, 1:10:59 PMnode: 3971d638.516142
stat/lighting/hallwaydimmer/RESULT : msg.payload : string[26]
"{"POWER":"ON","Dimmer":28}"
1/13/2021, 1:10:59 PMnode: 3971d638.516142
stat/lighting/stairwell/RESULT : msg.payload : string[26]
"{"POWER":"ON","Dimmer":28}"
1/13/2021, 1:10:59 PMnode: 3971d638.516142
stat/lighting/hallwaydimmer/RESULT : msg.payload : string[26]
"{"POWER":"ON","Dimmer":28}"
1/13/2021, 1:10:59 PMnode: 3971d638.516142
stat/lighting/stairwell/RESULT : msg.payload : string[25]
"{"POWER":"ON","Dimmer":1}"
1/13/2021, 1:10:59 PMnode: 3971d638.516142
stat/lighting/stairwell/RESULT : msg.payload : string[25]
"{"POWER":"ON","Dimmer":1}"
1/13/2021, 1:10:59 PMnode: 3971d638.516142
stat/lighting/hallwaydimmer/RESULT : msg.payload : string[26]
"{"POWER":"ON","Dimmer":28}"
1/13/2021, 1:10:59 PMnode: 3971d638.516142
stat/lighting/stairwell/RESULT : msg.payload : string[25]
"{"POWER":"ON","Dimmer":1}"
1/13/2021, 1:10:59 PMnode: 3971d638.516142
stat/lighting/hallwaydimmer/RESULT : msg.payload : string[26]
"{"POWER":"ON","Dimmer":28}"
1/13/2021, 1:10:59 PMnode: 3971d638.516142
stat/lighting/stairwell/RESULT : msg.payload : string[25]
"{"POWER":"ON","Dimmer":1}"

additionally, it appears that the touch interface on these switches is... imprecise. a single, intentional tap on the slider seems to trigger anywhere from 2-4 (most commonly 4) stat outputs of the same value:

1/13/2021, 1:17:24 PMnode: 3971d638.516142
stat/lighting/hallwaydimmer/RESULT : msg.payload : string[26]
"{"POWER":"ON","Dimmer":96}"
1/13/2021, 1:17:24 PMnode: 3971d638.516142
stat/lighting/stairwell/RESULT : msg.payload : string[26]
"{"POWER":"ON","Dimmer":96}"
1/13/2021, 1:17:24 PMnode: 3971d638.516142
stat/lighting/stairwell/RESULT : msg.payload : string[26]
"{"POWER":"ON","Dimmer":96}"
1/13/2021, 1:17:24 PMnode: 3971d638.516142
stat/lighting/stairwell/RESULT : msg.payload : string[26]
"{"POWER":"ON","Dimmer":96}"

that's if I'm being very cautious and intentional with a brief/precise tap. if I do a sloppy tap much like anybody in real life/practice would do, I will receive six or more MQTT outputs, oftentimes within a tolerance of 2-4 dimmer range increments:

1/13/2021, 1:20:18 PM[node: 3971d638.516142](http://192.168.4.36:1880/#)stat/lighting/hallwaydimmer/RESULT : msg.payload : string[26]

"{"POWER":"ON","Dimmer":50}"

1/13/2021, 1:20:18 PM[node: 3971d638.516142](http://192.168.4.36:1880/#)stat/lighting/hallwaydimmer/RESULT : msg.payload : string[26]

"{"POWER":"ON","Dimmer":48}"

1/13/2021, 1:20:18 PM[node: 3971d638.516142](http://192.168.4.36:1880/#)stat/lighting/stairwell/RESULT : msg.payload : string[14]

"{"POWER":"ON"}"

1/13/2021, 1:20:18 PM[node: 3971d638.516142](http://192.168.4.36:1880/#)stat/lighting/stairwell/RESULT : msg.payload : string[26]

"{"POWER":"ON","Dimmer":50}"

1/13/2021, 1:20:18 PM[node: 3971d638.516142](http://192.168.4.36:1880/#)stat/lighting/stairwell/RESULT : msg.payload : string[26]

"{"POWER":"ON","Dimmer":50}"

1/13/2021, 1:20:18 PM[node: 3971d638.516142](http://192.168.4.36:1880/#)stat/lighting/stairwell/RESULT : msg.payload : string[26]

"{"POWER":"ON","Dimmer":48}"

1/13/2021, 1:20:18 PM[node: 3971d638.516142](http://192.168.4.36:1880/#)stat/lighting/stairwell/RESULT : msg.payload : string[26]

"{"POWER":"ON","Dimmer":48}"

1/13/2021, 1:20:18 PM[node: 3971d638.516142](http://192.168.4.36:1880/#)stat/lighting/hallwaydimmer/RESULT : msg.payload : string[14]

It is obvious looking at your flow that you will have a loop. Cross coupling like that is doomed to failure I think.
I don't fully understand your system. When you talk about local dimmers do you mean physical controls or sliders on the dashboard? If on the dashboard then show us what you have done there.

hah, I wish it were that obvious to me. I'm frequently looking through the wrong end of the telescope.

these are the switches in question:

they contain touch sensitive sliders and LED arrays to indicate the dimmer level. when I say "local dimming" I'm referring to physical control.

I am currently not doing anything with the dashboard. if I were to scrap the work I've done thus far, I'd describe my goals as this:

interacting with switch A will mirror its state on B, C
interacting with switch B will mirror its state on A, C
interacting with switch C will mirror its state on A, B

effectively slaving all of these switches together, however only one will directly control line voltage to the light fixtures

I will add, that with the lower MQTT node disconnected, switch A duplicates its state on B perfectly and in realtime (acceptable latency)

OK, understood. It is late now, I think I can see how to do it, will have a look in the morning.

In the meantime could you post how you have configured the Switch and Change nodes in the image you posted.

welp... with the grace and elegance of a gorilla with all thumbs, I've come up with a seemingly working solution!

I've introduced more rate limiter nodes, this time telling it to DROP intermediate messages. This cleans up all the spam, breaks the loop, and gives me no greater perceivable latency between the operated switch and the slaved switches.

per your request, here is the switch config:
image
I'm very crudely using a switch as a filter, I'm sure there's a far better way

here is the change config:
image

FWIW, the MQTT outputs a string, and the json nodes convert msg.payload strings to objects, which are then pared and converted by the change node and output via MQTT again.

while this is definitely some sort of solution, I would love to be corrected on how to properly implement this design. if I repeatedly play with the dimmers, I can occasionally get them out of sync... they sync right back up on the next interact. sometimes on a long slide, they can end slightly apart as well... level 3 on one and 4 on the other.

Interesting setup,,,I think it could be a useful installation, nice to have all switches around the house synchronized like that!

Also looking at your flow. I see there are a lot of MQTT messages generated when moving a slider. I assume you are actually only interested in the very last message? That is when the slider has reached the final position

So a flow like below might give a good result. Assume you have 3 switches, S1, S2, S3 you would like to have in sync. All messages except the last will be discarded by the trigger node. Once the S1 originating incoming MQTT messages has ended, the trigger node waits for a second and then sends the latest received message that will be used to set the other switches (S2, S3)

This schema has to be repeated in total 3 times to cover operation from any of the 3 switches. Like:

S1 -> S2, S3
S2 -> S1, S3
S3 -> S1, S2

I configured the trigger node to wait for a second. To get a faster reaction to update switch states you can decrease the time, you have to test what works ok. I have not tested anything since I do not have any switches like this

EDIT: And still, maybe need something more to avoid crazy loops when setting up schemas for all possible configurations/groups of switches to be kept in sync

Is this a correct analysis of the problem?
You have three dimmers in the real world.
Each one of those controls its local light and when the brightness is changed the new value is sent to node-red via MQTT topics stat/lighting/<location>/RESULT.
When any one of those changes then in node-red to you want to send the new brightness to all the other lights using the topics cmd/lighting/<location>/dimmer.

If so then I think you have been overthinking the problem. My suggestion would be to something like this

That will pick up each of the values and by feeding each through an RBE node there will only be a message from each when it changes (this is to stop one mode of looping). The trigger node is configured like this

That absorbs multiple messages close together in order to cope with multiple dimmers being changed at the same time (and also the startup situation when you may get input from all of them at the same time). The output of the the Trigger node is then a value that you want all three dimmers set to, so that value can be passed on to all the dimmers. One of them will already be on that value, but it doesn't matter, the RBE on the way in will prevent that from coming through again.

I don't know what you need to put in the function in the middle, as you have not shown us what is in the Switch/JSON/Change sequence you have in the middle. I find that a very odd combination, so please export those three nodes as I feel sure it is not ideal.
As I am not able to test this it is difficult to be certain there will not be another mode where a loop could occur, it is notoriously difficult to design logic like this and think of all the possible situations.

@krambriw and @Colin, thank you both very much for your thoughtful replies! as this is my very first venture into node-red, I have only built what I could determine on my own, which is admittedly some Frankenstein combination of nodes to create some semblance of result.

krambriw, while yes it may be workable to only utilize the final message, it does potentially confound operation skipping all intermediate messaging because only one switch actually controls the light fixture. switches 2 and 3 have no line voltage only MQTT operation. this being the case, you wouldn't be able to adjust the dimming in real time to find the desired setting, you would have to pick a setting, then adjust up or down to taste. to reinsert my previous image:


if one was to adjust the slider on switch C, it wouldn't publish the result to switch A until the slider interaction was complete, meaning the actual light fixture wouldn't be dimmed until you removed your finger from the switch, meaning you wouldn't know the result of your dimming command immediately and would likely have to make another blind attempt at dimming to an acceptable value. I have to take usability (wife approval factor) into consideration.

second to that point, perhaps I will upload a video via YouTube, but it is SO cool watching two other switches mimic your dimming action in real time. I would be sad if I was unable to retain that functionality, as it's very futuristic and sleek.

I wish that I could use a rate limiter node at intervals >1sec. It seems odd that 1msg/sec is the shortest interval allowable. perhaps I could further Frankenstein a few side chained rate limiters with 250ms delays... haha joke.

@Colin I had posted some snippets above as well as some text explanation, but here is the mechanic of my flow:

MQTT node subscribed to state of other switch

rate limiting node passes 1msg/sec, discarding intermediate msg

switch node configured to pass through messages containing "Dimmer" commands:

JSON node converts string payload into objects:

the change node deletes the message topic from originating switch
the change node deletes the POWER object from payload (handled by different flow for power state sync)
the change node takes the value of the Dimmer object as the entirety of the payload

then the MQTT out node specifies the cmnd/lighting/+/dimmer

here is a brief video of the desired operation between two switches

You would be better to set the MQTT node to output a javascript object and use that rather than doing string manipulation.
Can you export the relevant nodes and paste here using the </> button when pasting it in.
Have you considered my suggested technique?

that was my original intent, but due to my extreme lack of knowledge here, this was the first working iteration I discovered. now to clean it up!

I am super excited to experiment with both of your suggestions, however I'm just settling in to work and will have to perform further testing later in the day

is this what you're asking for:

switch node

[{"id":"b11a49d0.103fb8","type":"switch","z":"f7c3ff8f.e6ce1","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"Dimmer","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":610,"y":280,"wires":[["3b25c56a.80ad02"]]}]

json node:

[{"id":"3b25c56a.80ad02","type":"json","z":"f7c3ff8f.e6ce1","name":"","property":"payload","action":"","pretty":false,"x":730,"y":280,"wires":[["36f573a.7e2e70c"]]}]

change node:

[{"id":"36f573a.7e2e70c","type":"change","z":"f7c3ff8f.e6ce1","name":"","rules":[{"t":"delete","p":"topic","pt":"msg"},{"t":"delete","p":"payload.POWER","pt":"msg"},{"t":"set","p":"payload","pt":"msg","to":"payload.Dimmer","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":280,"wires":[["f2066334.3a0058"]]}]

just to point out for certain, no each switch does not control its own local light. only switch A controls the light, switches B and C are simply stateful remote controls.

also, I am wondering.... perhaps there is utility in inserting a new payload object into the message, which can be used by receiving nodes to determine whether or not to "honor" the message? for instance, switch A embeds a payload SOURCE:A and for the next few seconds, no additional messages without payload SOURCE:A will be executed? each node could have logic to scrape the payload.source after using it to determine whether or not to honor the message.

this might help with the loop while still allowing relatively real-time operation? I'm just brainstorming

@Colin

I have tried my best to duplicate your suggested flow:


I have experimented with the trigger every 100-500ms with no appreciable change

this works very well with a caveat:

if I perform a long swiping dimmer action, there is no real-time update (bummer) but it always carries over the final setting to the adjacent switch. however, if I simply tap the slider to specify a value, it's about 3/5 that actually translate the tapped setting to the adjacent switch.

here's a video which can better explain the behavior:

EDIT: it works far more reliably w/o the RBE nodes. probably 7/8 success rate

Please export the flow and paste it here. Otherwise we are just guessing about how you have configured the nodes.

[{"id":"f7c3ff8f.e6ce1","type":"tab","label":"Link Dimmers","disabled":false,"info":""},{"id":"c730d800.4b699","type":"mqtt in","z":"f7c3ff8f.e6ce1","name":"","topic":"stat/lighting/hallwaydimmer/RESULT","qos":"0","datatype":"utf8","broker":"577d2db3.1e1f7c","x":220,"y":80,"wires":[["e7c3db9f.89f14"]]},{"id":"f2066334.3a0058","type":"mqtt out","z":"f7c3ff8f.e6ce1","name":"","topic":"cmnd/lighting/stairwell/dimmer","qos":"0","retain":"","broker":"577d2db3.1e1f7c","x":1110,"y":280,"wires":[]},{"id":"b11a49d0.103fb8","type":"switch","z":"f7c3ff8f.e6ce1","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"Dimmer","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":610,"y":280,"wires":[["3b25c56a.80ad02"]]},{"id":"36f573a.7e2e70c","type":"change","z":"f7c3ff8f.e6ce1","name":"","rules":[{"t":"delete","p":"topic","pt":"msg"},{"t":"delete","p":"payload.POWER","pt":"msg"},{"t":"set","p":"payload","pt":"msg","to":"payload.Dimmer","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":280,"wires":[["f2066334.3a0058"]]},{"id":"3b25c56a.80ad02","type":"json","z":"f7c3ff8f.e6ce1","name":"","property":"payload","action":"","pretty":false,"x":730,"y":280,"wires":[["36f573a.7e2e70c"]]},{"id":"617463e5.640b0c","type":"comment","z":"f7c3ff8f.e6ce1","name":"copy dimmer from hallway to stairwell","info":"","x":170,"y":40,"wires":[]},{"id":"58cb21d0.ed888","type":"comment","z":"f7c3ff8f.e6ce1","name":"copy dimmer from stairwell to hallway","info":"","x":170,"y":340,"wires":[]},{"id":"fcd12917.cb31f","type":"mqtt in","z":"f7c3ff8f.e6ce1","name":"","topic":"stat/lighting/stairwell/RESULT","qos":"0","datatype":"utf8","broker":"577d2db3.1e1f7c","x":180,"y":380,"wires":[["772262c6.efa7b4","e7c3db9f.89f14"]]},{"id":"88f03bc9.d91a18","type":"mqtt out","z":"f7c3ff8f.e6ce1","name":"","topic":"cmnd/lighting/hallwaydimmer/dimmer","qos":"0","retain":"","broker":"577d2db3.1e1f7c","x":1130,"y":620,"wires":[]},{"id":"e39a7f5.c3b41","type":"switch","z":"f7c3ff8f.e6ce1","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"Dimmer","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":610,"y":620,"wires":[["e9fc4809.41398"]]},{"id":"bf273be2.a3d2d8","type":"change","z":"f7c3ff8f.e6ce1","name":"","rules":[{"t":"delete","p":"topic","pt":"msg"},{"t":"delete","p":"payload.POWER","pt":"msg"},{"t":"set","p":"payload","pt":"msg","to":"payload.Dimmer","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":620,"wires":[["88f03bc9.d91a18"]]},{"id":"e9fc4809.41398","type":"json","z":"f7c3ff8f.e6ce1","name":"","property":"payload","action":"","pretty":false,"x":730,"y":620,"wires":[["bf273be2.a3d2d8"]]},{"id":"772262c6.efa7b4","type":"debug","z":"f7c3ff8f.e6ce1","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":630,"y":740,"wires":[]},{"id":"a2c99ff4.664c7","type":"rbe","z":"f7c3ff8f.e6ce1","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":430,"y":140,"wires":[[]]},{"id":"49775524.34ab64","type":"rbe","z":"f7c3ff8f.e6ce1","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":410,"y":380,"wires":[[]]},{"id":"e7c3db9f.89f14","type":"trigger","z":"f7c3ff8f.e6ce1","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"100","extend":true,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":440,"y":300,"wires":[["772262c6.efa7b4","b11a49d0.103fb8","e39a7f5.c3b41"]]},{"id":"577d2db3.1e1f7c","type":"mqtt-broker","name":"MQTT","broker":"192.168.4.36","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","willTopic":"","willQos":"0","willRetain":"false","willPayload":""}]

Try something like this. Note that I have changed the MQTT node's configs, the input nodes to output javascript objects not strings, and the output node by clearing the topic in the config so it can be passed in the message.
If it doesn't work connect debug nodes to the input MQTT and output MQTT, give them names so we can see what is what and paste the result here.
If nothing is coming through at all then use debug nodes to work out where it is failing.
I know it won't fix the issue of not tracking whilst scrolling the dimmer, but let's worry about that after we get it basically working.

[{"id":"c730d800.4b699","type":"mqtt in","z":"f7c3ff8f.e6ce1","name":"","topic":"stat/lighting/hallwaydimmer/RESULT","qos":"0","datatype":"json","broker":"577d2db3.1e1f7c","x":220,"y":80,"wires":[["ff144a2.116b838"]]},{"id":"f2066334.3a0058","type":"mqtt out","z":"f7c3ff8f.e6ce1","name":"","topic":"","qos":"0","retain":"","broker":"577d2db3.1e1f7c","x":810,"y":260,"wires":[]},{"id":"617463e5.640b0c","type":"comment","z":"f7c3ff8f.e6ce1","name":"copy dimmer from hallway to everywhere","info":"","x":180,"y":40,"wires":[]},{"id":"58cb21d0.ed888","type":"comment","z":"f7c3ff8f.e6ce1","name":"copy dimmer from stairwell to everywhere","info":"","x":180,"y":340,"wires":[]},{"id":"fcd12917.cb31f","type":"mqtt in","z":"f7c3ff8f.e6ce1","name":"","topic":"stat/lighting/stairwell/RESULT","qos":"0","datatype":"json","broker":"577d2db3.1e1f7c","x":180,"y":380,"wires":[["e238691e.d5f768"]]},{"id":"a2c99ff4.664c7","type":"rbe","z":"f7c3ff8f.e6ce1","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":770,"y":80,"wires":[["e7c3db9f.89f14"]]},{"id":"e7c3db9f.89f14","type":"trigger","z":"f7c3ff8f.e6ce1","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"100","extend":true,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":600,"y":220,"wires":[["c52c1ae0.0eb6b8"]]},{"id":"ff144a2.116b838","type":"switch","z":"f7c3ff8f.e6ce1","name":"Dimmer?","property":"payload","propertyType":"msg","rules":[{"t":"hask","v":"Dimmer","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":460,"y":80,"wires":[["9105ab1e.4d9ca"]]},{"id":"867bdd89.8e7738","type":"debug","z":"f7c3ff8f.e6ce1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":910,"y":160,"wires":[]},{"id":"9105ab1e.4d9ca","type":"change","z":"f7c3ff8f.e6ce1","name":"Move to payload","rules":[{"t":"move","p":"payload.Dimmer","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":620,"y":80,"wires":[["a2c99ff4.664c7"]]},{"id":"44f8fcdb.35f3cc","type":"rbe","z":"f7c3ff8f.e6ce1","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":730,"y":380,"wires":[["e7c3db9f.89f14"]]},{"id":"e238691e.d5f768","type":"switch","z":"f7c3ff8f.e6ce1","name":"Dimmer?","property":"payload","propertyType":"msg","rules":[{"t":"hask","v":"Dimmer","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":420,"y":380,"wires":[["eb8f402d.0808f"]]},{"id":"eb8f402d.0808f","type":"change","z":"f7c3ff8f.e6ce1","name":"Move to payload","rules":[{"t":"move","p":"payload.Dimmer","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":580,"y":380,"wires":[["44f8fcdb.35f3cc"]]},{"id":"c52c1ae0.0eb6b8","type":"function","z":"f7c3ff8f.e6ce1","name":"Send to all locations","func":"const locations = [\"stairwell\", \"hallwaydimmer\"]\nfor (let i = 0; i < locations.length; i++) {\n    const topic = `cmnd/lighting/${locations[i]}/dimmer`\n    node.send({payload: msg.payload, topic: topic})\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":800,"y":220,"wires":[["f2066334.3a0058","867bdd89.8e7738"]]},{"id":"577d2db3.1e1f7c","type":"mqtt-broker","name":"MQTT","broker":"192.168.4.36","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","willTopic":"","willQos":"0","willRetain":"false","willPayload":""}]

Thank you for your time and attention.

I will test this tonight and report back.

Cheers

UPDATE

@Colin, thank you very much for that. it does have a 100% success rate of transferring result values from one switch to the other, however I notice that during long exaggerated slide/adjustments, the LEDS will begin to flash, alternating between the starting value and the current value.

I also notice that when settling upon a value, the debug shows a bit of bounceback:

cmnd/lighting/stairwell/dimmer : msg.payload : number
76
1/15/2021, 9:18:03 PMnode: 15eddd31.05adeb
cmnd/lighting/hallwaydimmer/dimmer : msg.payload : number
76
1/15/2021, 9:18:04 PMnode: 15eddd31.05adeb
cmnd/lighting/stairwell/dimmer : msg.payload : number
76
1/15/2021, 9:18:04 PMnode: 15eddd31.05adeb
cmnd/lighting/hallwaydimmer/dimmer : msg.payload : number
76

still, without a doubt the best go yet, I really appreciate this two-fold: I'm closer to having the desired solution, and I can learn/infer from the mechanics of your flow.

not to sound ungrateful, but can you fathom a way to allow the LED sliders to update in unison, instead of in sequence?

cheers!!!