One "master flow" several "slave flows"

Hi all,

I am using Node Red to collect and display data from several units in our company which works fine. In general I am getting data via MQTT for all units and display them.

Currently I have about 30 flows on one Node Red Server (one for each unit) which are doing exactly the same of course with other data and parameters.

When I want to change something I change it in one flow and copy it one by one to the other flows.

My qeustions is: Is there any possibility do define a "master" flow which I can "deploy" for the all units?

I have one flow collecting and parsing the data. From there I could jump to the "deployed" flows.

I am really looking forward to your suggestions.

Thanks for your help and best regards
Dabbelju

If they are so similar is it not possible to combine them onto one flow and use, for example, the mqtt topic, or something similar, to determine exactly what to do?
Alternatively (or in conjuction with the above) are you aware of the subflow capability. It may well be ideally suited to what you want to do.
https://nodered.org/docs/user-guide/editor/workspace/subflows

Hi Colin,

thanks for your reply. I am aware of subflows and did try it already. My problem with the subflow ist that I would need to set the Group in which a node is shown dynamically and I have not found a way yet to do it.

I know that I need to create the tab and group in dashboard, which is fine. But in the flow I want to pass a parameter (e.g. to a gauge) in which tab/group it should be displayed.

I will look around again to see if someone did this before. I am pretty sure that this situation is not new.

Thanks and best regards
Dabbelju

Could you post an example of the sort of flow that you have to keep repeating? There may be ways of doing it that you haven't thought of. See this for how to post a flow here.

Hi Colin,

here is the flow I want to have 30 times. A few Information on top:

In the UI I have three different "views" = tabs.

  • MOBIL (one TAB containing all units)
    Displaying a gauge and a button per unit for all units. It is an overview for all units I have. The button links to the detail tab of a unit.
  • DIVISION (one TAB per Division)
    More or less the same (a few more information about the unit) as MOBIL but only the units belonging to the division.
  • DETAIL (one TAB per UNIT)
    Detailed information about the unit.

I did play arround again with subflows which is nearly what I want. I can use it without any problem for the MOBIL TAB.

My problem starts when it comes to DIVISON and DETAIL view. At the end of teh day I would need to set the group dynamically.

Thanks for your help, highly appreciated!

