Use Group Env Variable in global variable name

I’m trying to utilize a group environment variable as an addendum to variable names throughout a flow. Attached is a simplified version - a group env variable is set to TankNum = T1 and in theory a change node could set a variable name with a combination of a static name + a variable name. The resulting variable name would be TankNameT1. Is there any way of doing this as this method doesn’t seem to work?

[
    {
        "id": "1e05ea3ac797b66e",
        "type": "group",
        "z": "f6200681b265563b",
        "name": "",
        "style": {
            "label": true
        },
        "nodes": [
            "a17e5330370eca1d",
            "9ad2dc41299e88d4",
            "785e596f500556a3"
        ],
        "env": [
            {
                "name": "TankNum",
                "value": "T1",
                "type": "str"
            }
        ],
        "x": 174,
        "y": 6659,
        "w": 552,
        "h": 82
    },
    {
        "id": "a17e5330370eca1d",
        "type": "inject",
        "z": "f6200681b265563b",
        "g": "1e05ea3ac797b66e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "str",
        "x": 270,
        "y": 6700,
        "wires": [
            [
                "785e596f500556a3"
            ]
        ]
    },
    {
        "id": "9ad2dc41299e88d4",
        "type": "debug",
        "z": "f6200681b265563b",
        "g": "1e05ea3ac797b66e",
        "name": "debug 1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 620,
        "y": 6700,
        "wires": []
    },
    {
        "id": "785e596f500556a3",
        "type": "change",
        "z": "f6200681b265563b",
        "g": "1e05ea3ac797b66e",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "TankName${TankNum}",
                "tot": "global"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 440,
        "y": 6700,
        "wires": [
            [
                "9ad2dc41299e88d4"
            ]
        ]
    }
]

Screenshot 2025-09-01 at 2.01.23 PM

In the change node add a rule before global rule.
set msg. TankNum
to value
$ TankNum

Then in the global rule
use
TankName[msg.TankNum]

Thanks for the assist. It’s currently showing me “undefined” on the debug. New code export and image attached.

[
    {
        "id": "1e05ea3ac797b66e",
        "type": "group",
        "z": "f6200681b265563b",
        "name": "",
        "style": {
            "label": true
        },
        "nodes": [
            "a17e5330370eca1d",
            "9ad2dc41299e88d4",
            "785e596f500556a3"
        ],
        "env": [
            {
                "name": "TankNum",
                "value": "T1",
                "type": "str"
            }
        ],
        "x": 174,
        "y": 6659,
        "w": 552,
        "h": 82
    },
    {
        "id": "a17e5330370eca1d",
        "type": "inject",
        "z": "f6200681b265563b",
        "g": "1e05ea3ac797b66e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "str",
        "x": 270,
        "y": 6700,
        "wires": [
            [
                "785e596f500556a3"
            ]
        ]
    },
    {
        "id": "9ad2dc41299e88d4",
        "type": "debug",
        "z": "f6200681b265563b",
        "g": "1e05ea3ac797b66e",
        "name": "debug 1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 620,
        "y": 6700,
        "wires": []
    },
    {
        "id": "785e596f500556a3",
        "type": "change",
        "z": "f6200681b265563b",
        "g": "1e05ea3ac797b66e",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "TankNum",
                "pt": "msg",
                "to": "TankNum",
                "tot": "env"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "TankName[msg.TankNum]",
                "tot": "global"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 440,
        "y": 6700,
        "wires": [
            [
                "9ad2dc41299e88d4"
            ]
        ]
    }
]

Can you show the sidebar context where the global TankName is set.

I didn't use an env variable for TankNum (set msg.TankNum using msg.payload) but this worked for me.
Just to check, TankNum is a number & TankName is an Array (with number of elements at least as great as TankNum)?

Tank name is going to be, for example:

TankT1
TankT2
TankT16
TankC3

That is where you set the env var.

I am asking to see your sidebar context tab, This will show if there is a global context var and what it is, so I can clearly understand how the global is set up.

I think you may be using separate globals for each tank, it would be simpler to set up a global object for all tanks.

[edit]
Example of how to set tanks object and how to read value for global using group env

