Loop Context Flow Data

Morning Team

Could some one give me example of how one would loop through flow context data and get the item name and value

Example:
for (property, value in config_alarm.alarm.zones["10"]){
-- here I expect to get out each property plust its current value
--zone
--state
--state_at
--triggered_at
}

Example Flow Context Data

{
    "alarm": {
        "beep_zones": {
            "beep_zones": "on"
        },
        "zones": {
            "10": {
                "zone": "10",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "00": {
                "zone": "00",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "01": {
                "zone": "01",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "02": {
                "zone": "02",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "03": {
                "zone": "03",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "04": {
                "zone": "04",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "05": {
                "zone": "05",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "07": {
                "zone": "07",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            }
        }
    }
}

Not really clear what you are asking
could you supply exactly what you require the output to be for the input you have shown.

[{"id":"9e7c0f6f96986e8f","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"beep_zones\":{\"beep_zones\":\"on\"},\"zones\":{\"10\":{\"zone\":\"10\",\"state\":\"armed\",\"state_at\":\"\",\"triggered\":\"\",\"triggered_at\":\"\"},\"00\":{\"zone\":\"00\",\"state\":\"armed\",\"state_at\":\"\",\"triggered\":\"\",\"triggered_at\":\"\"},\"01\":{\"zone\":\"01\",\"state\":\"armed\",\"state_at\":\"\",\"triggered\":\"\",\"triggered_at\":\"\"},\"02\":{\"zone\":\"02\",\"state\":\"armed\",\"state_at\":\"\",\"triggered\":\"\",\"triggered_at\":\"\"},\"03\":{\"zone\":\"03\",\"state\":\"armed\",\"state_at\":\"\",\"triggered\":\"\",\"triggered_at\":\"\"},\"04\":{\"zone\":\"04\",\"state\":\"armed\",\"state_at\":\"\",\"triggered\":\"\",\"triggered_at\":\"\"},\"05\":{\"zone\":\"05\",\"state\":\"armed\",\"state_at\":\"\",\"triggered\":\"\",\"triggered_at\":\"\"},\"07\":{\"zone\":\"07\",\"state\":\"armed\",\"state_at\":\"\",\"triggered\":\"\",\"triggered_at\":\"\"}}}","payloadType":"json","x":230,"y":5880,"wires":[["85d3c09154def601"]]},{"id":"85d3c09154def601","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"alarms","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":5880,"wires":[[]]},{"id":"5efe2c491b823f3b","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"10","payload":"","payloadType":"date","x":230,"y":5940,"wires":[["f2c5e6919fc30926"]]},{"id":"f2c5e6919fc30926","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"alarms.zones[msg.topic]","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":5940,"wires":[["f03c398bb62e4ea2"]]},{"id":"f03c398bb62e4ea2","type":"debug","z":"d1395164b4eec73e","name":"debug 2557","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":570,"y":5940,"wires":[]},{"id":"727434568e7c5729","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"alarms.zones","payloadType":"flow","x":270,"y":6000,"wires":[["f5c1e6f0c91cecf1"]]},{"id":"f5c1e6f0c91cecf1","type":"split","z":"d1395164b4eec73e","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":450,"y":6000,"wires":[["573e72c81fd36bae"]]},{"id":"573e72c81fd36bae","type":"debug","z":"d1395164b4eec73e","name":"debug 2558","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":590,"y":6000,"wires":[]}]

so the flow context is set

{
    "alarm": {
        "beep_zones": {
            "beep_zones": "on"
        },
        "zones": {
            "10": {
                "zone": "10",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "00": {
                "zone": "00",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "01": {
                "zone": "01",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "02": {
                "zone": "02",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "03": {
                "zone": "03",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "04": {
                "zone": "04",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "05": {
                "zone": "05",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            },
            "07": {
                "zone": "07",
                "state": "armed",
                "state_at": "",
                "triggered": "",
                "triggered_at": ""
            }
        }
    }
}

What I need to do is loop a given section of this and get the name and value
For example loop alarm.zones.10 and get each pottery and value

in Python I would do this

"for var_str_dict_key, var_str_dict_value in var_dict_config['storage']['alarm']['zones'][var_str_zone_reference].items():",
"               var_str_topic = var_str_topic.replace('{%s}' %(var_str_dict_key), str(var_str_dict_value))",

To loop through Object keys you need to use Object.keys() alternatively use Object.entries()

MDN is a good source for info:

1 Like

Does this work?

for (const zone in msg.payload.alarm.zones) {
    let newmsg = {}
    newmsg.payload = {"name": zone, "state": msg.payload.alarm.zones[zone].state}
    node.send (newmsg)
}
return msg;

Edit -
And if msg.payload.alarm.zones was an array, you could use

for (const zone of msg.payload.alarm.zones) {
    let newmsg = {}
    newmsg.payload = {"name": zone.zone, "state": zone.state}
    node.send (newmsg)
}

:upside_down_face:

1 Like

Thanks @Steve-Mcl this helped.

Which of these would be the better choice,

Option - 1
const object1 = flow.get("config_alarm.alarm.zones.10")

for (const [key, value] of Object.entries(object1)) {
    node.warn(`${key}: ${value}`);
}

Option - 2
for (const [key, value] of Object.entries(flow.get("config_alarm.alarm.zones.10"))) {
    node.warn(`${key}: ${value}`);
}

one think I don't quite understand as yet

Why would one do this
// node.warn(${key});

Instead of this
node.warn(key);

Not quite what I am after but thanks for your help

I ended up getting a solution here,

for me, option 1. Though I would probably be a bit more guarded

const key = "config_alarm.alarm.zones.10"
const object1 = flow.get(key)

if (!object1 || typeof object1 !== 'Object') {
    node.warn(`'${key}' is not valid or does not exist in the flow context.`);
    return null
}

for (const [key, value] of Object.entries(object1)) {
    node.warn({key, value});
}

No reason and wasteful. node.warn(key); is the better option here

BUT, there is a reason for doing node.warn({key, value}); and even simple things like node.warn({value}); - as you will see as you learn more about Node-RED and JS
In simple terms, it will be shown as an expandable object in the node-warn debug output (easier to work with)