Sub-flows. I am missing something in how they work

That will result in you accessing the flow context variable $parent.device_Button_Debug

But I think you mean to get the value of $parent.device then add _Button_Debug to the end of that and use that as the key.

So if you already have device as a local variable containing the result of flow.get("$parent.device") then

var debug = flow.get(device+'_Button_Debug')

Would be correct.

If not, then I haven't understood what you want.

Either myself or @knolleary could be right. It depends what is in device.

I don't fully understand that. I thought that to get the value from the parent flow context the string defining the name had to start with "$parent." so that would only work if device contained a string "$parent.something"

I have interpreted the question as wanting to get the name of the device from parent context and use that as part of the key name when accessing local context.

I may well be wrong in that interpretation.

Sorry for the confusion.

Thanks for clearing up the confusion with the structure on building the name.

Just to reiterate the problem:

At the beginning a messages is sent to the sub-flow which sets the device name.
That is stored in sub-flow context( ) for that node.
Things happen and the device name is used to check/isolate/identify who is using the sub-flow.

Above the sub-flow I set a flow variable which indicates if the sub-flow has its debug active.
Obviously it is a flow variable as it needs to be accessed from the sub-flow.

When a message arrives in the sub-flow it checks if the flow variable (from the parent flow) is set to debug.

So I need to construct the name of the variable needed to check if the debug is active.
As in the flow/code I need to construct that name.

I need the device name with '_Button_Debug' for clarity.

So:

Correct. That is what I want.

So as an example:
The device is TimePi.
It needs to see if the flow variable named TimePi_Button_Debug is active. (True)

The original code is:
var debug = flow.get(device+'_Button_Debug') || false; // if active: true

That is what you (@knolleary) posted.

I am surprised that I got it correct.

Maybe I should have tested it first, before asking, but in light of other tests, it didn't seem to work.

Here is the flow I was using to establish if what I wrote is/was correct.
It doesn't work.

Walk through of this test flow:
Two inject nodes which set/change flow variable test to ONE or TWO.

The Test node invokes the sub-flow.
That reads the flow value of test and sends it out as the message.

Nothing comes out.

So I am confused why it should work, yet in testing, it doesn't seem to.

Flow here:

[{"id":"d03cee5c.debbf","type":"subflow","name":"Subflow 2","info":"","in":[{"x":220,"y":100,"wires":[{"id":"b6a05627.03a81"}]}],"out":[{"x":560,"y":100,"wires":[{"id":"b6a05627.03a81","port":0},{"id":"c320b7e7.d22ce","port":0}]}],"status":{"x":570,"y":190,"wires":[{"id":"16c3d7fc.e478","port":0}]}},{"id":"b6a05627.03a81","type":"function","z":"d03cee5c.debbf","name":"Get flow variable","func":"node.status({text:\"Message received\"});\nvar x;\nx = flow.get(test);\nmsg.payload = x;\nreturn msg;","outputs":1,"noerr":0,"x":400,"y":100,"wires":[[]]},{"id":"16c3d7fc.e478","type":"status","z":"d03cee5c.debbf","name":"","scope":null,"x":380,"y":190,"wires":[[]]},{"id":"c320b7e7.d22ce","type":"change","z":"d03cee5c.debbf","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$test","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":50,"wires":[[]]},{"id":"9ea5acd.d1ad25","type":"debug","z":"accbdb61.d75918","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":580,"y":760,"wires":[]},{"id":"69a06ac9.813d24","type":"inject","z":"accbdb61.d75918","name":"Test","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":760,"wires":[["f6961980.dfd6d"]]},{"id":"f6961980.dfd6d","type":"subflow:d03cee5c.debbf","z":"accbdb61.d75918","name":"","x":340,"y":760,"wires":[["9ea5acd.d1ad25"]]},{"id":"26a16337.fdde04","type":"inject","z":"accbdb61.d75918","name":"One","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":620,"wires":[["37c662d1.dc05ae"]]},{"id":"37c662d1.dc05ae","type":"change","z":"accbdb61.d75918","name":"","rules":[{"t":"set","p":"test","pt":"flow","to":"ONE","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":620,"wires":[[]]},{"id":"f43ae422.a4c","type":"change","z":"accbdb61.d75918","name":"","rules":[{"t":"set","p":"test","pt":"flow","to":"TWO","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":670,"wires":[[]]},{"id":"79938c3d.d2cf7c","type":"inject","z":"accbdb61.d75918","name":"Two","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":670,"wires":[["f43ae422.a4c"]]}]

Sub flow:

[{"id":"b6a05627.03a81","type":"function","z":"d03cee5c.debbf","name":"Get flow variable","func":"node.status({text:\"Message received\"});\nvar x;\nx = flow.get(test);\nmsg.payload = x;\nreturn msg;","outputs":1,"noerr":0,"x":400,"y":100,"wires":[[]]},{"id":"16c3d7fc.e478","type":"status","z":"d03cee5c.debbf","name":"","scope":null,"x":380,"y":190,"wires":[[]]}]

What am I missing?
(It will be something obvious or silly. But hey, I'm sorry. I can't see it.)

Ok, I got the test flow working.

The function node is this:
(bit messy, but it has debug stuff)

node.status({text:"Message received"});
var x;
var y = "blank";
node.status({text:"blah1"});
x = flow.get("$parent.test");
y = '>>>' + x + '<<<';
node.status({text:"blah2"});
msg.payload = y;
return msg;

Great. Progress.

But the bigger problem is that the name (x) needs to be preceded by something. (the device in the real example).

So for the sake of it I'll make it A_

I'll set the A_ in the code. That's not a problem.

How do I attach it to the name of the parent flow variable name I get?

Does this help with the clarity?
(or make it worse?)

Update:
This is now the code in the function node.
Given that the parent flow has a flow variable A_test set to ONE:

node.status({text:"Message received"});
var prefix = 'A_';
var x;
var y = "blank";
var name = prefix + "test";
node.warn("Name set to " + name);
node.status({text:"blah1"});
x = flow.get("$parent.name");
y = '>>>' + x + '<<<';
node.status({text:"blah2"});
msg.payload = y;
return msg;

>>>undefined<<<

Stuck.

Oh, the node.warn works and I see A_test as the name.

Another update:

Modifying the code further to this:

node.status({text:"Message received"});
var prefix = 'A_';
var x;
var t;
var y = "blank";
var name = prefix + "test";
node.warn("Name set to " + name);
node.status({text:"blah1"});
x = flow.get("$parent.name");
t = flow.get("$parent.A_test");
node.warn("T is " + t);
y = '>>>' + x + '<<<';
node.status({text:"blah2"});
msg.payload = y;
return msg;

I get a correct reply/printout of T.
So there seems a problem with the name construction of x.

Making the line:
x = flow.get("$parent."+name);

resolves the problem.

At last!

Thanks all.

And in the bigger picture it should be this:
var debug = flow.get("$parent."+device+'_Button_Debug') || false; // if active: true

yes?