Need help with subflow code

I am trying to rationalise a subflow and rather than using a setup message.

I know the code in the function node is a bit messy, but that's because it was written to receive this setup message.

When I deployed it I was told that msg is not defined.

[{"id":"f78bdf06ae572875","type":"subflow","name":"Button toggle with enable (new)","info":"The message from the `button` node must be `X` to toggle the state, and the button must NOT pass the input onto the output!\n\nA `setup` message must also be received at flow initiation before it will work.\n\nStructure (eg):\n```\nmsg = {\n    \"topic\":\"SETUP\",\n    \"disabledColour\":\"brown\",\n    \"colourA\": \"lime\",\n    \"colourB\": \"green\",\n    \"txtA\": \"Log\",\n    \"txtB\": \"Stop\",\n    \"txtclrA\": \"black\",\n    \"txtclrB\": \"black\",\n    \"payloadA\": \"GO\",\n    \"payloadB\": \"STOP\",\n    \"topicSET\": \"CONTROL\"\n}\nreturn msg;\n```\n```\ndisabledColour - the colour the button is when disabled.\ncolourA - the background colour if condition `A` is selected.  (Temporary)\ncolourB - the background colour if condition `B` is selected.  (Temporary)\ntxtA - The text to display if condition `A` is selected.\ntxtB - The text to display if condition `B` is selected.\ntxtclrA - the colour of the text if condition `A` is selected.\ntxtclrB - the colour of the text if condtion `B` is selected.\npayloadA - the text sent to the `gate` if condtion `A` is selected.\npayloadB - the text sent to the `gate` if condition `B` is selected.\ntopicSET - the message topic which is sent to the `gate`.\n```\n\nThe *temporary* meaning is that the button will show that colour for a few seconds\nthen it will turn to the `disabled` colour.\n\nThe active time is `3` seconds to press/toggle the button once initially pressed.","category":"","in":[{"x":190,"y":90,"wires":[{"id":"f9b742ce67c53927"},{"id":"7f6db7e922a9aec4"}]}],"out":[{"x":560,"y":50,"wires":[{"id":"7f6db7e922a9aec4","port":0}]},{"x":560,"y":130,"wires":[{"id":"7f6db7e922a9aec4","port":1}]}],"env":[],"meta":{},"color":"#3FADB5","outputLabels":["To the `GATE` node","To the `BUTTON` node"],"icon":"node-red-dashboard/ui_switch.png","status":{"x":560,"y":210,"wires":[{"id":"6aaf4e9c71587bfd","port":0}]}},{"id":"7f6db7e922a9aec4","type":"function","z":"f78bdf06ae572875","name":"Push Button","func":"//  2021 06 08  tidied up a lot of mess.   Working now.\n//  Rewriting this for subflow usability.\nmsg1 = {};\nvar state = context.get(\"STATE\")||0;\nvar enabled = context.get(\"ENABLED\")||0;\n\n//node.warn(\"INPUT \" + msg.payload);\n\n\n\n//  Look for a message with topic set to SETUP to set values.\n//if (msg.topic == \"SETUP\")     //Do this if the message is NOT \"X\"\n    //  To control the state of the `gate` node.\n    //msg.payload = context.get(\"PayloadA\");\n    //msg.topic = context.get(\"Topic\");\n    //  To set the `button` colour/text/etc.\n    msg1.txt = context.get(\"Atxt\");\n    msg1.colour = context.get(\"DISABLEDCLR\");\n    msg1.fontclr = context.get(\"AFC\");\n\n    //return [msg,msg1];\n//}\n\n//node.warn(\"payload \" + msg.payload);\n//node.warn(\" start\");\n\n\n//      Now on to the real stuff.\nif (msg.payload == \"X\")\n{\n    //\n    //node.warn(\"Button press detected\");\n    //\n    if (context.get(\"PayloadA\") == undefined)\n    {\n        node.status({text:\"Button_Toggle_Enable_Context_Not_Set\"});\n        return [null,null];\n    }\n    //node.warn(\"X detected\");\n    //  Insert here code to enable other stuff.\n    if (enabled === 0)\n    {\n        //node.warn(\"State = \" + state);\n\n        if (state === 0)\n        {\n            //\n            //  Set things for state 0\n            //\n            //node.warn(\"State 0 detected\");\n            msg.payload = context.get(\"PayloadA\");\n            msg.topic = context.get(\"Topic\");\n            msg1.colour = context.get(\"ABGC\");\n            msg1.txt = context.get(\"Atxt\");\n            msg1.fontclr = context.get(\"AFC\");\n        }\n        else if (state === 1)\n        {\n            //\n            //  Set things for state 1\n            //\n            //node.warn(\"State 1 detected\");\n            msg.payload = context.get(\"PayloadB\");\n            msg.topic = context.get(\"Topic\");\n            msg1.colour = context.get(\"BBGC\");\n            msg1.txt = context.get(\"Btxt\");\n            msg1.fontclr = context.get(\"BFC\");\n        }\n        context.set(\"ENABLED\",1);\n        return [null,msg1];\n    }\n\n//    if (context.get(\"ENABLED\") === 1)\n    state = (state + 1)% 2;\n    //node.warn(state);\n    context.set(\"STATE\",state);\n    if (enabled === 1)\n    {\n        if (state === 0)\n        {\n            //  Condition A\n            msg.payload = context.get(\"PayloadA\");\n            msg1.colour = context.get(\"ABGC\");\n            msg1.txt = context.get(\"Atxt\");\n            msg1.fontclr = context.get(\"AFC\");\n        } else\n        if (state === 1)\n        {\n            //  Condition B\n            msg.payload = context.get(\"PayloadB\");\n            msg1.colour = context.get(\"BBGC\");\n            msg1.txt = context.get(\"Btxt\");\n            msg1.fontclr = context.get(\"BFC\");\n        }\n    }\n    \n    if (context.get(\"Topic\") == \"~\")\n    {\n        msg.topic = \"\";\n    } else\n    {\n        msg.topic = context.get(\"Topic\");\n    }\n    return [msg,msg1];\n}\nif (msg.payload == \"Z\")\n{\n    //\n    ////node.warn(\"Timed out\");\n    //\n    if (context.get(\"PayloadA\") == undefined)\n    {\n        return [null,null];\n    }\n    context.set(\"ENABLED\",0);\n    if (state === 0)\n    {\n        //\n        //  Set things for state 1\n        //\n        msg.payload = context.get(\"PayloadA\");\n        msg.topic = context.get(\"Topic\");\n        msg1.colour = context.get(\"DISABLEDCLR\");\n        msg1.txt = context.get(\"Atxt\");\n        msg1.fontclr = context.get(\"AFC\");\n    }\n    else if (state === 1)\n    {\n        //\n        //  Set things for state 2\n        //\n        msg.payload = context.get(\"PayloadB\");\n        msg.topic = context.get(\"Topic\");\n        msg1.colour = context.get(\"DISABLEDCLR\");\n        msg1.txt = context.get(\"Btxt\");\n        msg1.fontclr = context.get(\"BFC\");\n    }\n    return [null,msg1];\n}\n","outputs":2,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\n\ncontext.set(\"ABGC\", env.get(\"colourA\"));\ncontext.set(\"BBGC\", env.get(\"colourB\"));\n//\n//  Disabled button background colour.\n//\ncontext.set(\"DISABLEDCLR\",env.get(\"disabledColour\"));\n//\n//  Now do text.\n//\ncontext.set(\"Atxt\", env.get(\"txtA\"));\ncontext.set(\"Btxt\", env.get(\"txtB\"));\n//\n//  Font colours.\n//\ncontext.set(\"AFC\",env.get(\"txtclrA\"));\ncontext.set(\"BFC\",env.get(\"txtclrB\"));\n//\n//  Payloads.\n//\ncontext.set(\"PayloadA\", env.get(\"payloadA\"));\ncontext.set(\"PayloadB\", env.get(\"payloadB\"));\n\nmsg.payload = context.get(\"PayloadA\");\nmsg.topic = context.get(\"Topic\");\n\nmsg1.txt = context.get(\"Atxt\");\nmsg1.colour = context.get(\"DISABLEDCLR\");\nmsg1.fontclr = context.get(\"AFC\");\n\nreturn [msg,msg1];\n","finalize":"","libs":[],"x":380,"y":90,"wires":[[],[]],"outputLabels":["To gate","To button"]},{"id":"f9b742ce67c53927","type":"trigger","z":"f78bdf06ae572875","name":"","op1":"","op2":"Z","op1type":"nul","op2type":"str","duration":"3","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":255,"y":140,"wires":[["7f6db7e922a9aec4"]],"l":false},{"id":"6aaf4e9c71587bfd","type":"status","z":"f78bdf06ae572875","name":"","scope":["7f6db7e922a9aec4"],"x":400,"y":210,"wires":[[]]},{"id":"27872f8e88e28fba","type":"subflow:f78bdf06ae572875","z":"1283f6a97005461c","name":"","env":[{"name":"disabledColour","value":"brown","type":"str"},{"name":"txtA","value":"Go","type":"str"},{"name":"txtB","value":"Stop","type":"str"},{"name":"txtclrA","value":"black","type":"str"},{"name":"txtclrB","value":"black","type":"str"},{"name":"colourA","value":"lime","type":"str"},{"name":"colourB","value":"green","type":"str"},{"name":"payloadA","value":"go","type":"str"},{"name":"payloadB","value":"stop","type":"str"},{"name":"topicSET","value":"CONTROL","type":"str"}],"x":340,"y":120,"wires":[["1ee1d186296bbfb9"],["7dfdce3cd2ede505"]]}]

Thanks.

Without looking too deep, i see you havent declared the variable msg1

image

but that wouldnt cause it to say msg is not defined.

Can you copy the exact error?

Can you see / search which node generates this error?

You can't reference 'msg' in the 'On Start' section because you don't have a msg at that point.

From Version 1.1 released : Node-RED

The Function node now lets you provide code that should be run when the node is deployed and when it is being stopped. This lets you initialise any state in the node before it starts handling any messages

1 Like

ah, well spotted.

@Trying_to_learn - what paul says ↑

Thanks guys.

My bad.

I was stuck with needing a message sent at start up.

The solution - of course - is to put an inject node just in front of the node and inject at startup.

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