Consolidating flows

I’m trying to consolidate some of my motion and lighting automations. Here is what I’ve come up with so far

My question is, is this a good way to do it, or is there a better way?

I prefer to use sub-flows to combine entities. All my door and window sensors in one sub flow, all my intrusion detection (motion sensors, etc) in another sub flow, my logic for sending messages in another sub-flow, and I try to be as generic as possible when I am placing a service call so that I can use that service call multiple times with different flows.

I don’t fully understand what you mean, do you mind posting the code?

It’s funny when people ask me for this, as I can’t simply do that. What PART do you want more information on? I can show you screenshots of how everything works together, but with links, subflows, and global variables…it’s impossible for me to share the entire thing.

1 Like

I’ve not use sub flows yet, so I was just hoping to see how you are implementing them.

Here is a subflow of mine, consolidating all the window and door sensors into one node that I can read from.

And here is one of the flows that uses it (bottom left).

1 Like

Thank you!

How do you differentiate the payloads from the output?

I just used 1 through whatever.

Every entity has an entity name and a friendly name. I run everything through a subflow called “prep chat” to form the msg object that I want to come out the other end. If I want to do something else with them, I filter off the entity name.

It’s messy, but it works for me. I will eventually get around to cleaning it up.

2 Likes

As I’m not that good at writing code, but understands most of it when I read, I would love to get a dump of that flow to learn. Would you mind posting an export of it? :slight_smile:

Of the prep chat flow?

Exactly :slight_smile:

I’ll try to get it in a bit. I’m not near a computer right now.

1 Like

Just a reminder if you get a chance to post the code please? I find this very interesting.

My apologies. I forgot to come back to this thread. A lot of this could be cleaned up and done nicer, but this is what I came up with right after starting to use Node Red with my HA instance, and it’s worked, so I haven’t messed with it.