[
    {
        "id": "24b6ad3.befba52",
        "type": "tab",
        "label": "Anzeige 2250",
        "disabled": false,
        "info": ""
    },
    {
        "id": "3ba693a1.029e0c",
        "type": "link in",
        "z": "24b6ad3.befba52",
        "name": "GR2250",
        "links": [],
        "x": 195,
        "y": 140,
        "wires": [
            [
                "55aeae00.57b03c"
            ]
        ]
    },
    {
        "id": "5e0186bd.35899",
        "type": "ui_gauge",
        "z": "24b6ad3.befba52",
        "name": "MOBIL - Teile pro Stunde",
        "group": "cd164f6d.ac1f98",
        "order": 1,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "{{msg.label}}",
        "label": "{{msg.units}}",
        "format": "{{value|number:2}}",
        "min": "0",
        "max": "0",
        "colors": [
            "#ca3737",
            "#e6e600",
            "#00b500"
        ],
        "seg1": "",
        "seg2": "",
        "x": 690,
        "y": 140,
        "wires": []
    },
    {
        "id": "55aeae00.57b03c",
        "type": "change",
        "z": "24b6ad3.befba52",
        "name": "Parameter setzen",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "values[1]",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "background",
                "pt": "msg",
                "to": "values[13]",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "units",
                "pt": "msg",
                "to": "Bogen/ h (Auftrag)",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "label",
                "pt": "msg",
                "to": "values[10]",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "units15",
                "pt": "msg",
                "to": "Bogen/ h (Ø 15min)",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "units30",
                "pt": "msg",
                "to": "Bogen/ h (Ø 30min)",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "unitstag",
                "pt": "msg",
                "to": "Bogen/Tag",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "ui_control.min",
                "pt": "msg",
                "to": "0",
                "tot": "num"
            },
            {
                "t": "set",
                "p": "ui_control.max",
                "pt": "msg",
                "to": "250",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "link",
                "pt": "flow",
                "to": "DEV GR2250",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "ui_group",
                "pt": "msg",
                "to": "testgroup",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 370,
        "y": 140,
        "wires": [
            [
                "5e0186bd.35899",
                "57109d07.acc31c",
                "235c8a6.bc2d7f6",
                "2a4b9ddd.5e6e02",
                "79ffc038.69702",
                "e01460d.a6bcba",
                "857442f0.1b96d8",
                "29656072.829018",
                "4da5cf23.86b4e",
                "4f6a879.37d5bf8",
                "f24c0bc9.ccdfa",
                "a6b368f9.3e49b"
            ]
        ]
    },
    {
        "id": "57109d07.acc31c",
        "type": "ui_button",
        "z": "24b6ad3.befba52",
        "name": "MOBIL - Button/Status",
        "group": "cd164f6d.ac1f98",
        "order": 2,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "{{msg.values[6]}} - {{msg.values[8]}} - {{msg.values[7]}} - {{msg.values[11]}}",
        "tooltip": "",
        "color": "",
        "bgcolor": "{{background}}",
        "icon": "",
        "payload": "temp",
        "payloadType": "str",
        "topic": "",
        "x": 680,
        "y": 180,
        "wires": [
            [
                "4aed47ad.418b38"
            ]
        ]
    },
    {
        "id": "235c8a6.bc2d7f6",
        "type": "ui_template",
        "z": "24b6ad3.befba52",
        "group": "e168fe4b.0b8b38",
        "name": "Druckerei - ALLE - Kopf",
        "order": 1,
        "width": 11,
        "height": 4,
        "format": "<div layout=\"row\" layout-align=\"start center\">\n  <span flex style=\"color: cyan\"><b>{{msg.values[10]}}</b></span>\n  <span flex><b>Produkt</b></span>\n  <span flex><b>Auftragsnummer</b></span>\n</div>\n<div layout=\"row\" layout-align=\"start center\">\n  <span flex style={{msg.colorstr}}><b>{{msg.values[6]}}</b></span>\n  <span flex style=\"color: lime\"><b>{{msg.values[7]}}</b></span>\n  <span flex style=\"color: lime\"><b><h2>{{msg.values[11]}}</h2></b></span>\n</div>\n<div layout=\"row\" layout-align=\"start center\">\n  <span flex><b>Startzeit</b></span>\n  <span flex><b>Laufzeit</b></span>\n  <span flex><b>Bogen</b></span>\n</div>\n<div layout=\"row\" layout-align=\"start center\">\n  <span flex style=\"color: lime\"><b>{{msg.values[9]}}</b></span>\n  <span flex style=\"color: lime\"><b>{{msg.values[5]}}</b></span>\n  <span flex style=\"color: lime\"><b><h2>{{msg.values[8]}}</h2></b></span>\n</div>\n",
        "storeOutMessages": false,
        "fwdInMessages": true,
        "templateScope": "local",
        "x": 690,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "2a4b9ddd.5e6e02",
        "type": "ui_button",
        "z": "24b6ad3.befba52",
        "name": "Druckerei - ALLE - Button/Status",
        "group": "e168fe4b.0b8b38",
        "order": 19,
        "width": 11,
        "height": 1,
        "passthru": false,
        "label": "{{msg.values[6]}} - {{msg.values[8]}} - {{msg.values[7]}} - {{msg.values[11]}}",
        "tooltip": "",
        "color": "",
        "bgcolor": "{{background}}",
        "icon": "",
        "payload": "DEV 2250",
        "payloadType": "str",
        "topic": "",
        "x": 720,
        "y": 360,
        "wires": [
            []
        ]
    },
    {
        "id": "79ffc038.69702",
        "type": "ui_gauge",
        "z": "24b6ad3.befba52",
        "name": "Druckerei - ALLE - Teile pro Stunde",
        "group": "e168fe4b.0b8b38",
        "order": 7,
        "width": 6,
        "height": 5,
        "gtype": "gage",
        "title": "{{msg.label}}",
        "label": "{{msg.units}}",
        "format": "{{value|number:2}}",
        "min": 0,
        "max": "0",
        "colors": [
            "#ca3737",
            "#e6e600",
            "#00b500"
        ],
        "seg1": "",
        "seg2": "",
        "x": 730,
        "y": 320,
        "wires": []
    },
    {
        "id": "64dd4de0.d5d084",
        "type": "ui_ui_control",
        "z": "24b6ad3.befba52",
        "name": "",
        "events": "all",
        "x": 1180,
        "y": 180,
        "wires": [
            []
        ]
    },
    {
        "id": "8c75c18.5b533c",
        "type": "comment",
        "z": "24b6ad3.befba52",
        "name": "TAB MOBIL - Anzeige auf der Übersichtsseite aller Maschinen",
        "info": "",
        "x": 800,
        "y": 100,
        "wires": []
    },
    {
        "id": "b530ee10.93ebd8",
        "type": "comment",
        "z": "24b6ad3.befba52",
        "name": "TAB DIVISON - Anzeige auf der Übersichtsseite einer \"Abteilung\"",
        "info": "",
        "x": 810,
        "y": 240,
        "wires": []
    },
    {
        "id": "bac13169.c2c818",
        "type": "comment",
        "z": "24b6ad3.befba52",
        "name": "TAB DETAIL - Anzeige Maschine im Detail",
        "info": "",
        "x": 740,
        "y": 420,
        "wires": []
    },
    {
        "id": "e01460d.a6bcba",
        "type": "ui_template",
        "z": "24b6ad3.befba52",
        "group": "1ef19d54.cee5fb",
        "name": "Detail - Kopf",
        "order": 1,
        "width": 23,
        "height": 3,
        "format": "<table>\n    <thead>\n        <tr>\n            <th style=\"width: 16%;\">Produkt</th>\n            <th style=\"width: 16%;\">Auftragsnummer</th>\n            <th style=\"width: 16%;\">Status</th>\n            <th style=\"width: 16%;\">Startzeit</th>\n            <th style=\"width: 16%;\">Laufzeit</th>\n            <th style=\"width: 16%;\">Bogen</th>\n        </tr>\n    </thead>\n    <tbody>\n        <tr style=\"text-align: center;\">\n            <td>{{msg.values[7]}}</td>\n            <td>{{msg.values[11]}}</td>\n            <td>{{msg.values[6]}}</td>\n            <td>{{msg.values[9]}}</td>\n            <td>{{msg.values[5]}}</td>\n            <td>{{msg.values[8]}}</td>\n        </tr>\n        <tr>\n            <td>&nbsp;</td>\n        </tr>\n        <tr>\n            <th>Station</th>\n            <th>akt. Zykluszeit</th>\n            <th>letzte Zykluszeit</th>\n            <th>letzter Datensatz</th>\n            <th></th>\n            <th></th>\n        </tr>\n        <tr style=\"text-align: center;\">\n            <td>{{msg.values[14]}}</td>\n            <td>{{msg.values[15]}}</td>\n            <td>{{msg.values[4]}}</td>\n            <td>{{msg.ts}}</td>\n            <td></td>\n            <td></td>\n        </tr>\n    </tbody>\n</table>\n",
        "storeOutMessages": false,
        "fwdInMessages": true,
        "templateScope": "local",
        "x": 650,
        "y": 460,
        "wires": [
            []
        ]
    },
    {
        "id": "a6b368f9.3e49b",
        "type": "ui_gauge",
        "z": "24b6ad3.befba52",
        "name": "DETAIL - Teile pro Stunde",
        "group": "1ef19d54.cee5fb",
        "order": 3,
        "width": 5,
        "height": 3,
        "gtype": "gage",
        "title": "{{msg.units}}",
        "label": "",
        "format": "{{value|number:2}}",
        "min": "0",
        "max": "0",
        "colors": [
            "#ca3737",
            "#e6e600",
            "#00b500"
        ],
        "seg1": "",
        "seg2": "",
        "x": 690,
        "y": 500,
        "wires": []
    },
    {
        "id": "a0d204ba.afcda",
        "type": "ui_gauge",
        "z": "24b6ad3.befba52",
        "name": "DETAIL - Teile pro 15 Minuten",
        "group": "1ef19d54.cee5fb",
        "order": 5,
        "width": 5,
        "height": 3,
        "gtype": "gage",
        "title": "{{msg.units15}}",
        "label": "",
        "format": "{{value|number:2}}",
        "min": "0",
        "max": "0",
        "colors": [
            "#ca3737",
            "#e6e600",
            "#00b500"
        ],
        "seg1": "",
        "seg2": "",
        "x": 710,
        "y": 540,
        "wires": []
    },
    {
        "id": "9535f989.a152e",
        "type": "ui_gauge",
        "z": "24b6ad3.befba52",
        "name": "DETAIL - Teile pro 30 Minuten",
        "group": "1ef19d54.cee5fb",
        "order": 7,
        "width": 5,
        "height": 3,
        "gtype": "gage",
        "title": "{{msg.units30}}",
        "label": "",
        "format": "{{value|number:2}}",
        "min": "0",
        "max": "0",
        "colors": [
            "#ca3737",
            "#e6e600",
            "#00b500"
        ],
        "seg1": "",
        "seg2": "",
        "x": 710,
        "y": 580,
        "wires": []
    },
    {
        "id": "857442f0.1b96d8",
        "type": "change",
        "z": "24b6ad3.befba52",
        "name": "15 Minuten",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "values[2]",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 350,
        "y": 540,
        "wires": [
            [
                "a0d204ba.afcda"
            ]
        ]
    },
    {
        "id": "29656072.829018",
        "type": "change",
        "z": "24b6ad3.befba52",
        "name": "30 Minuten",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "values[3]",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 350,
        "y": 580,
        "wires": [
            [
                "9535f989.a152e"
            ]
        ]
    },
    {
        "id": "2916247c.a65bcc",
        "type": "average-bars",
        "z": "24b6ad3.befba52",
        "name": "Stundendurchschnitt",
        "title": "Stundendurchschnitt",
        "period": "day",
        "yMin": "0",
        "yMax": "auto",
        "showBarsValue": true,
        "showScaleValue": true,
        "showLastValue": true,
        "showAverageValue": true,
        "showMinimumValue": true,
        "showMaximumValue": true,
        "maxBar": 30,
        "topColor": "#00ff40",
        "bottomColor": "#ff0000",
        "unit": "",
        "fontColor": "#aaaaaa",
        "barStyle": "Equalizer",
        "decimal": 1,
        "x": 680,
        "y": 620,
        "wires": [
            [
                "3939a59e.e66b7a"
            ]
        ]
    },
    {
        "id": "3939a59e.e66b7a",
        "type": "ui_template",
        "z": "24b6ad3.befba52",
        "group": "1ef19d54.cee5fb",
        "name": "Stundendurchschnitt",
        "order": 18,
        "width": 23,
        "height": 6,
        "format": "<div ng-bind-html=\"msg.payload\"></div>",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "templateScope": "local",
        "x": 920,
        "y": 620,
        "wires": [
            []
        ]
    },
    {
        "id": "4da5cf23.86b4e",
        "type": "change",
        "z": "24b6ad3.befba52",
        "name": "Stundendurchschnitt",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "values[1]",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "rate",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 380,
        "y": 620,
        "wires": [
            [
                "2916247c.a65bcc"
            ]
        ]
    },
    {
        "id": "a303f05b.cf6188",
        "type": "ui_template",
        "z": "24b6ad3.befba52",
        "group": "1ef19d54.cee5fb",
        "name": "Menge pro Tag",
        "order": 19,
        "width": 23,
        "height": 6,
        "format": "<div ng-bind-html=\"msg.payload\"></div>",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "templateScope": "local",
        "x": 900,
        "y": 660,
        "wires": [
            []
        ]
    },
    {
        "id": "4f6a879.37d5bf8",
        "type": "rbe",
        "z": "24b6ad3.befba52",
        "name": "",
        "func": "rbe",
        "gap": "",
        "start": "",
        "inout": "out",
        "property": "values[8]",
        "x": 150,
        "y": 660,
        "wires": [
            [
                "3c7a258f.e29302"
            ]
        ]
    },
    {
        "id": "3c7a258f.e29302",
        "type": "change",
        "z": "24b6ad3.befba52",
        "name": "Menge pro Tag",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "1",
                "tot": "num"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "maschinenzyklen",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 360,
        "y": 660,
        "wires": [
            [
                "8fad7094.477338"
            ]
        ]
    },
    {
        "id": "f24c0bc9.ccdfa",
        "type": "change",
        "z": "24b6ad3.befba52",
        "name": "Menge pro Stunde Chart",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "values[1]",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 390,
        "y": 700,
        "wires": [
            [
                "d784e881.05dc8"
            ]
        ]
    },
    {
        "id": "8fad7094.477338",
        "type": "sum-bars",
        "z": "24b6ad3.befba52",
        "name": "Menge pro Tag",
        "title": "Bogen/Tag",
        "period": "week",
        "yMin": "0",
        "yMax": "auto",
        "showBarsValue": true,
        "showScaleValue": true,
        "showSumValue": true,
        "maxBar": 30,
        "topColor": "#008000",
        "bottomColor": "#ff0000",
        "unit": "",
        "fontColor": "#aaaaaa",
        "barStyle": "Rectangle",
        "decimal": 1,
        "x": 660,
        "y": 660,
        "wires": [
            [
                "a303f05b.cf6188"
            ]
        ]
    },
    {
        "id": "d784e881.05dc8",
        "type": "ui_chart",
        "z": "24b6ad3.befba52",
        "name": "Menge pro Stunde (Auftrag)",
        "group": "1ef19d54.cee5fb",
        "order": 17,
        "width": 23,
        "height": 6,
        "label": "chart",
        "chartType": "line",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "0",
        "ymax": "250",
        "removeOlder": 1,
        "removeOlderPoints": "",
        "removeOlderUnit": "3600",
        "cutout": 0,
        "useOneColor": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "useOldStyle": false,
        "outputs": 1,
        "x": 700,
        "y": 700,
        "wires": [
            []
        ]
    },
    {
        "id": "8f365542.99b42",
        "type": "debug",
        "z": "24b6ad3.befba52",
        "name": "Anzeige 2250",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 660,
        "y": 60,
        "wires": []
    },
    {
        "id": "4aed47ad.418b38",
        "type": "change",
        "z": "24b6ad3.befba52",
        "name": "setLink",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "link",
                "tot": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 900,
        "y": 180,
        "wires": [
            [
                "64dd4de0.d5d084"
            ]
        ]
    },
    {
        "id": "cd164f6d.ac1f98",
        "type": "ui_group",
        "z": "",
        "name": "DEV Mobil Druckerei",
        "tab": "9c0c6f.5c50139",
        "order": 1,
        "disp": true,
        "width": 6,
        "collapse": false
    },
    {
        "id": "e168fe4b.0b8b38",
        "type": "ui_group",
        "z": "",
        "name": "DEV Druckerei ALLE",
        "tab": "5f45723d.e2e6bc",
        "order": 1,
        "disp": true,
        "width": 30,
        "collapse": false
    },
    {
        "id": "1ef19d54.cee5fb",
        "type": "ui_group",
        "z": "",
        "name": "Detail GR2250",
        "tab": "304b54dc.c3a774",
        "order": 1,
        "disp": true,
        "width": "23",
        "collapse": false
    },
    {
        "id": "9c0c6f.5c50139",
        "type": "ui_tab",
        "z": "",
        "name": "DEV Mobil",
        "icon": "dashboard",
        "order": 34,
        "disabled": false,
        "hidden": false
    },
    {
        "id": "5f45723d.e2e6bc",
        "type": "ui_tab",
        "z": "",
        "name": "DEV Druckerei",
        "icon": "dashboard",
        "order": 35,
        "disabled": false,
        "hidden": false
    },
    {
        "id": "304b54dc.c3a774",
        "type": "ui_tab",
        "z": "",
        "name": "DEV GR2250",
        "icon": "dashboard",
        "order": 36,
        "disabled": false,
        "hidden": false
    }
]```

Are multiple of those identical tabs on display at once? If only one then could you use one set of display nodes but change the data you feed them?

Hi Colin,

good idea I did try it but unfortunately I have multiple users which use the Dashboard. So it might happen that user a is looking at a detailed tab for unit x and at the same time I have user b looking at the detail tab for unit y.

The same problem with the DIVISON tab.

The subflow would help me, but I run into layout problems. I am looking forward to this project: https://github.com/node-red/designs/pull/24. If I got it right it would let me "layout" widgets in subflows.

Perhaps I am thinking in the wrong direction but a combination of subflow, layout subflow and setting the tab/group in which a widget is displayed dynamically (assuming I have it configured properly in the dashboard) would solve my issues.

Yes, I see your points. I think I will have to leave it for someone else to suggest something.

Thanks anyway, Colin!

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