Queueing messages - need help - can this flow be optimised?

On a side project to control a lightbulb - yeah, bit pitiful - with adjustments.

If the bulb is on, any adjustments are done, and you can see the effect.

Alas there is a problem that if the bulb is OFF and you change the brightness (or other things) it bulb turns ON.

That isn't too annoying, but I don't like that. To me the adjustments should only work if the bulb is ON.

This is a bit of a flow I knocked together to accommodate this. Yes, there is an underlying problem but for now..... This is what I have:

(Foreign node required: node-red-contrib-queue-gate)

[{"id":"b941f136.0105f","type":"q-gate","z":"26262ba1.62dcbc","name":"","controlTopic":"control","defaultState":"open","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","queueCmd":"queue","defaultCmd":"default","triggerCmd":"trigger","flushCmd":"flush","resetCmd":"reset","maxQueueLength":"100","keepNewest":false,"qToggle":false,"persist":false,"x":3113,"y":3900,"wires":[["273e9670.7baf5a"]]},{"id":"2ac8ea66.531cde","type":"inject","z":"26262ba1.62dcbc","name":"Normal data","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2850,"y":3900,"wires":[["b941f136.0105f","1200f19c.e4f676"]]},{"id":"273e9670.7baf5a","type":"debug","z":"26262ba1.62dcbc","name":"OUTPUT","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":3270,"y":3900,"wires":[]},{"id":"2e87680d.2873b","type":"change","z":"26262ba1.62dcbc","name":"\"Stop\"","rules":[{"t":"set","p":"payload","pt":"msg","to":"queue","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2830,"y":3800,"wires":[["b941f136.0105f"]]},{"id":"f807665.0451798","type":"change","z":"26262ba1.62dcbc","name":"\"Go\"","rules":[{"t":"set","p":"payload","pt":"msg","to":"flush","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2830,"y":3840,"wires":[["b941f136.0105f","b064f285.5a01e"]]},{"id":"19b80cc9.762a03","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"On","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2830,"y":3680,"wires":[["273e9670.7baf5a","aa4418b6.73fed","b37a5fdd.fc86f"]]},{"id":"c46a811d.743cb8","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"Off","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2830,"y":3640,"wires":[["273e9670.7baf5a","8e87f280.16ff58","b37a5fdd.fc86f","f1ce66f9.5cf67"]]},{"id":"1200f19c.e4f676","type":"counter","z":"26262ba1.62dcbc","name":"","init":"0","step":"1","lower":null,"upper":null,"mode":"increment","outputs":2,"x":3120,"y":3860,"wires":[["b37a5fdd.fc86f"],[]]},{"id":"f1ce66f9.5cf67","type":"trigger","z":"26262ba1.62dcbc","op1":"1","op2":"0","op1type":"val","op2type":"val","duration":"250","extend":"false","units":"ms","reset":"","bytopic":"all","name":"","x":3130,"y":3640,"wires":[["2e87680d.2873b"]]},{"id":"8e87f280.16ff58","type":"change","z":"26262ba1.62dcbc","name":"Stop","rules":[{"t":"set","p":"payload","pt":"msg","to":"close","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2830,"y":3720,"wires":[["b941f136.0105f"]]},{"id":"aa4418b6.73fed","type":"change","z":"26262ba1.62dcbc","name":"Go","rules":[{"t":"set","p":"payload","pt":"msg","to":"open","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2830,"y":3760,"wires":[["b941f136.0105f"]]},{"id":"b37a5fdd.fc86f","type":"function","z":"26262ba1.62dcbc","name":"","func":"var counter = context.get(\"counter\") || 0;\nif (msg.payload === 0)\n{\n    context.set(\"counter\",0);\n    node.status({fill: \"green\",text:\"Wiped\"});\n}\nelse\nif (msg.payload == \"On\")\n{\n    //\n    context.set(\"SKIP\",1);\n    node.status({fill: \"blue\",text:\"Open\"});\n    msg.payload = \"flush\";\n    return msg;\n}\nelse\nif (msg.payload == \"Off\")\n{\n    node.status({fill: \"red\",text:\"Queue\"});\n    context.set(\"SKIP\",0);\n    return;\n}\n{\n    if (context.get(\"SKIP\") == 0)\n    {\n        node.status({text:counter + 1});\n        context.set(\"counter\",counter + 1)\n    }\n}\n//return msg;","outputs":1,"noerr":0,"x":3260,"y":3810,"wires":[["a2c673cb.bdbca"]]},{"id":"a2c673cb.bdbca","type":"link out","z":"26262ba1.62dcbc","name":"","links":["44933f09.b93388"],"x":3375,"y":3810,"wires":[]},{"id":"44933f09.b93388","type":"link in","z":"26262ba1.62dcbc","name":"","links":["a2c673cb.bdbca"],"x":2735,"y":3840,"wires":[["f807665.0451798"]]},{"id":"7e19ba21.83d6b4","type":"comment","z":"26262ba1.62dcbc","name":"Press On before doing anything!","info":"","x":2870,"y":3590,"wires":[]},{"id":"b064f285.5a01e","type":"change","z":"26262ba1.62dcbc","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"reset","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2980,"y":3840,"wires":[["1200f19c.e4f676"]]}]

Instructions:

Press the On (inject) node near the top - as said in the comments node.
That is needed to set things up.

Then click the Normal data (inject) node at the bottom.

You will see that being echoed in the OUTPUT node.

Now, press the Off node.

Click the Normal data node a couple of times to simulate the values being adjusted while the bulb is off.

Then click the On node again.

The On message is sent and then all the saved values.

It works.

But is there another way?

Without making it a Rocket science project of course.

tbh i am not sure what your flow is trying to accomplish, using queue, counters, contexts, skip etc, it is very much rocketscience to me.

Why not just store any adjustments as flow context and if bulb is on apply, if not on only update the flow context.

Because I hadn't thought of doing it that way. Or I don't know how to do it.
(Not sure which is more correct)

But flow context of node context..... What's the difference? Other than where they are stored?

This page on writing functions explains that.
https://nodered.org/docs/user-guide/writing-functions

The main difference is the scope where the value can be read by other nodes. In node context only the function node itself can read the stored value. In flow context it is the flow and when in global context you can guess.

Thanks.

I'm ok with that idea.

So: given the flow I posted I can't see why I would need any thing further than context. flow or global don't seem needed.

I can kind of get that I set a flow value to the bulb's extra stuff.
But I am failing to see the advantage of doing that over simply keeping it local in the node.

Granted I maybe could have not used the q-gate node and simply store the last thing sent and on-send it when the bulb is turned back on.

1 Like

It shows the difference. Explaining it: well, that's debatable.

Yes, and as I said: I am trying to get it working. Working: Doing what I want.

Yes, I may not have explained that too well. I seem to be good at that. Its something to do with how I think.

After the replies I may change it and simply store the last value sent to it.

However that too will have its drawbacks.

Why:

How I see it.

It's a bulb. It is on. I set the brightness (etc) to how I want it. Dim so as to give a certain mood.

I turn it off.

There is a problem that if: while the bulb is off one of those other things are adjusted the bulb turns on.

I'd prefer that to not happen.
Old school bulb dimmers don't turn on if you turn the brightness adjustment knob while the bulb is off.
But! If you turn the brightness knob to a different position then turn on the bulb, it will then be at the new brightness level.
So this propagates down to how I want this to work.

I want that to happen with the new electronic bulb.

Queuing messages is/was probably not the right way to go.
I get that now.

I have to ask to learn.

This is something I have done in light of the replies.

This is the code in a function node, which replaces all the other kafuffle.

var flag = context.get("flag") || 0;
if (msg.topic == "control")
{
    //
    if (msg.payload == "On")
    {
        context.set("flag",0);
    }
    if (msg.payload == "Off")
    {
        context.set("flag",1)
    }
    return;
}

if (flag === 0)
{
    //  Pass message.
    
    //  Get stored values.
    var held = context.get("hold") || 0;
    
    //  Build message.
    
    
    //
} else
{
    //  Block (store anything).
    context.set("hold",msg.payload);
    return;
}

It is work in progress.

But compared to the original...... Is this looking better?

1 Like

In terms of context - the flow context can be read by other nodes in the same flow.

For tracking the state I would use flow variables.
Example context:

{bulb: {state:"ON/OFF",color:"green/red/etc"}}

Update the color and on/off seperately and only pass the message if the state is ON.

Example flow.

[{"id":"ab267c8b.600df","type":"inject","z":"ad2c1422.b29428","name":"","topic":"","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":264,"wires":[["917baa18.467a68"]]},{"id":"917baa18.467a68","type":"change","z":"ad2c1422.b29428","name":"","rules":[{"t":"set","p":"bulb.state","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":354,"y":288,"wires":[["28caf38.743fd0c"]]},{"id":"7613e8d0.e65ef8","type":"inject","z":"ad2c1422.b29428","name":"","topic":"","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":312,"wires":[["917baa18.467a68"]]},{"id":"cdd0cc88.4105b8","type":"inject","z":"ad2c1422.b29428","name":"","topic":"","payload":"green","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":408,"wires":[["5103a9e6.0f4ad"]]},{"id":"5103a9e6.0f4ad","type":"change","z":"ad2c1422.b29428","name":"","rules":[{"t":"set","p":"bulb.color","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":354,"y":432,"wires":[["d7039df0.2ba538"]]},{"id":"7fed339d.a64cdc","type":"inject","z":"ad2c1422.b29428","name":"","topic":"","payload":"red","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":456,"wires":[["5103a9e6.0f4ad"]]},{"id":"d7039df0.2ba538","type":"switch","z":"ad2c1422.b29428","name":"Bulb On ?","property":"bulb.state","propertyType":"flow","rules":[{"t":"eq","v":"ON","vt":"str"},{"t":"eq","v":"OFF","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":540,"y":432,"wires":[["a86cdbae.1c0588"],["90490a6.229c2f8"]]},{"id":"a86cdbae.1c0588","type":"change","z":"ad2c1422.b29428","name":"Pass","rules":[{"t":"set","p":"payload","pt":"msg","to":"Bulb is ON - PASS","tot":"str"},{"t":"set","p":"context","pt":"msg","to":"bulb","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":698,"y":408,"wires":[["95fbeaa7.e46f8"]]},{"id":"90490a6.229c2f8","type":"change","z":"ad2c1422.b29428","name":"Block","rules":[{"t":"set","p":"payload","pt":"msg","to":"Bulb is OFF - BLOCKED","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":698,"y":456,"wires":[["4b63ddea.23fb2c"]]},{"id":"4b63ddea.23fb2c","type":"debug","z":"ad2c1422.b29428","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":842,"y":456,"wires":[]},{"id":"95fbeaa7.e46f8","type":"debug","z":"ad2c1422.b29428","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":842,"y":408,"wires":[]},{"id":"28caf38.743fd0c","type":"debug","z":"ad2c1422.b29428","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":552,"y":288,"wires":[]},{"id":"17b60e5d.e2bb72","type":"inject","z":"ad2c1422.b29428","name":"init  ","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":170,"y":648,"wires":[["674c17a3.43d1a"]]},{"id":"674c17a3.43d1a","type":"function","z":"ad2c1422.b29428","name":"","func":"f = flow.get(\"bulb\")\n\nif (typeof f == \"undefined\") {\n    flow.set(\"bulb\",{state:\"OFF\"})\n}","outputs":1,"noerr":0,"x":302,"y":648,"wires":[[]]},{"id":"3c893cf0.71e704","type":"comment","z":"ad2c1422.b29428","name":"Set initial bulb state to OFF if not exists","info":"","x":246,"y":600,"wires":[]}]

Thanks.

I get I need to do work to get things more as I want.

But, here's a problem I see with what that flow does:

I press the ON button.
I then press the RED button. I get a message saying the bulb is on and the red part is set.
Yeah. Ok.

Then I press the OFF button. I have to disable the block debug node. It doesn't really do anything AFAICS.

I press the GREEN button. Good. Nothing happens.

But when I press the ON button.... I don't get the GREEN.

The idea is the GREEN is sent when the bulb is turned on - as it was changed while the bulb is/was off.

It is an example flow, I was hoping that you could work it out further to expand on.

Sorry.....

I think I did it using your suggestion.

Thoughts?

[{"id":"a6276cfa.8523e","type":"change","z":"26262ba1.62dcbc","name":"","rules":[{"t":"set","p":"bulb.color","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":2320,"y":4740,"wires":[["bcdd3970.47aba8","f67d1f87.b45c4"]]},{"id":"9b57096d.e63f68","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"green","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2136,"y":4716,"wires":[["a6276cfa.8523e"]]},{"id":"a49ec36a.85b1d8","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"red","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2136,"y":4764,"wires":[["a6276cfa.8523e"]]},{"id":"bcdd3970.47aba8","type":"debug","z":"26262ba1.62dcbc","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":2518,"y":4740,"wires":[]},{"id":"f67d1f87.b45c4","type":"switch","z":"26262ba1.62dcbc","name":"Bulb On ?","property":"bulb.state","propertyType":"flow","rules":[{"t":"eq","v":"ON","vt":"str"},{"t":"eq","v":"OFF","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":2510,"y":4828,"wires":[["8218db4.bbfce28"],["4f00fa11.889064"]]},{"id":"8218db4.bbfce28","type":"change","z":"26262ba1.62dcbc","name":"Pass","rules":[{"t":"set","p":"payload","pt":"msg","to":"Bulb is ON - PASS","tot":"str"},{"t":"set","p":"context","pt":"msg","to":"bulb","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":2668,"y":4804,"wires":[["bc41bd58.ccc4d"]]},{"id":"4f00fa11.889064","type":"change","z":"26262ba1.62dcbc","name":"Block","rules":[{"t":"set","p":"payload","pt":"msg","to":"Bulb is OFF - BLOCKED","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2668,"y":4852,"wires":[["fe08be3.b27dec"]]},{"id":"c64b72bb.5894e","type":"change","z":"26262ba1.62dcbc","name":"","rules":[{"t":"set","p":"bulb.state","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":2320,"y":4828,"wires":[["f67d1f87.b45c4"]]},{"id":"bc41bd58.ccc4d","type":"debug","z":"26262ba1.62dcbc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":2812,"y":4804,"wires":[]},{"id":"fe08be3.b27dec","type":"debug","z":"26262ba1.62dcbc","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":2812,"y":4852,"wires":[]},{"id":"cba33d77.be962","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2136,"y":4804,"wires":[["c64b72bb.5894e"]]},{"id":"bddda49a.ec826","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2136,"y":4852,"wires":[["c64b72bb.5894e"]]}]

On mobile now, can't check your flow but what you essentially want to do is:

  • save the light state/color in context every time they change regardless if the state is on or off
  • when light state is toggled on, read the color value from the context and include them in the toggle on message
  • skip sending the message to the lamp if it only contains color values and the state in context is off

Edit: it sounds like you already got it this far!

Almost there (depending on your needs). You may want to set initial values if they don't exist yet, else you will find some weird behaviour along the way.

Yeah, I missed the "off" part.

One extra line seems to nearly do it.

[{"id":"f67d1f87.b45c4","type":"switch","z":"26262ba1.62dcbc","name":"Bulb On ?","property":"bulb.state","propertyType":"flow","rules":[{"t":"eq","v":"ON","vt":"str"},{"t":"eq","v":"OFF","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":2510,"y":4828,"wires":[["8218db4.bbfce28"],["4f00fa11.889064"]]},{"id":"8218db4.bbfce28","type":"change","z":"26262ba1.62dcbc","name":"Pass","rules":[{"t":"set","p":"payload","pt":"msg","to":"Bulb is ON - PASS","tot":"str"},{"t":"set","p":"context","pt":"msg","to":"bulb","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":2668,"y":4804,"wires":[["bc41bd58.ccc4d"]]},{"id":"4f00fa11.889064","type":"change","z":"26262ba1.62dcbc","name":"Block","rules":[{"t":"set","p":"payload","pt":"msg","to":"Bulb is OFF - BLOCKED","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2668,"y":4852,"wires":[["fe08be3.b27dec","bc41bd58.ccc4d"]]},{"id":"c64b72bb.5894e","type":"change","z":"26262ba1.62dcbc","name":"","rules":[{"t":"set","p":"bulb.state","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":2320,"y":4828,"wires":[["f67d1f87.b45c4"]]},{"id":"a6276cfa.8523e","type":"change","z":"26262ba1.62dcbc","name":"","rules":[{"t":"set","p":"bulb.color","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":2320,"y":4740,"wires":[["bcdd3970.47aba8","f67d1f87.b45c4"]]},{"id":"bc41bd58.ccc4d","type":"debug","z":"26262ba1.62dcbc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":2812,"y":4804,"wires":[]},{"id":"fe08be3.b27dec","type":"debug","z":"26262ba1.62dcbc","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":2812,"y":4852,"wires":[]},{"id":"cba33d77.be962","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2136,"y":4804,"wires":[["c64b72bb.5894e"]]},{"id":"bddda49a.ec826","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2136,"y":4852,"wires":[["c64b72bb.5894e"]]},{"id":"9b57096d.e63f68","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"green","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2136,"y":4716,"wires":[["a6276cfa.8523e"]]},{"id":"a49ec36a.85b1d8","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"red","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2136,"y":4764,"wires":[["a6276cfa.8523e"]]},{"id":"bcdd3970.47aba8","type":"debug","z":"26262ba1.62dcbc","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":2518,"y":4740,"wires":[]}]

Would this work for you ? It can be expanded to multiple bulbs (or other devices).

Yes, there may be multiple bulbs. Thus local single node context would also miss the problem that with a flow name it would be back to union lights: One on: All on.
kind of thing.

You could work with bulb "names" or something and per bulb keep track.

like

{"bulb":[{"id":1,"state":"OFF","color":"green"},{"id":2,"state":"ON","color":"red"},{"id":3,"state":"ON","color":"green"}]}

With the beauty of jsonata you can selectively turn on/off, change color per bulb or per group of bulbs and pass block based on their state

I'll look at yours in a second.

This is what I have since made:

[{"id":"3e7a9c13.62a77c","type":"function","z":"26262ba1.62dcbc","name":"","func":"var flag = context.get(\"flag\") || 0;\nvar x = \"\";\nif (msg.topic == \"control\")\n{\n    //\n    if (msg.payload == \"On\")\n    {\n        context.set(\"flag\",0);\n        node.status({fill:\"green\",shape:\"dot\",text:\"Pass\"});\n        \n        var held = context.get(\"hold\") || 0;\n    \n        if (held !== 0)\n        {\n            //  Build message.\n            x = context.get(\"hold\");\n            msg = {payload: \"On\", colour: x};\n        }\n        else\n        {\n            x = msg.payload;\n            msg = {payload: \"On\", colour: x};\n        }\n    }\n    if (msg.payload == \"Off\")\n    {\n        context.set(\"flag\",1)\n        node.status({fill:\"red\",shape:\"dot\",text:\"Block\"});\n        msg.payload = \"Off\";\n    }\n    return msg;\n}\n\n//node.warn(\"Here\");\n\nif (flag === 0)\n{\n    //  Pass message.\n//    node.warn(\"Pass\");\n    \n    //  Get stored values.\n    held = context.get(\"hold\") || 0;\n    \n    if (held !== 0)\n    {\n        //  Build message.\n        x = context.get(\"hold\");\n        msg = {payload: \"On\", colour: x};\n    }\n    else\n    {\n        x = msg.payload;\n        msg = {payload: \"On\", colour: x};\n    }\n    \n    \n    return msg;\n    //\n} else\n{\n    //  Block (store anything).\n    context.set(\"hold\",msg.payload);\n    return;\n}\n","outputs":1,"noerr":0,"x":2440,"y":4150,"wires":[["f37f9e97.43e6"]]},{"id":"bc808f81.e81f9","type":"change","z":"26262ba1.62dcbc","name":"control","rules":[{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2290,"y":4100,"wires":[["3e7a9c13.62a77c"]]},{"id":"d7cf154.981bde8","type":"inject","z":"26262ba1.62dcbc","name":"Red","topic":"","payload":"red","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2280,"y":4150,"wires":[["3e7a9c13.62a77c"]]},{"id":"f37f9e97.43e6","type":"debug","z":"26262ba1.62dcbc","name":"OUTPUT","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":2620,"y":4150,"wires":[]},{"id":"1c6baa41.db953e","type":"inject","z":"26262ba1.62dcbc","name":"Green","topic":"","payload":"green","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2280,"y":4200,"wires":[["3e7a9c13.62a77c"]]},{"id":"6651fc9c.ca198c","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"On","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2290,"y":4050,"wires":[["bc808f81.e81f9"]]},{"id":"1387b470.e15aa4","type":"inject","z":"26262ba1.62dcbc","name":"","topic":"","payload":"Off","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2290,"y":4010,"wires":[["bc808f81.e81f9"]]}]

Errr......

Sorry @bakman2... You have started talking above my intelligence level.

I tried several times to import that as a flow only to realise it isn't. So that really means I am stupid.

I am just now having a lot of fun with CSS and - I think - that sort of thing. I'm not getting it there so I am really not going to get it here.

If you don't mind, could you look at that latest flow though? I know it is very different to what you are saying. I get we think (everyone) differently.

To help me with understanding what I am doing, it would be nice if you wouldn't mind casting a view of it and just making sure I haven't left any nasty things in there that may bite me later.