[ { "id": "ps_basic_tab", "type": "tab", "label": "PumpingStation - Basic", "disabled": false, "info": "Tier 1: single pumpingStation node driven by inject nodes only. Demonstrates the canonical Phase-2 topic API: set.mode, set.inflow, set.demand." }, { "id": "ps_basic_title", "type": "comment", "z": "ps_basic_tab", "name": "PumpingStation - Basic\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nA 50 m³ basin (3.5 m tall, inflow at 3.0 m, outflow at 0.2 m,\noverflow at 3.2 m). controlMode = levelbased, manual demand allowed\nonly when set.mode = manual.\n\nHOW TO USE:\n 1. Deploy the flow.\n 2. Click \"set.mode = manual\" so set.demand is honoured.\n 3. Click \"set.inflow = 60 m3/h\" to push wastewater into the basin.\n 4. Watch the basin fill on Port 0 (level, volume, percControl rise).\n 5. Click \"calibrate volume 25 m3\" to jump straight to half-full.\n\nAliases (changemode, q_in, Qd, …) still work but log a deprecation\nwarning - fresh flows use the canonical names.", "info": "", "x": 600, "y": 40, "wires": [] }, { "id": "ps_basic_inj_mode", "type": "inject", "z": "ps_basic_tab", "name": "set.mode = manual", "props": [ { "p": "topic", "vt": "str" }, { "p": "payload", "v": "manual", "vt": "str" } ], "topic": "set.mode", "repeat": "", "crontab": "", "once": false, "onceDelay": "", "x": 200, "y": 160, "wires": [ [ "ps_basic_node" ] ] }, { "id": "ps_basic_inj_mode_lvl", "type": "inject", "z": "ps_basic_tab", "name": "set.mode = levelbased", "props": [ { "p": "topic", "vt": "str" }, { "p": "payload", "v": "levelbased", "vt": "str" } ], "topic": "set.mode", "repeat": "", "crontab": "", "once": false, "onceDelay": "", "x": 220, "y": 200, "wires": [ [ "ps_basic_node" ] ] }, { "id": "ps_basic_inj_inflow", "type": "inject", "z": "ps_basic_tab", "name": "set.inflow = 60 m3/h", "props": [ { "p": "topic", "vt": "str" }, { "p": "payload", "v": "60", "vt": "num" } ], "topic": "set.inflow", "repeat": "", "crontab": "", "once": false, "onceDelay": "", "x": 200, "y": 260, "wires": [ [ "ps_basic_node" ] ] }, { "id": "ps_basic_inj_demand", "type": "inject", "z": "ps_basic_tab", "name": "set.demand = 40 %", "props": [ { "p": "topic", "vt": "str" }, { "p": "payload", "v": "40", "vt": "num" } ], "topic": "set.demand", "repeat": "", "crontab": "", "once": false, "onceDelay": "", "x": 200, "y": 300, "wires": [ [ "ps_basic_node" ] ] }, { "id": "ps_basic_inj_calvol", "type": "inject", "z": "ps_basic_tab", "name": "calibrate volume 25 m3", "props": [ { "p": "topic", "vt": "str" }, { "p": "payload", "v": "25", "vt": "num" } ], "topic": "cmd.calibrate.volume", "repeat": "", "crontab": "", "once": false, "onceDelay": "", "x": 220, "y": 360, "wires": [ [ "ps_basic_node" ] ] }, { "id": "ps_basic_inj_callvl", "type": "inject", "z": "ps_basic_tab", "name": "calibrate level 1.5 m", "props": [ { "p": "topic", "vt": "str" }, { "p": "payload", "v": "1.5", "vt": "num" } ], "topic": "cmd.calibrate.level", "repeat": "", "crontab": "", "once": false, "onceDelay": "", "x": 220, "y": 400, "wires": [ [ "ps_basic_node" ] ] }, { "id": "ps_basic_node", "type": "pumpingStation", "z": "ps_basic_tab", "name": "Pumping Station", "simulator": false, "basinVolume": 50, "basinHeight": 3.5, "inflowLevel": 3, "outflowLevel": 0.2, "overflowLevel": 3.2, "defaultFluid": "wastewater", "inletPipeDiameter": 0.3, "outletPipeDiameter": 0.3, "pipelineLength": 80, "maxDischargeHead": 24, "staticHead": 12, "maxInflowRate": 200, "temperatureReferenceDegC": 15, "timeleftToFullOrEmptyThresholdSeconds": 0, "enableDryRunProtection": true, "enableOverfillProtection": true, "dryRunThresholdPercent": 2, "overfillThresholdPercent": 98, "minHeightBasedOn": "outlet", "processOutputFormat": "process", "dbaseOutputFormat": "influxdb", "refHeight": "NAP", "basinBottomRef": 1, "uuid": "example-ps-001", "supplier": "WBD-RD", "category": "station", "assetType": "pumpingstation", "model": "demo-50m3", "unit": "m3/h", "enableLog": true, "logLevel": "info", "positionVsParent": "atEquipment", "positionIcon": "", "hasDistance": false, "distance": "", "distanceUnit": "m", "distanceDescription": "", "controlMode": "levelbased", "startLevel": 1.2, "minLevel": 0.4, "maxLevel": 2.8, "flowSetpoint": null, "flowDeadband": null, "x": 1320, "y": 300, "wires": [ [ "ps_basic_format" ], [ "ps_basic_dbg_influx" ], [ "ps_basic_dbg_parent" ] ] }, { "id": "ps_basic_format", "type": "function", "z": "ps_basic_tab", "name": "Merge deltas + format", "func": "const p = (msg && msg.payload && typeof msg.payload === 'object') ? msg.payload : {};\nconst cache = context.get('c') || {};\nObject.assign(cache, p);\ncontext.set('c', cache);\nfunction pick(prefix) {\n for (const k of Object.keys(cache)) if (k === prefix || k.indexOf(prefix + '.') === 0) {\n const v = Number(cache[k]); if (Number.isFinite(v)) return v;\n } return null;\n}\nconst vol = pick('volume.predicted.atequipment');\nconst lvl = pick('level.predicted.atequipment');\nconst flIn = pick('flow.predicted.in');\nmsg.payload = {\n state: cache.state || 'unknown',\n controlMode: cache.controlMode || cache.mode || 'n/a',\n direction: cache.direction || 'n/a',\n percControl: cache.percControl != null ? Number(cache.percControl).toFixed(1) + ' %' : 'n/a',\n volume: vol != null ? vol.toFixed(2) + ' m3' : 'n/a',\n volumePercent: cache.volumePercent != null ? Number(cache.volumePercent).toFixed(1) + ' %' : 'n/a',\n level: lvl != null ? lvl.toFixed(3) + ' m' : 'n/a',\n inflow: flIn != null ? (flIn * 3600).toFixed(1) + ' m3/h' : 'n/a',\n timeToFull: cache.timeToFull != null ? Number(cache.timeToFull).toFixed(0) + ' s' : 'n/a',\n timeToEmpty: cache.timeToEmpty != null ? Number(cache.timeToEmpty).toFixed(0) + ' s' : 'n/a'\n};\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1560, "y": 280, "wires": [ [ "ps_basic_dbg_process" ] ] }, { "id": "ps_basic_dbg_process", "type": "debug", "z": "ps_basic_tab", "name": "Port 0: Process", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 1800, "y": 240, "wires": [] }, { "id": "ps_basic_dbg_influx", "type": "debug", "z": "ps_basic_tab", "name": "Port 1: InfluxDB", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "x": 1800, "y": 320, "wires": [] }, { "id": "ps_basic_dbg_parent", "type": "debug", "z": "ps_basic_tab", "name": "Port 2: Parent reg", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "x": 1800, "y": 380, "wires": [] }, { "id": "grp_ps_basic", "type": "group", "z": "ps_basic_tab", "name": "Pumping Station (PC)", "style": { "label": true, "stroke": "#000000", "fill": "#0c99d9", "fill-opacity": "0.10" }, "nodes": [ "ps_basic_node", "ps_basic_format" ], "x": 1290, "y": 230, "w": 500, "h": 140 } ]