[
    {
        "id": "8d53840d.bbbfa8",
        "type": "function",
        "z": "caaac6d8.279038",
        "name": "friendly name",
        "func": "if(msg.data.attributes){\n    msg.entity = msg.data.attributes.friendly_name;\n} else if (msg.data.new_state) {\n    msg.entity = msg.data.new_state.attributes.friendly_name;\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 140,
        "y": 140,
        "wires": [
            [
                "1fe45b17.2d3b85"
            ]
        ]
    },
    {
        "id": "59081597.6ee05c",
        "type": "debug",
        "z": "caaac6d8.279038",
        "name": "Prep Chat",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "x": 1420,
        "y": 180,
        "wires": []
    },
    {
        "id": "c471888.d318a78",
        "type": "change",
        "z": "caaac6d8.279038",
        "name": "find set temp",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "data.new_state.attributes.temperature",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 570,
        "y": 140,
        "wires": [
            [
                "1d733de4.1a6ce2"
            ]
        ]
    },
    {
        "id": "1fe45b17.2d3b85",
        "type": "function",
        "z": "caaac6d8.279038",
        "name": "what device",
        "func": "if(msg.topic.includes(\"climate.downstairs_thermostat_\")||msg.topic.includes(\"climate.upstairs_thermostat_\")){\n    msg.type = \"thermostat\";\n    return [null, msg, null, null];\n}\nelse if(msg.topic.includes(\"_temp\")){\n    msg.type = \"temperature\";\n    return [null, null, msg, null];\n}\nelse if(msg.topic.includes(\"_phone_battery\")||msg.topic.includes(\"iphone_battery_level\")||msg.topic.includes(\"_battery\")){\n    msg.type = \"battery\";\n    return [null, null, null, msg];\n}\nelse if(msg.topic.includes(\"person.\")){\n    msg.type = \"person\";\n    return [msg, null, null, null];\n}\nelse { return [msg, null, null, null]; }",
        "outputs": "4",
        "noerr": 0,
        "x": 310,
        "y": 140,
        "wires": [
            [
                "abbbd0b7.04188"
            ],
            [
                "c471888.d318a78"
            ],
            [
                "1d733de4.1a6ce2"
            ],
            [
                "eceeb643.a8c838"
            ]
        ],
        "outputLabels": [
            "state",
            "thermostat",
            "temp reading",
            "phone battery"
        ]
    },
    {
        "id": "abbbd0b7.04188",
        "type": "function",
        "z": "caaac6d8.279038",
        "name": "what verb?",
        "func": "if(msg.topic.endsWith(\"_home_status\")){\n    if(msg.payload === 'on'){\n        msg.payload = 'home';\n    } else if(msg.payload === 'off'){\n        msg.payload = 'not home'\n    }\n    msg.entity = msg.entity.split(\" \")[0];\n    msg.verb = 'is';\n}\nif(msg.topic.includes(\"person.\")){\n    if(msg.payload === 'not_home'){\n        msg.payload = 'not home';\n        msg.verb = 'is';\n    }\n    else if(msg.payload !== 'home'){\n        msg.verb = 'is at'\n    }\n    else if(msg.payload === 'home'){\n        msg.verb = 'is'\n    }\n    msg.entity = msg.entity.split(\" \")[0];\n}\nelse if(msg.topic.endsWith(\"alarm_control_panel.house_alarm\")){\n    if(msg.payload === 'armed_home'){\n        msg.payload = 'armed home'\n    }\n    else if(msg.payload === 'armed_away'){\n        msg.payload = 'armed away'\n    }\n    else if(msg.payload === 'pending'){\n        msg.payload = 'arming in 60 seconds'\n    }\n    msg.verb = 'is';\n}\nelse if(msg.entity.endsWith(\"s\")){\n    msg.verb = \"are\";\n}\nelse if(msg.payload == 'Breached'){\n    msg.verb = \"has been\";\n}\nelse if(msg.type == \"thermostat\"){\n    msg.verb = \"set temp is\";\n}\nelse if(msg.type == \"battery\"){\n    msg.verb = \"is at\";\n}\nelse { msg.verb = \"is\"; }\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 970,
        "y": 120,
        "wires": [
            [
                "4c3b13a0.ddb33c"
            ]
        ]
    },
    {
        "id": "1d733de4.1a6ce2",
        "type": "function",
        "z": "caaac6d8.279038",
        "name": "add UOM to payload",
        "func": "if(msg.data.attributes){\n    var val = msg.payload;\n    msg.payload = val + msg.data.attributes.unit_of_measurement;\n} else if (msg.data.new_state) {\n    if(msg.data.new_state.attributes.temperature && !msg.topic.includes(\"_battery_sensor\")){\n        var val = msg.data.new_state.attributes.temperature.toString();\n        msg.payload = val + \"°F\";\n    } else { \n        var val =  msg.data.new_state.state; \n        msg.payload = val + msg.data.new_state.attributes.unit_of_measurement;\n    }\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 780,
        "y": 180,
        "wires": [
            [
                "abbbd0b7.04188"
            ]
        ]
    },
    {
        "id": "eceeb643.a8c838",
        "type": "function",
        "z": "caaac6d8.279038",
        "name": "batt_hits_25",
        "func": "if (msg.data.old_state.state == \"26.0\" && msg.data.new_state.state == \"25.0\"){\n    return msg;\n} else { return null;}\n",
        "outputs": 1,
        "noerr": 0,
        "x": 570,
        "y": 220,
        "wires": [
            [
                "1d733de4.1a6ce2"
            ]
        ]
    },
    {
        "id": "4c3b13a0.ddb33c",
        "type": "change",
        "z": "caaac6d8.279038",
        "name": "set message",
        "rules": [
            {
                "t": "set",
                "p": "message",
                "pt": "msg",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1130,
        "y": 120,
        "wires": [
            [
                "fed78da3.bca8"
            ]
        ]
    },
    {
        "id": "fed78da3.bca8",
        "type": "template",
        "z": "caaac6d8.279038",
        "name": "Entity is/are status",
        "field": "payload",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "{{{entity}}} {{verb}} {{message}}",
        "output": "str",
        "x": 1310,
        "y": 120,
        "wires": [
            [
                "59081597.6ee05c"
            ]
        ]
    }
]

@flamingm0e I forgot to report back and thank you for showing me the subflows. They’ve become a huge part of my automations, especially the YAML/Node-RED security alarm I’ve been working on.

Thanks again!

1 Like