[{"id":"fd653333f4af8a92","type":"inject","z":"d1395164b4eec73e","name":"set tanks global object","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":260,"y":2160,"wires":[["1959b4cc2eb0baa2"]]},{"id":"1959b4cc2eb0baa2","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"Tanks","pt":"global","to":"{\"T1\":1,\"T2\":2,\"T16\":16,\"C3\":3}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":2160,"wires":[[]]},{"id":"1e05ea3ac797b66e","type":"group","z":"d1395164b4eec73e","name":"","style":{"label":true},"nodes":["a17e5330370eca1d","9ad2dc41299e88d4","785e596f500556a3"],"env":[{"name":"TankNum","value":"T1","type":"str"}],"x":174,"y":2219,"w":552,"h":82},{"id":"a17e5330370eca1d","type":"inject","z":"d1395164b4eec73e","g":"1e05ea3ac797b66e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"str","x":270,"y":2260,"wires":[["785e596f500556a3"]]},{"id":"9ad2dc41299e88d4","type":"debug","z":"d1395164b4eec73e","g":"1e05ea3ac797b66e","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":620,"y":2260,"wires":[]},{"id":"785e596f500556a3","type":"change","z":"d1395164b4eec73e","g":"1e05ea3ac797b66e","name":"","rules":[{"t":"set","p":"TankNum","pt":"msg","to":"TankNum","tot":"env"},{"t":"set","p":"payload","pt":"msg","to":"Tanks[msg.TankNum]","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":2260,"wires":[["9ad2dc41299e88d4"]]}]

I have about 15 or so tanks that are being temperature controlled - each one in a flow like the flows below. I’m trying to set a group environment variable that can be used to modify some of the variable names so that when I tweak one of these group flows in the future, it will be a lot easier to replicate to each tank.

Your flow creates the following in context data but my version doesn’t create a variable called global.TankNameT1 as I would expect.

Screenshot 2025-09-01 at 3.13.57 PM

1 Like

So, for example, any time TankC1 is referenced in the name of different variables, the environment variable can be set on a group level and used in different variable names within that group.

I am trying to point out to you that you have made your globals more difficult to work with. Having separate global vars for each tank and then each tanks properties, makes it harder to access each property, as your are now noticing as you application becomes more involved.

Setting the tanks to an object will be a better solution in the long run for you. so instead of trying to create a context using your ( Frankenstein ) design, why not use the power of an already created system and get the most out of the JSON/javascript object, as it is what it was designed for.

another example

[{"id":"fd653333f4af8a92","type":"inject","z":"d1395164b4eec73e","name":"set tanks global object","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":280,"y":2220,"wires":[["1959b4cc2eb0baa2"]]},{"id":"1959b4cc2eb0baa2","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"Tanks","pt":"global","to":"{\"T1\":{\"batch\":1,\"sip\":{\"upper\":\"up1\",\"lower\":\"low1\"}},\"T2\":{\"batch\":2,\"sip\":{\"upper\":\"up2\",\"lower\":\"low2\"}}}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":2220,"wires":[[]]},{"id":"1e05ea3ac797b66e","type":"group","z":"d1395164b4eec73e","name":"","style":{"label":true},"nodes":["a17e5330370eca1d","9ad2dc41299e88d4","785e596f500556a3","2074fec0d74f0ad0","667e1ec4078c14a3"],"env":[{"name":"TankNum","value":"T1","type":"str"}],"x":174,"y":2279,"w":632,"h":122},{"id":"a17e5330370eca1d","type":"inject","z":"d1395164b4eec73e","g":"1e05ea3ac797b66e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"str","x":290,"y":2320,"wires":[["785e596f500556a3"]]},{"id":"9ad2dc41299e88d4","type":"debug","z":"d1395164b4eec73e","g":"1e05ea3ac797b66e","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":640,"y":2320,"wires":[]},{"id":"785e596f500556a3","type":"change","z":"d1395164b4eec73e","g":"1e05ea3ac797b66e","name":"","rules":[{"t":"set","p":"TankNum","pt":"msg","to":"TankNum","tot":"env"},{"t":"set","p":"payload","pt":"msg","to":"Tanks[msg.TankNum].sip","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":2320,"wires":[["9ad2dc41299e88d4"]]},{"id":"2074fec0d74f0ad0","type":"change","z":"d1395164b4eec73e","g":"1e05ea3ac797b66e","name":"","rules":[{"t":"set","p":"Tanks.T1.sip.upper","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":660,"y":2360,"wires":[[]]},{"id":"667e1ec4078c14a3","type":"inject","z":"d1395164b4eec73e","g":"1e05ea3ac797b66e","name":"set ta property in anks global object","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"upper","payload":"","payloadType":"date","x":360,"y":2360,"wires":[["2074fec0d74f0ad0"]]}]

Yes you will have to rethink and edit your already created flows, but in the end your flows will become simpler to create and maintain. With a well thought out object you could probably have one flow do the job of your 15 flows. Removing the need to add a flow each time you add a tank , all you would need to do is add a entry in the global object for the new tank.

p.s. When you finally show me the sidebar context for the global you are trying to read, i may be able to show you the way you can do it, your way, i am not going to guess what your global context vars look like. An example flow containing an inject and change node setting your global, would be nice then i and others would be able to test and provide a example using the correct context name and value/s.

Yeah, “just make it simpler” doesn’t take into account the complexity of all of the data sources coming in and out and dashboard nodes. Sometimes you have to build a complex machine first and then simplify it. I’m in the process of simplifying it and learning how to do that in node-red along the way.

It seems like there isn’t actually a way of using an environment variable from a group in constructing variable names.

Sure there is, here is an example using JSONata

[{"id":"785e596f500556a3","type":"change","z":"d1395164b4eec73e","g":"1e05ea3ac797b66e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$globalContext(\"TankName\" & $env(\"TankNum\"))\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":2320,"wires":[["9ad2dc41299e88d4"]]}]