[ { "id": "e2e-flow-tab", "type": "tab", "label": "E2E Test Flow", "disabled": false, "info": "End-to-end test flow that verifies EVOLV nodes load, accept input, and produce output." }, { "id": "inject-trigger", "type": "inject", "z": "e2e-flow-tab", "name": "Trigger once on start", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": true, "onceDelay": "3", "topic": "e2e-test", "payload": "", "payloadType": "date", "x": 160, "y": 80, "wires": [["build-measurement-msg"]] }, { "id": "build-measurement-msg", "type": "function", "z": "e2e-flow-tab", "name": "Build measurement input", "func": "// Simulate an analog sensor reading sent to the measurement node.\n// The measurement node expects a numeric payload on topic 'analogInput'.\nmsg.payload = 4.2 + Math.random() * 15.8; // 4-20 mA range\nmsg.topic = 'analogInput';\nnode.status({ fill: 'green', shape: 'dot', text: 'sent ' + msg.payload.toFixed(2) });\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 380, "y": 80, "wires": [["measurement-e2e-node"]] }, { "id": "measurement-e2e-node", "type": "measurement", "z": "e2e-flow-tab", "name": "E2E-Level-Sensor", "scaling": true, "i_min": 4, "i_max": 20, "i_offset": 0, "o_min": 0, "o_max": 5, "simulator": false, "smooth_method": "", "count": "10", "uuid": "", "supplier": "e2e-test", "category": "level", "assetType": "sensor", "model": "e2e-virtual", "unit": "m", "enableLog": false, "logLevel": "error", "positionVsParent": "upstream", "positionIcon": "", "hasDistance": false, "distance": 0, "distanceUnit": "m", "distanceDescription": "", "x": 600, "y": 80, "wires": [ ["debug-process"], ["debug-dbase"], ["debug-parent"] ] }, { "id": "debug-process", "type": "debug", "z": "e2e-flow-tab", "name": "Process Output", "active": true, "tosidebar": true, "console": true, "tostatus": true, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 830, "y": 40, "wires": [] }, { "id": "debug-dbase", "type": "debug", "z": "e2e-flow-tab", "name": "Database Output", "active": true, "tosidebar": true, "console": true, "tostatus": true, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 840, "y": 80, "wires": [] }, { "id": "debug-parent", "type": "debug", "z": "e2e-flow-tab", "name": "Parent Output", "active": true, "tosidebar": true, "console": true, "tostatus": true, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 830, "y": 120, "wires": [] }, { "id": "inject-periodic", "type": "inject", "z": "e2e-flow-tab", "name": "Periodic (5s)", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "5", "crontab": "", "once": true, "onceDelay": "6", "topic": "e2e-heartbeat", "payload": "", "payloadType": "date", "x": 160, "y": 200, "wires": [["heartbeat-func"]] }, { "id": "heartbeat-func", "type": "function", "z": "e2e-flow-tab", "name": "Heartbeat check", "func": "// Verify the EVOLV measurement node is running by querying its presence\nmsg.payload = {\n check: 'heartbeat',\n timestamp: Date.now(),\n nodeCount: global.get('_e2e_msg_count') || 0\n};\n// Increment message counter\nlet count = global.get('_e2e_msg_count') || 0;\nglobal.set('_e2e_msg_count', count + 1);\nnode.status({ fill: 'blue', shape: 'ring', text: 'beat #' + (count+1) });\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 380, "y": 200, "wires": [["debug-heartbeat"]] }, { "id": "debug-heartbeat", "type": "debug", "z": "e2e-flow-tab", "name": "Heartbeat Debug", "active": true, "tosidebar": true, "console": true, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 600, "y": 200, "wires": [] }, { "id": "inject-monster-prediction", "type": "inject", "z": "e2e-flow-tab", "name": "Monster prediction", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": true, "onceDelay": "4", "topic": "model_prediction", "payload": "120", "payloadType": "num", "x": 150, "y": 320, "wires": [["evolv-monster"]] }, { "id": "inject-monster-flow", "type": "inject", "z": "e2e-flow-tab", "name": "Monster flow", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "3", "crontab": "", "once": true, "onceDelay": "5", "topic": "i_flow", "payload": "3600", "payloadType": "num", "x": 140, "y": 360, "wires": [["evolv-monster"]] }, { "id": "inject-monster-start", "type": "inject", "z": "e2e-flow-tab", "name": "Monster start", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": true, "onceDelay": "6", "topic": "start", "payload": "", "payloadType": "date", "x": 140, "y": 400, "wires": [["evolv-monster"]] }, { "id": "evolv-monster", "type": "monster", "z": "e2e-flow-tab", "name": "E2E-Monster", "samplingtime": 1, "minvolume": 5, "maxweight": 23, "emptyWeightBucket": 3, "aquon_sample_name": "112100", "supplier": "e2e-test", "subType": "samplingCabinet", "model": "e2e-virtual", "unit": "m3/h", "enableLog": false, "logLevel": "error", "x": 390, "y": 360, "wires": [ ["debug-monster-process"], ["debug-monster-dbase"], [], [] ] }, { "id": "debug-monster-process", "type": "debug", "z": "e2e-flow-tab", "name": "Monster Process Output", "active": true, "tosidebar": true, "console": true, "tostatus": true, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 660, "y": 340, "wires": [] }, { "id": "debug-monster-dbase", "type": "debug", "z": "e2e-flow-tab", "name": "Monster Database Output", "active": true, "tosidebar": true, "console": true, "tostatus": true, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 670, "y": 380, "wires": [] }, { "id": "inject-dashboardapi-register", "type": "inject", "z": "e2e-flow-tab", "name": "DashboardAPI register child", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": true, "onceDelay": "12", "payload": "", "payloadType": "date", "x": 160, "y": 500, "wires": [["build-dashboardapi-msg"]] }, { "id": "build-dashboardapi-msg", "type": "function", "z": "e2e-flow-tab", "name": "Build dashboardapi input", "func": "msg.topic = 'registerChild';\nmsg.payload = {\n config: {\n general: {\n name: 'E2E-Level-Sensor'\n },\n functionality: {\n softwareType: 'measurement'\n }\n }\n};\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 400, "y": 500, "wires": [["dashboardapi-e2e"]] }, { "id": "dashboardapi-e2e", "type": "dashboardapi", "z": "e2e-flow-tab", "name": "E2E-DashboardAPI", "logLevel": "error", "enableLog": false, "host": "grafana", "port": "3000", "bearerToken": "", "x": 660, "y": 500, "wires": [["debug-dashboardapi-output"]] }, { "id": "debug-dashboardapi-output", "type": "debug", "z": "e2e-flow-tab", "name": "DashboardAPI Output", "active": true, "tosidebar": true, "console": true, "tostatus": true, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 920, "y": 500, "wires": [] } ]