Subflows, outputs, environment variables - today's question. (Demarcation lines?)

This question has popped up.


A message comes in. It can be A or B.
Depending if it is A or B determines the output.
The output is (for now) msgA or msgB. Just to keep things clear for association.

Big picture:

The message arrives and the correct message is then sent.


As is, the two output messages are defined.
So it is pretty simple how things work.

Taking it to a block of nodes in the flow.
You can change the msgA and msgB by flow.context or global.context.
Again: Fair enough.

This allows you to change the values. (Good)

The spanner:

Subflows are still being explored and so I am going to ask questions.
Some good. Some silly.
And I think I may have just realised the answer, but want to check.

So ok, in the building of a subflow, I can define environment variables which are used in the subflow to define things.
Like - for instance - msgA and msgB.
But only to a point.

Subflows are great as they allow you to replace duplicate code/nodes (more so) with a single node.

I have a few occurrences of the subflow doing the same thing, but not quite.

Where is the line drawn to what is IN the subflow and what is OUTSIDE?
(and how many outputs does it need?)

The subflows spit out their msgA and msgB messages (one output) to do their things.

So, ideally that should be enough. The downstream code parses the message and acts accordingly.

I have some RGB LEDs. (Yeah, don't go there. I've had enough fun getting them working)

The structure is this:
It is text at this stage.
rgb - the command
(led) - a number to indicate which LED.
r,g,b - values from 0 to 255.

I have LED65 assigned a job. (edited: I think you can see a problem)
If something happens, it starts flashing. This is done with a subflow and where the problem starts.

Below is an example of the subflow.

A message is received that activates the subflow and it starts alternating the output message at a given speed and at the output of it are the two alternating messages.

In this example:

Which is fine. For now.

Then one day for what ever reason I change it and want to use LED
from 5 to 6. (See the problem to which I hinted above?)

So I change the flow.context from 5 and change it to 6.
That isn't going to do me much good as the output messages are fixed.


To get around this I could keep the output messages simple and then have a switch node on the output that then goes into two change nodes that then build the really needed messages.

Again: Fair enough.

Then why not have TWO outputs from the subflow - given the output messages are FIXED.
Then all I need to do is add only 2 changed nodes.
There is little extra overhead putting 2 outputs to the subflow and .....

The other question:

So what magic would be needed so when I define the output messages, I can include the flow.context.
I'm guessing it will/could be something to do with the J: option. But that is still WAY beyond my skill set.

I'm more asking about where the demarcation lines are to what to do.
Do I have two outputs?
Do I include the variable (to set the LED) with the inbound message?

This is (probably) page 2 stuff for most of you.

I'm stuck on page 1. :wink:

I'm spit balling the pros and cons of what to do.

It is just I am (again) TRYING to write better code and I have a lot of machines to go over and bring their code up to speed.
While doing it these questions are presenting themselves to me and I just have no idea of their relationship with things in the bigger picture.

