How to get the summary of nodes used in node-red?

Here is a Friday twiddle for you all. An update to the original flow.

In this update, I've corrected a couple of issues and I've added a function node version as well as the JSONata version. In fact, the function node version of the flow is rather more complete and accurate because the original didn't take into account the fact that tabs and subflow definitions were included in the count.

Please remember to change the file name to match your own.

[
    {
        "id": "1dd9f4ac.8347eb",
        "type": "file in",
        "z": "396e6d9.614e192",
        "name": "",
        "filename": "/home/pi/nrlive/.data/flows.json",
        "format": "utf8",
        "chunk": false,
        "sendError": false,
        "x": 350,
        "y": 1900,
        "wires": [
            [
                "7db3c4dc.803e6c"
            ]
        ]
    },
    {
        "id": "51fb56d2.8ca248",
        "type": "inject",
        "z": "396e6d9.614e192",
        "name": "",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 140,
        "y": 1900,
        "wires": [
            [
                "1dd9f4ac.8347eb"
            ]
        ]
    },
    {
        "id": "2d29205.cb6abe",
        "type": "comment",
        "z": "396e6d9.614e192",
        "name": "How Many Nodes in my flow?",
        "info": "Don't forget to change the path to your flow file.\n\nNote the oddity regarding subflows. \nThey appear firstly as type \"subflow\" which is the\ndefinition, then again in the form\n\"subflow:<id>\" once for each instance of that\nsubflow `<id>` in your flows.\n\nI show both a JSONata and a function node\napproach to getting the data but note that\nthe JSONata version _is not quite correct_.\nIn the sense that it doesn't subtract the tabs\nand subflows from the overal counts.\n\nSo while the execution time of both approaches\nseems to be pretty identical, the function node\nis more comprehensive.",
        "x": 200,
        "y": 1860,
        "wires": []
    },
    {
        "id": "7db3c4dc.803e6c",
        "type": "json",
        "z": "396e6d9.614e192",
        "name": "",
        "pretty": false,
        "x": 610,
        "y": 1900,
        "wires": [
            [
                "3aeb5629.c2b33a",
                "53264ae7.07a974",
                "9c8f63ea.e8083"
            ]
        ]
    },
    {
        "id": "53264ae7.07a974",
        "type": "debug",
        "z": "396e6d9.614e192",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "false",
        "x": 770,
        "y": 1860,
        "wires": []
    },
    {
        "id": "3aeb5629.c2b33a",
        "type": "change",
        "z": "396e6d9.614e192",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "totalNodes",
                "pt": "msg",
                "to": "$count(payload)\t",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload^(type) {\t   `type`: $count([$])\t}",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "nodeTypesCount",
                "pt": "msg",
                "to": "$count($keys(payload))",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 780,
        "y": 1900,
        "wires": [
            [
                "5de6fbf7.a75344"
            ]
        ]
    },
    {
        "id": "9c8f63ea.e8083",
        "type": "function",
        "z": "396e6d9.614e192",
        "name": "",
        "func": "msg.totalNodes = msg.payload.length\n\nlet tabsCount = 0, subflowsCount = 0, nodeTypesCount = 0\nlet totalNodes = 0\nlet tabs = {}, subflows = {}, nodeTypes = {}\n\nmsg.payload.sort(function(a, b) {\n  var typeA = a.type.toUpperCase(); // ignore upper and lowercase\n  var typeB = b.type.toUpperCase(); // ignore upper and lowercase\n  if (typeA < typeB) {\n    return -1;\n  }\n  if (typeA > typeB) {\n    return 1;\n  }\n\n  // names must be equal\n  return 0;\n})\n\nmsg.payload.forEach((el) => {\n    if ( el.type === 'tab' ) {\n        tabsCount++\n        tabs[el.label] = el.id\n    } else if ( el.type === 'subflow' ) {\n        subflowsCount++\n        subflows[el.name] = el.id\n    } else {\n        nodeTypes[el.type] = nodeTypes[el.type]+1 || 1\n        totalNodes++\n    }\n})\n\nmsg.payload = {\n    'totalNodesCount': totalNodes,\n    'tabsCount': tabsCount,\n    'subflowsCount': subflowsCount,\n    'nodeTypesCount': Object.keys(nodeTypes).length,\n    'tabs': tabs,\n    'subflows': subflows,\n    'nodeTypes': nodeTypes,\n}\n\nreturn msg",
        "outputs": 1,
        "noerr": 0,
        "x": 715,
        "y": 1940,
        "wires": [
            [
                "97a2dead.fea94"
            ]
        ],
        "l": false
    },
    {
        "id": "5de6fbf7.a75344",
        "type": "debug",
        "z": "396e6d9.614e192",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 950,
        "y": 1900,
        "wires": []
    },
    {
        "id": "97a2dead.fea94",
        "type": "debug",
        "z": "396e6d9.614e192",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "x": 970,
        "y": 1940,
        "wires": []
    }
]
2 Likes