Sure, I CAN define how they interact and what the rules are. I just would like to get an external perspective to make sure I'm not missing any elephants.
(I'm good at doing that)

Sorry it was so long and I hope it makes sense. I am trying (argh!) to explain it as best I can.
But not really understanding it isn't helping me do a good job on that front either.

[{"id":"ca5e1e7f2227fa14","type":"subflow","name":"Blinker","info":"2021 12 7  \nA subflow to send pulsing messages at a given interval to make something *flash*.\n\nConfigurable by setting `environment` variables in the node's settings.\n\n\n# **Output toggle node to send alternating messages at a specified frequency.**\n# \n\n## 3 things need to be set to configure this subflow\n1 - `delay`:  milliseconds between toggles (override with msg.delay)\n\n2 - `msg1`:   text message for state 1  \n\n3 - `msg2`:   text message for state 2 \n\n`msg.topic` is output and alternates between `msg1` and `msg2` to indicate which message is being sent.\n\n## Optional:\n`offmsg` - sent when it is reset.\n\nMay be handy to make sure things are *off*.\n\n## Input message\nTo start send `msg` (anything)\n\nTo stop, send `msg.reset`","category":"","in":[{"x":50,"y":80,"wires":[{"id":"3a95f6976aee6fd0"}]}],"out":[{"x":920,"y":70,"wires":[{"id":"f3b2b2634e2662cd","port":1},{"id":"a655faf0bc379507","port":0}]}],"env":[{"name":"delay","type":"num","value":""},{"name":"msg1","type":"str","value":""},{"name":"msg2","type":"str","value":""},{"name":"offmsg","type":"str","value":""}],"meta":{"module":"Toggler","version":"0.1.1","desc":"Toggles output between `msg1` and `msg2` set in node config"},"color":"#A6BBCF","icon":"node-red-contrib-bool-gate/switch.png","status":{"x":920,"y":170,"wires":[{"id":"502c279ae9a6f385","port":0}]}},{"id":"c57d4f9cf1932087","type":"trigger","z":"ca5e1e7f2227fa14","name":"","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"-2","extend":false,"overrideDelay":true,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":370,"y":400,"wires":[["dc59ee15636e05ce"]]},{"id":"dc59ee15636e05ce","type":"function","z":"ca5e1e7f2227fa14","name":"toggle","func":"msg1 = {};\nlet c = context.get(\"counter\") ||0;\nif (c == 0)\n{\n    //  0\n    //msg.payload = \"rgb,1,0,18,12\";\n    msg.payload = env.get(\"msg1\");\n    msg.topic = \"A\";\n} else\nif (c == 1)\n{\n    //  1\n    //msg.payload = \"rgb,1,0,0,0\";\n    msg.payload = env.get(\"msg2\");\n    msg.topic = \"B\";\n}\nmsg1.payload = c;\nc = (c + 1) % 2;\ncontext.set(\"counter\",c);\nreturn [msg,msg1];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":400,"wires":[[],["5f212ac993db393c"]]},{"id":"cb927a5096e82c6b","type":"change","z":"ca5e1e7f2227fa14","name":"","rules":[{"t":"set","p":"delay","pt":"msg","to":"delay","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":180,"y":400,"wires":[["c57d4f9cf1932087"]]},{"id":"dc53c043d49299b6","type":"switch","z":"ca5e1e7f2227fa14","name":"reset?","property":"reset","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","repair":false,"outputs":1,"x":150,"y":440,"wires":[["7cb7dddb4ea4f5d5","06acc957025d15a9"]]},{"id":"7cb7dddb4ea4f5d5","type":"switch","z":"ca5e1e7f2227fa14","name":"off msg?","property":"offmsg","propertyType":"env","rules":[{"t":"nempty"}],"checkall":"true","repair":false,"outputs":1,"x":350,"y":440,"wires":[["f46b5eab2fed46bc"]]},{"id":"f46b5eab2fed46bc","type":"change","z":"ca5e1e7f2227fa14","name":"set off message","rules":[{"t":"set","p":"payload","pt":"msg","to":"offmsg","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":440,"wires":[[]]},{"id":"5f212ac993db393c","type":"function","z":"ca5e1e7f2227fa14","name":"","func":"let c = msg.payload;\nif (c == 0)\n{\n    msg.payload = ({text: \"A\"});\n} else if (c == 1)\n{\n    msg.payload = ({text: \"B\"});\n} else\n    msg.payload = ({text:\" \"});\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":500,"wires":[[]]},{"id":"06acc957025d15a9","type":"change","z":"ca5e1e7f2227fa14","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"reset","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":315,"y":500,"wires":[["5f212ac993db393c"]],"l":false},{"id":"c53ebcc9e62a7552","type":"trigger","z":"ca5e1e7f2227fa14","name":"resend every x","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"-1","extend":false,"overrideDelay":true,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":430,"y":80,"wires":[["f3b2b2634e2662cd"]]},{"id":"f3b2b2634e2662cd","type":"function","z":"ca5e1e7f2227fa14","name":"toggle","func":"delete msg.delay;\nconst msg1 = {};\nlet c = context.get(\"counter\") ||0;\n\nif (c == 0) {\n    //  0\n    msg.payload = env.get(\"msg1\");\n    msg.topic = \"msg1\";\n} else if (c == 1) {\n    //  1\n    msg.payload = env.get(\"msg2\");\n    msg.topic = \"msg2\";\n};\n\nmsg1.payload = c;\nc = (c + 1) % 2;\ncontext.set(\"counter\",c);\nreturn [msg1,msg];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":80,"wires":[["502c279ae9a6f385"],[]]},{"id":"c183245c1a6a7fac","type":"switch","z":"ca5e1e7f2227fa14","name":"is reset?","property":"reset","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","repair":false,"outputs":1,"x":410,"y":170,"wires":[["a9be61803cd67654","6e3a0cdb44f6a994"]]},{"id":"a9be61803cd67654","type":"switch","z":"ca5e1e7f2227fa14","name":"off msg?","property":"offmsg","propertyType":"env","rules":[{"t":"nempty"}],"checkall":"true","repair":false,"outputs":1,"x":610,"y":130,"wires":[["a655faf0bc379507"]]},{"id":"a655faf0bc379507","type":"change","z":"ca5e1e7f2227fa14","name":"set off message","rules":[{"t":"set","p":"payload","pt":"msg","to":"offmsg","tot":"env"},{"t":"delete","p":"reset","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":130,"wires":[[]]},{"id":"502c279ae9a6f385","type":"function","z":"ca5e1e7f2227fa14","name":"status","func":"const c = msg.payload;\n\nif (c == 0) {\n    msg.payload = ({text: \"msg1\"});\n} else if (c == 1) {\n    msg.payload = ({text: \"msg2\"});\n} else {\n    msg.payload = ({text:\"\"});\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":760,"y":170,"wires":[[]]},{"id":"6e3a0cdb44f6a994","type":"change","z":"ca5e1e7f2227fa14","name":"reset","rules":[{"t":"set","p":"payload","pt":"msg","to":"2","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":170,"wires":[["502c279ae9a6f385"]]},{"id":"3a95f6976aee6fd0","type":"function","z":"ca5e1e7f2227fa14","name":"set msg.delay","func":"msg.delay = msg.delay || env.get(\"delay\") || 1000;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":230,"y":80,"wires":[["c53ebcc9e62a7552","c183245c1a6a7fac"]]},{"id":"fe628d897122513b","type":"subflow:ca5e1e7f2227fa14","z":"f4651491.221e58","name":"New IP address","env":[{"name":"delay","value":"1300","type":"num"},{"name":"msg1","value":"rgb,5,180,0,0","type":"str"},{"name":"msg2","value":"rgb,5,0,0,0","type":"str"},{"name":"offmsg","value":"rgb,5,0,0,0","type":"str"}],"x":900,"y":2740,"wires":[["8fad71e3fdab2d59","2cedd9617f803817"]]}]

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