Some checks failed
CI / lint-and-test (push) Has been cancelled
The tank gauge (basin level) and 270° arc gauge (fill %) now live on the trend pages alongside the basin metrics chart — not on the control page. Each trend page (10 min / 1 hour) gets its own pair of gauges. Layout per trend page Basin group: - Chart (width 8): Basin fill % + Level + Net flow series - Tank gauge (width 2): 0–3 m with color zones at stop/start levels - Arc gauge (width 2): 0–100% fill with red/orange/green zones Deployed via partial (nodes-only) deploy so the basin wasn't reset. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3987 lines
87 KiB
JSON
3987 lines
87 KiB
JSON
[
|
|
{
|
|
"id": "tab_process",
|
|
"type": "tab",
|
|
"label": "\ud83c\udfed Process Plant",
|
|
"disabled": false,
|
|
"info": "EVOLV plant model: pumpingStation + machineGroupControl + 3 rotatingMachines, each with upstream and downstream pressure measurements.\n\nReceives commands via link-in nodes from the Dashboard / Demo Drivers tabs. Emits per-pump status via link-out per pump.\n\nNo UI, no demo drivers, no one-shot setup logic on this tab \u2014 those live on their own tabs so this layer can be lifted into production unchanged."
|
|
},
|
|
{
|
|
"id": "c_process_title",
|
|
"type": "comment",
|
|
"z": "tab_process",
|
|
"name": "\ud83c\udfed PROCESS PLANT \u2014 EVOLV nodes only",
|
|
"info": "Per pump: 2 measurement sensors \u2192 rotatingMachine \u2192 output formatter \u2192 link-out to dashboard.\nMGC orchestrates 3 pumps. PS observes basin (manual mode for the demo).\nAll cross-tab wires are link-in / link-out by named channel.",
|
|
"x": 640,
|
|
"y": 20,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_pump_a",
|
|
"type": "comment",
|
|
"z": "tab_process",
|
|
"name": "\u2500\u2500 Pump A \u2500\u2500",
|
|
"info": "Up + Dn pressure sensors register as children. rotatingMachine emits state on port 0 (formatted then link-out to UI). Port 2 emits registerChild \u2192 MGC.",
|
|
"x": 640,
|
|
"y": 100,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "meas_pump_a_u",
|
|
"type": "measurement",
|
|
"z": "tab_process",
|
|
"name": "PT-A-Up",
|
|
"mode": "analog",
|
|
"channels": "[]",
|
|
"scaling": false,
|
|
"i_min": 0,
|
|
"i_max": 1,
|
|
"i_offset": 0,
|
|
"o_min": 50,
|
|
"o_max": 400,
|
|
"simulator": true,
|
|
"smooth_method": "mean",
|
|
"count": "5",
|
|
"processOutputFormat": "process",
|
|
"dbaseOutputFormat": "influxdb",
|
|
"uuid": "sensor-pump_a-upstream",
|
|
"supplier": "vega",
|
|
"category": "sensor",
|
|
"assetType": "pressure",
|
|
"model": "vega-pressure-10",
|
|
"unit": "mbar",
|
|
"assetTagNumber": "PT-1-U",
|
|
"enableLog": false,
|
|
"logLevel": "warn",
|
|
"positionVsParent": "upstream",
|
|
"positionIcon": "",
|
|
"hasDistance": false,
|
|
"distance": 0,
|
|
"distanceUnit": "m",
|
|
"distanceDescription": "",
|
|
"x": 380,
|
|
"y": 140,
|
|
"wires": [
|
|
[],
|
|
[],
|
|
[
|
|
"pump_a"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "meas_pump_a_d",
|
|
"type": "measurement",
|
|
"z": "tab_process",
|
|
"name": "PT-A-Dn",
|
|
"mode": "analog",
|
|
"channels": "[]",
|
|
"scaling": false,
|
|
"i_min": 0,
|
|
"i_max": 1,
|
|
"i_offset": 0,
|
|
"o_min": 800,
|
|
"o_max": 2200,
|
|
"simulator": true,
|
|
"smooth_method": "mean",
|
|
"count": "5",
|
|
"processOutputFormat": "process",
|
|
"dbaseOutputFormat": "influxdb",
|
|
"uuid": "sensor-pump_a-downstream",
|
|
"supplier": "vega",
|
|
"category": "sensor",
|
|
"assetType": "pressure",
|
|
"model": "vega-pressure-10",
|
|
"unit": "mbar",
|
|
"assetTagNumber": "PT-1-D",
|
|
"enableLog": false,
|
|
"logLevel": "warn",
|
|
"positionVsParent": "downstream",
|
|
"positionIcon": "",
|
|
"hasDistance": false,
|
|
"distance": 0,
|
|
"distanceUnit": "m",
|
|
"distanceDescription": "",
|
|
"x": 380,
|
|
"y": 190,
|
|
"wires": [
|
|
[],
|
|
[],
|
|
[
|
|
"pump_a"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lin_setpoint_pump_a",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:setpoint-A",
|
|
"links": [
|
|
"lout_setpoint_pump_a_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 160,
|
|
"wires": [
|
|
[
|
|
"build_setpoint_pump_a"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "build_setpoint_pump_a",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "build setpoint cmd (Pump A)",
|
|
"func": "msg.topic = 'execMovement';\nmsg.payload = { source: 'GUI', action: 'execMovement', setpoint: Number(msg.payload) };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 600,
|
|
"y": 160,
|
|
"wires": [
|
|
[
|
|
"pump_a"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lin_seq_pump_a",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:pump-A-seq",
|
|
"links": [
|
|
"lout_seq_pump_a_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 210,
|
|
"wires": [
|
|
[
|
|
"pump_a"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "pump_a",
|
|
"type": "rotatingMachine",
|
|
"z": "tab_process",
|
|
"name": "Pump A",
|
|
"speed": "10",
|
|
"startup": "2",
|
|
"warmup": "1",
|
|
"shutdown": "2",
|
|
"cooldown": "1",
|
|
"movementMode": "staticspeed",
|
|
"machineCurve": "",
|
|
"uuid": "pump-pump_a",
|
|
"supplier": "hidrostal",
|
|
"category": "pump",
|
|
"assetType": "pump-centrifugal",
|
|
"model": "hidrostal-H05K-S03R",
|
|
"unit": "m3/h",
|
|
"curvePressureUnit": "mbar",
|
|
"curveFlowUnit": "m3/h",
|
|
"curvePowerUnit": "kW",
|
|
"curveControlUnit": "%",
|
|
"enableLog": false,
|
|
"logLevel": "warn",
|
|
"positionVsParent": "atEquipment",
|
|
"positionIcon": "",
|
|
"hasDistance": false,
|
|
"distance": 0,
|
|
"distanceUnit": "m",
|
|
"distanceDescription": "",
|
|
"x": 900,
|
|
"y": 180,
|
|
"wires": [
|
|
[
|
|
"format_pump_a"
|
|
],
|
|
[],
|
|
[
|
|
"mgc_pumps"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "format_pump_a",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "format Pump A port 0",
|
|
"func": "const p = msg.payload || {};\nconst c = context.get('c') || {};\nObject.assign(c, p);\ncontext.set('c', c);\nfunction find(prefix) {\n for (const k in c) { if (k.indexOf(prefix) === 0) return c[k]; }\n return null;\n}\nconst flow = find('flow.predicted.downstream.');\nconst power = find('power.predicted.atequipment.');\nconst pU = find('pressure.measured.upstream.');\nconst pD = find('pressure.measured.downstream.');\nmsg.payload = {\n state: c.state || 'idle',\n mode: c.mode || 'auto',\n ctrl: c.ctrl != null ? Number(c.ctrl).toFixed(1) + '%' : 'n/a',\n flow: flow != null ? Number(flow).toFixed(1) + ' m\u00b3/h' : 'n/a',\n power: power != null ? Number(power).toFixed(2) + ' kW' : 'n/a',\n pUp: pU != null ? Number(pU).toFixed(0) + ' mbar' : 'n/a',\n pDn: pD != null ? Number(pD).toFixed(0) + ' mbar' : 'n/a',\n flowNum: flow != null ? Number(flow) : null,\n powerNum: power != null ? Number(power) : null,\n};\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 1160,
|
|
"y": 180,
|
|
"wires": [
|
|
[
|
|
"lout_evt_pump_a"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_evt_pump_a",
|
|
"type": "link out",
|
|
"z": "tab_process",
|
|
"name": "evt:pump-A",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_evt_pump_a_dash"
|
|
],
|
|
"x": 1420,
|
|
"y": 180,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_pump_b",
|
|
"type": "comment",
|
|
"z": "tab_process",
|
|
"name": "\u2500\u2500 Pump B \u2500\u2500",
|
|
"info": "Up + Dn pressure sensors register as children. rotatingMachine emits state on port 0 (formatted then link-out to UI). Port 2 emits registerChild \u2192 MGC.",
|
|
"x": 640,
|
|
"y": 300,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "meas_pump_b_u",
|
|
"type": "measurement",
|
|
"z": "tab_process",
|
|
"name": "PT-B-Up",
|
|
"mode": "analog",
|
|
"channels": "[]",
|
|
"scaling": false,
|
|
"i_min": 0,
|
|
"i_max": 1,
|
|
"i_offset": 0,
|
|
"o_min": 50,
|
|
"o_max": 400,
|
|
"simulator": true,
|
|
"smooth_method": "mean",
|
|
"count": "5",
|
|
"processOutputFormat": "process",
|
|
"dbaseOutputFormat": "influxdb",
|
|
"uuid": "sensor-pump_b-upstream",
|
|
"supplier": "vega",
|
|
"category": "sensor",
|
|
"assetType": "pressure",
|
|
"model": "vega-pressure-10",
|
|
"unit": "mbar",
|
|
"assetTagNumber": "PT-2-U",
|
|
"enableLog": false,
|
|
"logLevel": "warn",
|
|
"positionVsParent": "upstream",
|
|
"positionIcon": "",
|
|
"hasDistance": false,
|
|
"distance": 0,
|
|
"distanceUnit": "m",
|
|
"distanceDescription": "",
|
|
"x": 380,
|
|
"y": 340,
|
|
"wires": [
|
|
[],
|
|
[],
|
|
[
|
|
"pump_b"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "meas_pump_b_d",
|
|
"type": "measurement",
|
|
"z": "tab_process",
|
|
"name": "PT-B-Dn",
|
|
"mode": "analog",
|
|
"channels": "[]",
|
|
"scaling": false,
|
|
"i_min": 0,
|
|
"i_max": 1,
|
|
"i_offset": 0,
|
|
"o_min": 800,
|
|
"o_max": 2200,
|
|
"simulator": true,
|
|
"smooth_method": "mean",
|
|
"count": "5",
|
|
"processOutputFormat": "process",
|
|
"dbaseOutputFormat": "influxdb",
|
|
"uuid": "sensor-pump_b-downstream",
|
|
"supplier": "vega",
|
|
"category": "sensor",
|
|
"assetType": "pressure",
|
|
"model": "vega-pressure-10",
|
|
"unit": "mbar",
|
|
"assetTagNumber": "PT-2-D",
|
|
"enableLog": false,
|
|
"logLevel": "warn",
|
|
"positionVsParent": "downstream",
|
|
"positionIcon": "",
|
|
"hasDistance": false,
|
|
"distance": 0,
|
|
"distanceUnit": "m",
|
|
"distanceDescription": "",
|
|
"x": 380,
|
|
"y": 390,
|
|
"wires": [
|
|
[],
|
|
[],
|
|
[
|
|
"pump_b"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lin_setpoint_pump_b",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:setpoint-B",
|
|
"links": [
|
|
"lout_setpoint_pump_b_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 360,
|
|
"wires": [
|
|
[
|
|
"build_setpoint_pump_b"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "build_setpoint_pump_b",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "build setpoint cmd (Pump B)",
|
|
"func": "msg.topic = 'execMovement';\nmsg.payload = { source: 'GUI', action: 'execMovement', setpoint: Number(msg.payload) };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 600,
|
|
"y": 360,
|
|
"wires": [
|
|
[
|
|
"pump_b"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lin_seq_pump_b",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:pump-B-seq",
|
|
"links": [
|
|
"lout_seq_pump_b_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 410,
|
|
"wires": [
|
|
[
|
|
"pump_b"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "pump_b",
|
|
"type": "rotatingMachine",
|
|
"z": "tab_process",
|
|
"name": "Pump B",
|
|
"speed": "10",
|
|
"startup": "2",
|
|
"warmup": "1",
|
|
"shutdown": "2",
|
|
"cooldown": "1",
|
|
"movementMode": "staticspeed",
|
|
"machineCurve": "",
|
|
"uuid": "pump-pump_b",
|
|
"supplier": "hidrostal",
|
|
"category": "pump",
|
|
"assetType": "pump-centrifugal",
|
|
"model": "hidrostal-H05K-S03R",
|
|
"unit": "m3/h",
|
|
"curvePressureUnit": "mbar",
|
|
"curveFlowUnit": "m3/h",
|
|
"curvePowerUnit": "kW",
|
|
"curveControlUnit": "%",
|
|
"enableLog": false,
|
|
"logLevel": "warn",
|
|
"positionVsParent": "atEquipment",
|
|
"positionIcon": "",
|
|
"hasDistance": false,
|
|
"distance": 0,
|
|
"distanceUnit": "m",
|
|
"distanceDescription": "",
|
|
"x": 900,
|
|
"y": 380,
|
|
"wires": [
|
|
[
|
|
"format_pump_b"
|
|
],
|
|
[],
|
|
[
|
|
"mgc_pumps"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "format_pump_b",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "format Pump B port 0",
|
|
"func": "const p = msg.payload || {};\nconst c = context.get('c') || {};\nObject.assign(c, p);\ncontext.set('c', c);\nfunction find(prefix) {\n for (const k in c) { if (k.indexOf(prefix) === 0) return c[k]; }\n return null;\n}\nconst flow = find('flow.predicted.downstream.');\nconst power = find('power.predicted.atequipment.');\nconst pU = find('pressure.measured.upstream.');\nconst pD = find('pressure.measured.downstream.');\nmsg.payload = {\n state: c.state || 'idle',\n mode: c.mode || 'auto',\n ctrl: c.ctrl != null ? Number(c.ctrl).toFixed(1) + '%' : 'n/a',\n flow: flow != null ? Number(flow).toFixed(1) + ' m\u00b3/h' : 'n/a',\n power: power != null ? Number(power).toFixed(2) + ' kW' : 'n/a',\n pUp: pU != null ? Number(pU).toFixed(0) + ' mbar' : 'n/a',\n pDn: pD != null ? Number(pD).toFixed(0) + ' mbar' : 'n/a',\n flowNum: flow != null ? Number(flow) : null,\n powerNum: power != null ? Number(power) : null,\n};\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 1160,
|
|
"y": 380,
|
|
"wires": [
|
|
[
|
|
"lout_evt_pump_b"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_evt_pump_b",
|
|
"type": "link out",
|
|
"z": "tab_process",
|
|
"name": "evt:pump-B",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_evt_pump_b_dash"
|
|
],
|
|
"x": 1420,
|
|
"y": 380,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_pump_c",
|
|
"type": "comment",
|
|
"z": "tab_process",
|
|
"name": "\u2500\u2500 Pump C \u2500\u2500",
|
|
"info": "Up + Dn pressure sensors register as children. rotatingMachine emits state on port 0 (formatted then link-out to UI). Port 2 emits registerChild \u2192 MGC.",
|
|
"x": 640,
|
|
"y": 500,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "meas_pump_c_u",
|
|
"type": "measurement",
|
|
"z": "tab_process",
|
|
"name": "PT-C-Up",
|
|
"mode": "analog",
|
|
"channels": "[]",
|
|
"scaling": false,
|
|
"i_min": 0,
|
|
"i_max": 1,
|
|
"i_offset": 0,
|
|
"o_min": 50,
|
|
"o_max": 400,
|
|
"simulator": true,
|
|
"smooth_method": "mean",
|
|
"count": "5",
|
|
"processOutputFormat": "process",
|
|
"dbaseOutputFormat": "influxdb",
|
|
"uuid": "sensor-pump_c-upstream",
|
|
"supplier": "vega",
|
|
"category": "sensor",
|
|
"assetType": "pressure",
|
|
"model": "vega-pressure-10",
|
|
"unit": "mbar",
|
|
"assetTagNumber": "PT-3-U",
|
|
"enableLog": false,
|
|
"logLevel": "warn",
|
|
"positionVsParent": "upstream",
|
|
"positionIcon": "",
|
|
"hasDistance": false,
|
|
"distance": 0,
|
|
"distanceUnit": "m",
|
|
"distanceDescription": "",
|
|
"x": 380,
|
|
"y": 540,
|
|
"wires": [
|
|
[],
|
|
[],
|
|
[
|
|
"pump_c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "meas_pump_c_d",
|
|
"type": "measurement",
|
|
"z": "tab_process",
|
|
"name": "PT-C-Dn",
|
|
"mode": "analog",
|
|
"channels": "[]",
|
|
"scaling": false,
|
|
"i_min": 0,
|
|
"i_max": 1,
|
|
"i_offset": 0,
|
|
"o_min": 800,
|
|
"o_max": 2200,
|
|
"simulator": true,
|
|
"smooth_method": "mean",
|
|
"count": "5",
|
|
"processOutputFormat": "process",
|
|
"dbaseOutputFormat": "influxdb",
|
|
"uuid": "sensor-pump_c-downstream",
|
|
"supplier": "vega",
|
|
"category": "sensor",
|
|
"assetType": "pressure",
|
|
"model": "vega-pressure-10",
|
|
"unit": "mbar",
|
|
"assetTagNumber": "PT-3-D",
|
|
"enableLog": false,
|
|
"logLevel": "warn",
|
|
"positionVsParent": "downstream",
|
|
"positionIcon": "",
|
|
"hasDistance": false,
|
|
"distance": 0,
|
|
"distanceUnit": "m",
|
|
"distanceDescription": "",
|
|
"x": 380,
|
|
"y": 590,
|
|
"wires": [
|
|
[],
|
|
[],
|
|
[
|
|
"pump_c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lin_setpoint_pump_c",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:setpoint-C",
|
|
"links": [
|
|
"lout_setpoint_pump_c_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 560,
|
|
"wires": [
|
|
[
|
|
"build_setpoint_pump_c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "build_setpoint_pump_c",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "build setpoint cmd (Pump C)",
|
|
"func": "msg.topic = 'execMovement';\nmsg.payload = { source: 'GUI', action: 'execMovement', setpoint: Number(msg.payload) };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 600,
|
|
"y": 560,
|
|
"wires": [
|
|
[
|
|
"pump_c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lin_seq_pump_c",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:pump-C-seq",
|
|
"links": [
|
|
"lout_seq_pump_c_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 610,
|
|
"wires": [
|
|
[
|
|
"pump_c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "pump_c",
|
|
"type": "rotatingMachine",
|
|
"z": "tab_process",
|
|
"name": "Pump C",
|
|
"speed": "10",
|
|
"startup": "2",
|
|
"warmup": "1",
|
|
"shutdown": "2",
|
|
"cooldown": "1",
|
|
"movementMode": "staticspeed",
|
|
"machineCurve": "",
|
|
"uuid": "pump-pump_c",
|
|
"supplier": "hidrostal",
|
|
"category": "pump",
|
|
"assetType": "pump-centrifugal",
|
|
"model": "hidrostal-H05K-S03R",
|
|
"unit": "m3/h",
|
|
"curvePressureUnit": "mbar",
|
|
"curveFlowUnit": "m3/h",
|
|
"curvePowerUnit": "kW",
|
|
"curveControlUnit": "%",
|
|
"enableLog": false,
|
|
"logLevel": "warn",
|
|
"positionVsParent": "atEquipment",
|
|
"positionIcon": "",
|
|
"hasDistance": false,
|
|
"distance": 0,
|
|
"distanceUnit": "m",
|
|
"distanceDescription": "",
|
|
"x": 900,
|
|
"y": 580,
|
|
"wires": [
|
|
[
|
|
"format_pump_c"
|
|
],
|
|
[],
|
|
[
|
|
"mgc_pumps"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "format_pump_c",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "format Pump C port 0",
|
|
"func": "const p = msg.payload || {};\nconst c = context.get('c') || {};\nObject.assign(c, p);\ncontext.set('c', c);\nfunction find(prefix) {\n for (const k in c) { if (k.indexOf(prefix) === 0) return c[k]; }\n return null;\n}\nconst flow = find('flow.predicted.downstream.');\nconst power = find('power.predicted.atequipment.');\nconst pU = find('pressure.measured.upstream.');\nconst pD = find('pressure.measured.downstream.');\nmsg.payload = {\n state: c.state || 'idle',\n mode: c.mode || 'auto',\n ctrl: c.ctrl != null ? Number(c.ctrl).toFixed(1) + '%' : 'n/a',\n flow: flow != null ? Number(flow).toFixed(1) + ' m\u00b3/h' : 'n/a',\n power: power != null ? Number(power).toFixed(2) + ' kW' : 'n/a',\n pUp: pU != null ? Number(pU).toFixed(0) + ' mbar' : 'n/a',\n pDn: pD != null ? Number(pD).toFixed(0) + ' mbar' : 'n/a',\n flowNum: flow != null ? Number(flow) : null,\n powerNum: power != null ? Number(power) : null,\n};\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 1160,
|
|
"y": 580,
|
|
"wires": [
|
|
[
|
|
"lout_evt_pump_c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_evt_pump_c",
|
|
"type": "link out",
|
|
"z": "tab_process",
|
|
"name": "evt:pump-C",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_evt_pump_c_dash"
|
|
],
|
|
"x": 1420,
|
|
"y": 580,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_mgc",
|
|
"type": "comment",
|
|
"z": "tab_process",
|
|
"name": "\u2500\u2500 MGC \u2500\u2500 (orchestrates the 3 pumps via optimalcontrol)",
|
|
"info": "Receives Qd from cmd:demand link-in. Distributes flow across pumps.",
|
|
"x": 640,
|
|
"y": 700,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "mgc_pumps",
|
|
"type": "machineGroupControl",
|
|
"z": "tab_process",
|
|
"name": "MGC \u2014 Pump Group",
|
|
"uuid": "mgc-pump-group",
|
|
"category": "controller",
|
|
"assetType": "machinegroupcontrol",
|
|
"model": "default",
|
|
"unit": "m3/h",
|
|
"supplier": "evolv",
|
|
"enableLog": false,
|
|
"logLevel": "warn",
|
|
"positionVsParent": "atEquipment",
|
|
"positionIcon": "",
|
|
"hasDistance": false,
|
|
"distance": 0,
|
|
"distanceUnit": "m",
|
|
"distanceDescription": "",
|
|
"processOutputFormat": "process",
|
|
"dbaseOutputFormat": "influxdb",
|
|
"x": 900,
|
|
"y": 780,
|
|
"wires": [
|
|
[
|
|
"format_mgc"
|
|
],
|
|
[],
|
|
[
|
|
"ps_basin"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "format_mgc",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "format MGC port 0",
|
|
"func": "const p = msg.payload || {};\nconst c = context.get('c') || {};\nObject.assign(c, p);\ncontext.set('c', c);\nfunction find(prefix) {\n for (const k in c) { if (k.indexOf(prefix) === 0) return c[k]; }\n return null;\n}\nconst totalFlow = find('flow.predicted.atequipment.') ?? find('downstream_predicted_flow');\nconst totalPower = find('power.predicted.atequipment.') ?? find('atEquipment_predicted_power');\nconst eff = find('efficiency.predicted.atequipment.');\nmsg.payload = {\n totalFlow: totalFlow != null ? Number(totalFlow).toFixed(1) + ' m\u00b3/h' : 'n/a',\n totalPower: totalPower != null ? Number(totalPower).toFixed(2) + ' kW' : 'n/a',\n efficiency: eff != null ? Number(eff).toFixed(3) : 'n/a',\n totalFlowNum: totalFlow != null ? Number(totalFlow) : null,\n totalPowerNum: totalPower != null ? Number(totalPower) : null,\n};\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 1160,
|
|
"y": 780,
|
|
"wires": [
|
|
[
|
|
"lout_evt_mgc"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_evt_mgc",
|
|
"type": "link out",
|
|
"z": "tab_process",
|
|
"name": "evt:mgc",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_evt_mgc_dash"
|
|
],
|
|
"x": 1420,
|
|
"y": 780,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_ps",
|
|
"type": "comment",
|
|
"z": "tab_process",
|
|
"name": "\u2500\u2500 Pumping Station \u2500\u2500 (basin model, levelbased control)",
|
|
"info": "Receives q_in (simulated inflow) from Demo Drivers tab.\nLevel-based control starts/stops pumps via MGC when level crosses start/stop thresholds.",
|
|
"x": 640,
|
|
"y": 900,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "lin_qin_at_ps",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:q_in",
|
|
"links": [
|
|
"lout_qin_drivers"
|
|
],
|
|
"x": 120,
|
|
"y": 940,
|
|
"wires": [
|
|
[
|
|
"ps_basin"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lin_qd_at_ps",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:Qd",
|
|
"links": [
|
|
"lout_demand_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 980,
|
|
"wires": [
|
|
[
|
|
"qd_to_ps_wrap"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "qd_to_ps_wrap",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "wrap slider \u2192 PS Qd",
|
|
"func": "msg.topic = 'Qd';\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 380,
|
|
"y": 980,
|
|
"wires": [
|
|
[
|
|
"ps_basin"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lin_ps_mode_at_ps",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:ps-mode",
|
|
"links": [
|
|
"lout_ps_mode_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 1020,
|
|
"wires": [
|
|
[
|
|
"ps_basin"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "ps_basin",
|
|
"type": "pumpingStation",
|
|
"z": "tab_process",
|
|
"name": "Pumping Station",
|
|
"uuid": "ps-basin-1",
|
|
"category": "station",
|
|
"assetType": "pumpingstation",
|
|
"model": "default",
|
|
"unit": "m3/s",
|
|
"supplier": "evolv",
|
|
"enableLog": false,
|
|
"logLevel": "warn",
|
|
"positionVsParent": "atEquipment",
|
|
"positionIcon": "",
|
|
"hasDistance": false,
|
|
"distance": 0,
|
|
"distanceUnit": "m",
|
|
"distanceDescription": "",
|
|
"processOutputFormat": "process",
|
|
"dbaseOutputFormat": "influxdb",
|
|
"controlMode": "levelbased",
|
|
"basinVolume": 10,
|
|
"basinHeight": 3,
|
|
"startLevel": 1.2,
|
|
"stopLevel": 0.6,
|
|
"minFlowLevel": 0.6,
|
|
"maxFlowLevel": 2.8,
|
|
"heightInlet": 2.5,
|
|
"heightOutlet": 0.2,
|
|
"heightOverflow": 2.8,
|
|
"enableDryRunProtection": true,
|
|
"enableOverfillProtection": true,
|
|
"dryRunThresholdPercent": 5,
|
|
"overfillThresholdPercent": 95,
|
|
"timeleftToFullOrEmptyThresholdSeconds": 0,
|
|
"x": 900,
|
|
"y": 980,
|
|
"wires": [
|
|
[
|
|
"format_ps"
|
|
],
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "format_ps",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "format PS port 0",
|
|
"func": "const p = msg.payload || {};\nconst c = context.get('c') || {};\nObject.assign(c, p);\ncontext.set('c', c);\nfunction find(prefix) {\n for (const k in c) { if (k.indexOf(prefix) === 0) return c[k]; }\n return null;\n}\nconst lvl = find('level.predicted.');\nconst vol = find('volume.predicted.');\nconst qIn = find('flow.measured.upstream.') || find('flow.measured.in.');\nconst qOut = find('flow.measured.downstream.') || find('flow.measured.out.');\n// Compute derived metrics\nconst maxVol = 9.33; // must match basinVolume * basinHeight / basinHeight = basinVolume / surfaceArea * height\nconst fillPct = vol != null ? Math.round(Number(vol) / maxVol * 100) : null;\nconst netM3h = (c.netFlow != null) ? Number(c.netFlow) * 3600 : null;\nconst seconds = (c.seconds != null && Number.isFinite(Number(c.seconds))) ? Number(c.seconds) : null;\nconst timeStr = seconds != null ? (seconds > 60 ? Math.round(seconds/60) + ' min' : Math.round(seconds) + ' s') : 'n/a';\nmsg.payload = {\n direction: c.direction || 'steady',\n level: lvl != null ? Number(lvl).toFixed(2) + ' m' : 'n/a',\n volume: vol != null ? Number(vol).toFixed(1) + ' m\u00b3' : 'n/a',\n fillPct: fillPct != null ? fillPct + '%' : 'n/a',\n netFlow: netM3h != null ? netM3h.toFixed(0) + ' m\u00b3/h' : 'n/a',\n timeLeft: timeStr,\n qIn: qIn != null ? (Number(qIn) * 3600).toFixed(0) + ' m\u00b3/h' : 'n/a',\n qOut: qOut != null ? (Number(qOut) * 3600).toFixed(0) + ' m\u00b3/h' : 'n/a',\n // Numerics for trends\n levelNum: lvl != null ? Number(lvl) : null,\n volumeNum: vol != null ? Number(vol) : null,\n fillPctNum: fillPct,\n netFlowNum: netM3h,\n};\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 1160,
|
|
"y": 980,
|
|
"wires": [
|
|
[
|
|
"lout_evt_ps"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_evt_ps",
|
|
"type": "link out",
|
|
"z": "tab_process",
|
|
"name": "evt:ps",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_evt_ps_dash"
|
|
],
|
|
"x": 1420,
|
|
"y": 980,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_mode_bcast",
|
|
"type": "comment",
|
|
"z": "tab_process",
|
|
"name": "\u2500\u2500 Mode broadcast \u2500\u2500",
|
|
"info": "Single 'auto' / 'virtualControl' value fans out as setMode to all 3 pumps.",
|
|
"x": 640,
|
|
"y": 1100,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "lin_mode",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:mode",
|
|
"links": [
|
|
"lout_mode_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 1160,
|
|
"wires": [
|
|
[
|
|
"fanout_mode"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "fanout_mode",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "fan setMode \u2192 3 pumps",
|
|
"func": "msg.topic = 'setMode';\nreturn [msg, msg, msg];",
|
|
"outputs": 3,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 600,
|
|
"y": 1160,
|
|
"wires": [
|
|
[
|
|
"pump_a"
|
|
],
|
|
[
|
|
"pump_b"
|
|
],
|
|
[
|
|
"pump_c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "c_station_cmds",
|
|
"type": "comment",
|
|
"z": "tab_process",
|
|
"name": "\u2500\u2500 Station-wide commands \u2500\u2500 (Start All / Stop All / Emergency)",
|
|
"info": "Each link-in carries a fully-built msg ready for handleInput; we just fan out 3-way.",
|
|
"x": 640,
|
|
"y": 1300,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "lin_station_start",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:station-startup",
|
|
"links": [
|
|
"lout_cmd_station_startup_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 1360,
|
|
"wires": [
|
|
[
|
|
"fan_station_start"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "fan_station_start",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "fan startup \u2192 3 pumps",
|
|
"func": "return [msg, msg, msg];",
|
|
"outputs": 3,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 600,
|
|
"y": 1360,
|
|
"wires": [
|
|
[
|
|
"pump_a"
|
|
],
|
|
[
|
|
"pump_b"
|
|
],
|
|
[
|
|
"pump_c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lin_station_stop",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:station-shutdown",
|
|
"links": [
|
|
"lout_cmd_station_shutdown_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 1420,
|
|
"wires": [
|
|
[
|
|
"fan_station_stop"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "fan_station_stop",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "fan shutdown \u2192 3 pumps",
|
|
"func": "return [msg, msg, msg];",
|
|
"outputs": 3,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 600,
|
|
"y": 1420,
|
|
"wires": [
|
|
[
|
|
"pump_a"
|
|
],
|
|
[
|
|
"pump_b"
|
|
],
|
|
[
|
|
"pump_c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lin_station_estop",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "cmd:station-estop",
|
|
"links": [
|
|
"lout_cmd_station_estop_dash"
|
|
],
|
|
"x": 120,
|
|
"y": 1480,
|
|
"wires": [
|
|
[
|
|
"fan_station_estop"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "fan_station_estop",
|
|
"type": "function",
|
|
"z": "tab_process",
|
|
"name": "fan emergency stop \u2192 3 pumps",
|
|
"func": "return [msg, msg, msg];",
|
|
"outputs": 3,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 600,
|
|
"y": 1480,
|
|
"wires": [
|
|
[
|
|
"pump_a"
|
|
],
|
|
[
|
|
"pump_b"
|
|
],
|
|
[
|
|
"pump_c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "c_setup_at_mgc",
|
|
"type": "comment",
|
|
"z": "tab_process",
|
|
"name": "\u2500\u2500 Setup feeders \u2500\u2500",
|
|
"info": "Cross-tab link from Setup tab \u2192 MGC scaling/mode init.",
|
|
"x": 640,
|
|
"y": 1500,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "lin_setup_at_mgc",
|
|
"type": "link in",
|
|
"z": "tab_process",
|
|
"name": "setup:to-mgc",
|
|
"links": [
|
|
"lout_setup_to_mgc"
|
|
],
|
|
"x": 120,
|
|
"y": 1560,
|
|
"wires": [
|
|
[
|
|
"mgc_pumps"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "tab_ui",
|
|
"type": "tab",
|
|
"label": "\ud83d\udcca Dashboard UI",
|
|
"disabled": false,
|
|
"info": "Every ui-* widget lives here. Inputs (sliders/switches/buttons) emit via link-out; status text + charts receive via link-in. No business logic on this tab."
|
|
},
|
|
{
|
|
"id": "ui_base_ps_demo",
|
|
"type": "ui-base",
|
|
"name": "EVOLV Demo",
|
|
"path": "/dashboard",
|
|
"appIcon": "",
|
|
"includeClientData": true,
|
|
"acceptsClientConfig": [
|
|
"ui-notification",
|
|
"ui-control"
|
|
],
|
|
"showPathInSidebar": true,
|
|
"headerContent": "page",
|
|
"navigationStyle": "default",
|
|
"titleBarStyle": "default"
|
|
},
|
|
{
|
|
"id": "ui_theme_ps_demo",
|
|
"type": "ui-theme",
|
|
"name": "EVOLV Theme",
|
|
"colors": {
|
|
"surface": "#ffffff",
|
|
"primary": "#0f52a5",
|
|
"bgPage": "#f4f6fa",
|
|
"groupBg": "#ffffff",
|
|
"groupOutline": "#cccccc"
|
|
},
|
|
"sizes": {
|
|
"density": "default",
|
|
"pagePadding": "12px",
|
|
"groupGap": "12px",
|
|
"groupBorderRadius": "6px",
|
|
"widgetGap": "8px"
|
|
}
|
|
},
|
|
{
|
|
"id": "ui_page_control",
|
|
"type": "ui-page",
|
|
"name": "Control",
|
|
"ui": "ui_base_ps_demo",
|
|
"path": "/pumping-station-demo",
|
|
"icon": "water_pump",
|
|
"layout": "grid",
|
|
"theme": "ui_theme_ps_demo",
|
|
"breakpoints": [
|
|
{
|
|
"name": "Default",
|
|
"px": "0",
|
|
"cols": "12"
|
|
}
|
|
],
|
|
"order": 1,
|
|
"className": ""
|
|
},
|
|
{
|
|
"id": "ui_page_short_trends",
|
|
"type": "ui-page",
|
|
"name": "Trends \u2014 10 min",
|
|
"ui": "ui_base_ps_demo",
|
|
"path": "/pumping-station-demo/trends-short",
|
|
"icon": "show_chart",
|
|
"layout": "grid",
|
|
"theme": "ui_theme_ps_demo",
|
|
"breakpoints": [
|
|
{
|
|
"name": "Default",
|
|
"px": "0",
|
|
"cols": "12"
|
|
}
|
|
],
|
|
"order": 2,
|
|
"className": ""
|
|
},
|
|
{
|
|
"id": "ui_page_long_trends",
|
|
"type": "ui-page",
|
|
"name": "Trends \u2014 1 hour",
|
|
"ui": "ui_base_ps_demo",
|
|
"path": "/pumping-station-demo/trends-long",
|
|
"icon": "timeline",
|
|
"layout": "grid",
|
|
"theme": "ui_theme_ps_demo",
|
|
"breakpoints": [
|
|
{
|
|
"name": "Default",
|
|
"px": "0",
|
|
"cols": "12"
|
|
}
|
|
],
|
|
"order": 3,
|
|
"className": ""
|
|
},
|
|
{
|
|
"id": "ui_grp_demand",
|
|
"type": "ui-group",
|
|
"name": "1. Process Demand",
|
|
"page": "ui_page_control",
|
|
"width": "12",
|
|
"height": "1",
|
|
"order": 1,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_station",
|
|
"type": "ui-group",
|
|
"name": "2. Station Controls",
|
|
"page": "ui_page_control",
|
|
"width": "12",
|
|
"height": "1",
|
|
"order": 2,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_mgc",
|
|
"type": "ui-group",
|
|
"name": "3a. MGC Status",
|
|
"page": "ui_page_control",
|
|
"width": "6",
|
|
"height": "1",
|
|
"order": 3,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_ps",
|
|
"type": "ui-group",
|
|
"name": "3b. Basin Status",
|
|
"page": "ui_page_control",
|
|
"width": "6",
|
|
"height": "1",
|
|
"order": 4,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_pump_a",
|
|
"type": "ui-group",
|
|
"name": "4a. Pump A",
|
|
"page": "ui_page_control",
|
|
"width": "4",
|
|
"height": "1",
|
|
"order": 5,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_pump_b",
|
|
"type": "ui-group",
|
|
"name": "4b. Pump B",
|
|
"page": "ui_page_control",
|
|
"width": "4",
|
|
"height": "1",
|
|
"order": 6,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_pump_c",
|
|
"type": "ui-group",
|
|
"name": "4c. Pump C",
|
|
"page": "ui_page_control",
|
|
"width": "4",
|
|
"height": "1",
|
|
"order": 7,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_trend_short_flow",
|
|
"type": "ui-group",
|
|
"name": "Flow (10 min)",
|
|
"page": "ui_page_short_trends",
|
|
"width": "12",
|
|
"height": "1",
|
|
"order": 1,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_trend_short_power",
|
|
"type": "ui-group",
|
|
"name": "Power (10 min)",
|
|
"page": "ui_page_short_trends",
|
|
"width": "12",
|
|
"height": "1",
|
|
"order": 2,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_trend_short_basin",
|
|
"type": "ui-group",
|
|
"name": "Basin (10 min)",
|
|
"page": "ui_page_short_trends",
|
|
"width": "12",
|
|
"height": "1",
|
|
"order": 3,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_trend_long_flow",
|
|
"type": "ui-group",
|
|
"name": "Flow (1 hour)",
|
|
"page": "ui_page_long_trends",
|
|
"width": "12",
|
|
"height": "1",
|
|
"order": 1,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_trend_long_power",
|
|
"type": "ui-group",
|
|
"name": "Power (1 hour)",
|
|
"page": "ui_page_long_trends",
|
|
"width": "12",
|
|
"height": "1",
|
|
"order": 2,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "ui_grp_trend_long_basin",
|
|
"type": "ui-group",
|
|
"name": "Basin (1 hour)",
|
|
"page": "ui_page_long_trends",
|
|
"width": "12",
|
|
"height": "1",
|
|
"order": 3,
|
|
"showTitle": true,
|
|
"className": "",
|
|
"groupType": "default",
|
|
"disabled": false,
|
|
"visible": true
|
|
},
|
|
{
|
|
"id": "c_ui_title",
|
|
"type": "comment",
|
|
"z": "tab_ui",
|
|
"name": "\ud83d\udcca DASHBOARD UI \u2014 only ui-* widgets here",
|
|
"info": "Layout: column 1 = inputs (sliders/switches/buttons) \u2192 link-outs.\nColumn 2 = link-ins from process \u2192 routed to text/gauge/chart widgets.",
|
|
"x": 640,
|
|
"y": 20,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_ui_demand",
|
|
"type": "comment",
|
|
"z": "tab_ui",
|
|
"name": "\u2500\u2500 Process Demand \u2500\u2500",
|
|
"info": "",
|
|
"x": 640,
|
|
"y": 100,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_demand_slider",
|
|
"type": "ui-slider",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_demand",
|
|
"name": "Manual demand (manual mode only)",
|
|
"label": "Manual demand (m\u00b3/h) \u2014 active in manual mode only",
|
|
"tooltip": "",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"passthru": true,
|
|
"outs": "end",
|
|
"topic": "manualDemand",
|
|
"topicType": "str",
|
|
"min": "0",
|
|
"max": "100",
|
|
"step": "5.0",
|
|
"showLabel": true,
|
|
"showValue": true,
|
|
"labelPosition": "top",
|
|
"valuePosition": "left",
|
|
"thumbLabel": false,
|
|
"iconStart": "",
|
|
"iconEnd": "",
|
|
"x": 120,
|
|
"y": 140,
|
|
"wires": [
|
|
[
|
|
"lout_demand_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_demand_dash",
|
|
"type": "link out",
|
|
"z": "tab_ui",
|
|
"name": "cmd:Qd",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_qd_at_ps"
|
|
],
|
|
"x": 380,
|
|
"y": 140,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_demand_text",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_demand",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Manual demand (active in manual mode)",
|
|
"label": "Manual demand",
|
|
"format": "{{msg.payload}} m\u00b3/h",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 900,
|
|
"y": 140,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_ui_station",
|
|
"type": "comment",
|
|
"z": "tab_ui",
|
|
"name": "\u2500\u2500 Mode + Station-wide buttons \u2500\u2500",
|
|
"info": "",
|
|
"x": 640,
|
|
"y": 320,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_mode_toggle",
|
|
"type": "ui-switch",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_station",
|
|
"name": "Station mode",
|
|
"label": "Station mode (Auto = level-based control \u00b7 Manual = slider demand)",
|
|
"tooltip": "",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"passthru": true,
|
|
"decouple": "false",
|
|
"topic": "changemode",
|
|
"topicType": "str",
|
|
"style": "",
|
|
"className": "",
|
|
"evaluate": "true",
|
|
"onvalue": "levelbased",
|
|
"onvalueType": "str",
|
|
"onicon": "auto_mode",
|
|
"oncolor": "#0f52a5",
|
|
"offvalue": "manual",
|
|
"offvalueType": "str",
|
|
"officon": "back_hand",
|
|
"offcolor": "#888888",
|
|
"x": 120,
|
|
"y": 360,
|
|
"wires": [
|
|
[
|
|
"lout_ps_mode_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_ps_mode_dash",
|
|
"type": "link out",
|
|
"z": "tab_ui",
|
|
"name": "cmd:ps-mode",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_ps_mode_at_ps"
|
|
],
|
|
"x": 380,
|
|
"y": 360,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "btn_station_0",
|
|
"type": "ui-button",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_station",
|
|
"name": "Start all pumps",
|
|
"label": "Start all pumps",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"tooltip": "",
|
|
"color": "#ffffff",
|
|
"bgcolor": "#16a34a",
|
|
"className": "",
|
|
"icon": "play_arrow",
|
|
"iconPosition": "left",
|
|
"payload": "fired",
|
|
"payloadType": "str",
|
|
"topic": "station_0",
|
|
"topicType": "str",
|
|
"buttonType": "default",
|
|
"x": 120,
|
|
"y": 420,
|
|
"wires": [
|
|
[
|
|
"wrap_station_0"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "wrap_station_0",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "build cmd (Start all pumps)",
|
|
"func": "msg.topic = 'execSequence';\nmsg.payload = { source:'GUI', action:'execSequence', parameter:'startup' };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 480,
|
|
"y": 420,
|
|
"wires": [
|
|
[
|
|
"lout_cmd_station_startup_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_cmd_station_startup_dash",
|
|
"type": "link out",
|
|
"z": "tab_ui",
|
|
"name": "cmd:station-startup",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_station_start"
|
|
],
|
|
"x": 640,
|
|
"y": 420,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "btn_station_1",
|
|
"type": "ui-button",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_station",
|
|
"name": "Stop all pumps",
|
|
"label": "Stop all pumps",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"tooltip": "",
|
|
"color": "#ffffff",
|
|
"bgcolor": "#ea580c",
|
|
"className": "",
|
|
"icon": "stop",
|
|
"iconPosition": "left",
|
|
"payload": "fired",
|
|
"payloadType": "str",
|
|
"topic": "station_1",
|
|
"topicType": "str",
|
|
"buttonType": "default",
|
|
"x": 120,
|
|
"y": 480,
|
|
"wires": [
|
|
[
|
|
"wrap_station_1"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "wrap_station_1",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "build cmd (Stop all pumps)",
|
|
"func": "msg.topic = 'execSequence';\nmsg.payload = { source:'GUI', action:'execSequence', parameter:'shutdown' };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 480,
|
|
"y": 480,
|
|
"wires": [
|
|
[
|
|
"lout_cmd_station_shutdown_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_cmd_station_shutdown_dash",
|
|
"type": "link out",
|
|
"z": "tab_ui",
|
|
"name": "cmd:station-shutdown",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_station_stop"
|
|
],
|
|
"x": 640,
|
|
"y": 480,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "btn_station_2",
|
|
"type": "ui-button",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_station",
|
|
"name": "EMERGENCY STOP",
|
|
"label": "EMERGENCY STOP",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"tooltip": "",
|
|
"color": "#ffffff",
|
|
"bgcolor": "#dc2626",
|
|
"className": "",
|
|
"icon": "stop_circle",
|
|
"iconPosition": "left",
|
|
"payload": "fired",
|
|
"payloadType": "str",
|
|
"topic": "station_2",
|
|
"topicType": "str",
|
|
"buttonType": "default",
|
|
"x": 120,
|
|
"y": 540,
|
|
"wires": [
|
|
[
|
|
"wrap_station_2"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "wrap_station_2",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "build cmd (EMERGENCY STOP)",
|
|
"func": "msg.topic = 'emergencystop';\nmsg.payload = { source:'GUI', action:'emergencystop' };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 480,
|
|
"y": 540,
|
|
"wires": [
|
|
[
|
|
"lout_cmd_station_estop_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_cmd_station_estop_dash",
|
|
"type": "link out",
|
|
"z": "tab_ui",
|
|
"name": "cmd:station-estop",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_station_estop"
|
|
],
|
|
"x": 640,
|
|
"y": 540,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_ui_mgc_ps",
|
|
"type": "comment",
|
|
"z": "tab_ui",
|
|
"name": "\u2500\u2500 MGC + Basin overview \u2500\u2500",
|
|
"info": "",
|
|
"x": 640,
|
|
"y": 600,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "lin_evt_mgc_dash",
|
|
"type": "link in",
|
|
"z": "tab_ui",
|
|
"name": "evt:mgc",
|
|
"links": [
|
|
"lout_evt_mgc"
|
|
],
|
|
"x": 120,
|
|
"y": 640,
|
|
"wires": [
|
|
[
|
|
"dispatch_mgc"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "dispatch_mgc",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "dispatch MGC",
|
|
"func": "const p = msg.payload || {};\nreturn [\n {payload: String(p.totalFlow || 'n/a')},\n {payload: String(p.totalPower || 'n/a')},\n {payload: String(p.efficiency || 'n/a')},\n];",
|
|
"outputs": 3,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 380,
|
|
"y": 640,
|
|
"wires": [
|
|
[
|
|
"ui_mgc_total_flow"
|
|
],
|
|
[
|
|
"ui_mgc_total_power"
|
|
],
|
|
[
|
|
"ui_mgc_eff"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "ui_mgc_total_flow",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_mgc",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "MGC total flow",
|
|
"label": "Total flow",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 640,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_mgc_total_power",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_mgc",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "MGC total power",
|
|
"label": "Total power",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 670,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_mgc_eff",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_mgc",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "MGC efficiency",
|
|
"label": "Group efficiency",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 700,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "lin_evt_ps_dash",
|
|
"type": "link in",
|
|
"z": "tab_ui",
|
|
"name": "evt:ps",
|
|
"links": [
|
|
"lout_evt_ps"
|
|
],
|
|
"x": 120,
|
|
"y": 760,
|
|
"wires": [
|
|
[
|
|
"dispatch_ps"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "dispatch_ps",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "dispatch PS",
|
|
"func": "const p = msg.payload || {};\nconst ts = Date.now();\nreturn [\n {payload: String(p.direction || 'steady')},\n {payload: String(p.level || 'n/a')},\n {payload: String(p.volume || 'n/a')},\n {payload: String(p.fillPct || 'n/a')},\n {payload: String(p.netFlow || 'n/a')},\n {payload: String(p.timeLeft || 'n/a')},\n {payload: String(p.qIn || 'n/a')},\n // Trend numerics\n p.fillPctNum != null ? {topic: 'Basin fill', payload: p.fillPctNum, timestamp: ts} : null,\n p.levelNum != null ? {topic: 'Basin level', payload: p.levelNum, timestamp: ts} : null,\n p.netFlowNum != null ? {topic: 'Net flow', payload: p.netFlowNum,timestamp: ts} : null,\n];",
|
|
"outputs": 10,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 380,
|
|
"y": 760,
|
|
"wires": [
|
|
[
|
|
"ui_ps_direction"
|
|
],
|
|
[
|
|
"ui_ps_level"
|
|
],
|
|
[
|
|
"ui_ps_volume"
|
|
],
|
|
[
|
|
"ui_ps_fill"
|
|
],
|
|
[
|
|
"ui_ps_netflow"
|
|
],
|
|
[
|
|
"ui_ps_timeleft"
|
|
],
|
|
[
|
|
"ui_ps_qin"
|
|
],
|
|
[
|
|
"trend_short_basin",
|
|
"trend_long_basin",
|
|
"gauge_ps_fill",
|
|
"gauge_ps_fill_long"
|
|
],
|
|
[
|
|
"trend_short_basin",
|
|
"trend_long_basin",
|
|
"gauge_ps_level",
|
|
"gauge_ps_level_long"
|
|
],
|
|
[
|
|
"trend_short_basin",
|
|
"trend_long_basin"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "ui_ps_direction",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_ps",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "PS direction",
|
|
"label": "Direction",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 760,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_ps_level",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_ps",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "PS level",
|
|
"label": "Basin level",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 800,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_ps_volume",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_ps",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "PS volume",
|
|
"label": "Basin volume",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 840,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_ps_fill",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_ps",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "PS fill %",
|
|
"label": "Fill level",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 880,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_ps_netflow",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_ps",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "PS net flow",
|
|
"label": "Net flow",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 920,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_ps_timeleft",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_ps",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "PS time left",
|
|
"label": "Time to full/empty",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 960,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_ps_qin",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_ps",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "PS Qin",
|
|
"label": "Inflow",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1000,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_ui_pump_a",
|
|
"type": "comment",
|
|
"z": "tab_ui",
|
|
"name": "\u2500\u2500 Pump A \u2500\u2500",
|
|
"info": "",
|
|
"x": 640,
|
|
"y": 1000,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "lin_evt_pump_a_dash",
|
|
"type": "link in",
|
|
"z": "tab_ui",
|
|
"name": "evt:pump-A",
|
|
"links": [
|
|
"lout_evt_pump_a"
|
|
],
|
|
"x": 120,
|
|
"y": 1040,
|
|
"wires": [
|
|
[
|
|
"dispatch_pump_a"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "dispatch_pump_a",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "dispatch Pump A",
|
|
"func": "const p = msg.payload || {};\nconst ts = Date.now();\nreturn [\n {payload: String(p.state || 'idle')},\n {payload: String(p.mode || 'auto')},\n {payload: String(p.ctrl || 'n/a')},\n {payload: String(p.flow || 'n/a')},\n {payload: String(p.power || 'n/a')},\n {payload: String(p.pUp || 'n/a')},\n {payload: String(p.pDn || 'n/a')},\n p.flowNum != null ? {topic: 'Pump A', payload: p.flowNum, timestamp: ts} : null,\n p.powerNum != null ? {topic: 'Pump A', payload: p.powerNum, timestamp: ts} : null,\n];",
|
|
"outputs": 9,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 380,
|
|
"y": 1040,
|
|
"wires": [
|
|
[
|
|
"ui_pump_a_state"
|
|
],
|
|
[
|
|
"ui_pump_a_mode"
|
|
],
|
|
[
|
|
"ui_pump_a_ctrl"
|
|
],
|
|
[
|
|
"ui_pump_a_flow"
|
|
],
|
|
[
|
|
"ui_pump_a_power"
|
|
],
|
|
[
|
|
"ui_pump_a_pUp"
|
|
],
|
|
[
|
|
"ui_pump_a_pDn"
|
|
],
|
|
[
|
|
"trend_short_flow",
|
|
"trend_long_flow"
|
|
],
|
|
[
|
|
"trend_short_power",
|
|
"trend_long_power"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "ui_pump_a_state",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_a",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump A State",
|
|
"label": "State",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1040,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_a_mode",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_a",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump A Mode",
|
|
"label": "Mode",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1080,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_a_ctrl",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_a",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump A Controller %",
|
|
"label": "Controller %",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1120,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_a_flow",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_a",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump A Flow",
|
|
"label": "Flow",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1160,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_a_power",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_a",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump A Power",
|
|
"label": "Power",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1200,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_a_pUp",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_a",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump A p Upstream",
|
|
"label": "p Upstream",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1240,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_a_pDn",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_a",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump A p Downstream",
|
|
"label": "p Downstream",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1280,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_a_setpoint",
|
|
"type": "ui-slider",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_a",
|
|
"name": "Pump A setpoint",
|
|
"label": "Setpoint % (manual mode)",
|
|
"tooltip": "",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"passthru": true,
|
|
"outs": "end",
|
|
"topic": "setpoint_pump_a",
|
|
"topicType": "str",
|
|
"min": "0",
|
|
"max": "100",
|
|
"step": "5.0",
|
|
"showLabel": true,
|
|
"showValue": true,
|
|
"labelPosition": "top",
|
|
"valuePosition": "left",
|
|
"thumbLabel": false,
|
|
"iconStart": "",
|
|
"iconEnd": "",
|
|
"x": 120,
|
|
"y": 1280,
|
|
"wires": [
|
|
[
|
|
"lout_setpoint_pump_a_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_setpoint_pump_a_dash",
|
|
"type": "link out",
|
|
"z": "tab_ui",
|
|
"name": "cmd:setpoint-A",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_setpoint_pump_a"
|
|
],
|
|
"x": 380,
|
|
"y": 1280,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "btn_pump_a_start",
|
|
"type": "ui-button",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_a",
|
|
"name": "Pump A startup",
|
|
"label": "Startup",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"tooltip": "",
|
|
"color": "#ffffff",
|
|
"bgcolor": "#16a34a",
|
|
"className": "",
|
|
"icon": "play_arrow",
|
|
"iconPosition": "left",
|
|
"payload": "fired",
|
|
"payloadType": "str",
|
|
"topic": "start_pump_a",
|
|
"topicType": "str",
|
|
"buttonType": "default",
|
|
"x": 120,
|
|
"y": 1330,
|
|
"wires": [
|
|
[
|
|
"wrap_pump_a_start"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "wrap_pump_a_start",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "build start (Pump A)",
|
|
"func": "msg.topic = 'execSequence';\nmsg.payload = { source:'GUI', action:'execSequence', parameter:'startup' };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 480,
|
|
"y": 1330,
|
|
"wires": [
|
|
[
|
|
"lout_seq_pump_a_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "btn_pump_a_stop",
|
|
"type": "ui-button",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_a",
|
|
"name": "Pump A shutdown",
|
|
"label": "Shutdown",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"tooltip": "",
|
|
"color": "#ffffff",
|
|
"bgcolor": "#ea580c",
|
|
"className": "",
|
|
"icon": "stop",
|
|
"iconPosition": "left",
|
|
"payload": "fired",
|
|
"payloadType": "str",
|
|
"topic": "stop_pump_a",
|
|
"topicType": "str",
|
|
"buttonType": "default",
|
|
"x": 120,
|
|
"y": 1380,
|
|
"wires": [
|
|
[
|
|
"wrap_pump_a_stop"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "wrap_pump_a_stop",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "build stop (Pump A)",
|
|
"func": "msg.topic = 'execSequence';\nmsg.payload = { source:'GUI', action:'execSequence', parameter:'shutdown' };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 480,
|
|
"y": 1380,
|
|
"wires": [
|
|
[
|
|
"lout_seq_pump_a_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_seq_pump_a_dash",
|
|
"type": "link out",
|
|
"z": "tab_ui",
|
|
"name": "cmd:pump-A-seq",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_seq_pump_a"
|
|
],
|
|
"x": 640,
|
|
"y": 1355,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_ui_pump_b",
|
|
"type": "comment",
|
|
"z": "tab_ui",
|
|
"name": "\u2500\u2500 Pump B \u2500\u2500",
|
|
"info": "",
|
|
"x": 640,
|
|
"y": 1400,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "lin_evt_pump_b_dash",
|
|
"type": "link in",
|
|
"z": "tab_ui",
|
|
"name": "evt:pump-B",
|
|
"links": [
|
|
"lout_evt_pump_b"
|
|
],
|
|
"x": 120,
|
|
"y": 1440,
|
|
"wires": [
|
|
[
|
|
"dispatch_pump_b"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "dispatch_pump_b",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "dispatch Pump B",
|
|
"func": "const p = msg.payload || {};\nconst ts = Date.now();\nreturn [\n {payload: String(p.state || 'idle')},\n {payload: String(p.mode || 'auto')},\n {payload: String(p.ctrl || 'n/a')},\n {payload: String(p.flow || 'n/a')},\n {payload: String(p.power || 'n/a')},\n {payload: String(p.pUp || 'n/a')},\n {payload: String(p.pDn || 'n/a')},\n p.flowNum != null ? {topic: 'Pump B', payload: p.flowNum, timestamp: ts} : null,\n p.powerNum != null ? {topic: 'Pump B', payload: p.powerNum, timestamp: ts} : null,\n];",
|
|
"outputs": 9,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 380,
|
|
"y": 1440,
|
|
"wires": [
|
|
[
|
|
"ui_pump_b_state"
|
|
],
|
|
[
|
|
"ui_pump_b_mode"
|
|
],
|
|
[
|
|
"ui_pump_b_ctrl"
|
|
],
|
|
[
|
|
"ui_pump_b_flow"
|
|
],
|
|
[
|
|
"ui_pump_b_power"
|
|
],
|
|
[
|
|
"ui_pump_b_pUp"
|
|
],
|
|
[
|
|
"ui_pump_b_pDn"
|
|
],
|
|
[
|
|
"trend_short_flow",
|
|
"trend_long_flow"
|
|
],
|
|
[
|
|
"trend_short_power",
|
|
"trend_long_power"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "ui_pump_b_state",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_b",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump B State",
|
|
"label": "State",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1440,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_b_mode",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_b",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump B Mode",
|
|
"label": "Mode",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1480,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_b_ctrl",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_b",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump B Controller %",
|
|
"label": "Controller %",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1520,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_b_flow",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_b",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump B Flow",
|
|
"label": "Flow",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1560,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_b_power",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_b",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump B Power",
|
|
"label": "Power",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1600,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_b_pUp",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_b",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump B p Upstream",
|
|
"label": "p Upstream",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1640,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_b_pDn",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_b",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump B p Downstream",
|
|
"label": "p Downstream",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1680,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_b_setpoint",
|
|
"type": "ui-slider",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_b",
|
|
"name": "Pump B setpoint",
|
|
"label": "Setpoint % (manual mode)",
|
|
"tooltip": "",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"passthru": true,
|
|
"outs": "end",
|
|
"topic": "setpoint_pump_b",
|
|
"topicType": "str",
|
|
"min": "0",
|
|
"max": "100",
|
|
"step": "5.0",
|
|
"showLabel": true,
|
|
"showValue": true,
|
|
"labelPosition": "top",
|
|
"valuePosition": "left",
|
|
"thumbLabel": false,
|
|
"iconStart": "",
|
|
"iconEnd": "",
|
|
"x": 120,
|
|
"y": 1680,
|
|
"wires": [
|
|
[
|
|
"lout_setpoint_pump_b_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_setpoint_pump_b_dash",
|
|
"type": "link out",
|
|
"z": "tab_ui",
|
|
"name": "cmd:setpoint-B",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_setpoint_pump_b"
|
|
],
|
|
"x": 380,
|
|
"y": 1680,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "btn_pump_b_start",
|
|
"type": "ui-button",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_b",
|
|
"name": "Pump B startup",
|
|
"label": "Startup",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"tooltip": "",
|
|
"color": "#ffffff",
|
|
"bgcolor": "#16a34a",
|
|
"className": "",
|
|
"icon": "play_arrow",
|
|
"iconPosition": "left",
|
|
"payload": "fired",
|
|
"payloadType": "str",
|
|
"topic": "start_pump_b",
|
|
"topicType": "str",
|
|
"buttonType": "default",
|
|
"x": 120,
|
|
"y": 1730,
|
|
"wires": [
|
|
[
|
|
"wrap_pump_b_start"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "wrap_pump_b_start",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "build start (Pump B)",
|
|
"func": "msg.topic = 'execSequence';\nmsg.payload = { source:'GUI', action:'execSequence', parameter:'startup' };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 480,
|
|
"y": 1730,
|
|
"wires": [
|
|
[
|
|
"lout_seq_pump_b_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "btn_pump_b_stop",
|
|
"type": "ui-button",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_b",
|
|
"name": "Pump B shutdown",
|
|
"label": "Shutdown",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"tooltip": "",
|
|
"color": "#ffffff",
|
|
"bgcolor": "#ea580c",
|
|
"className": "",
|
|
"icon": "stop",
|
|
"iconPosition": "left",
|
|
"payload": "fired",
|
|
"payloadType": "str",
|
|
"topic": "stop_pump_b",
|
|
"topicType": "str",
|
|
"buttonType": "default",
|
|
"x": 120,
|
|
"y": 1780,
|
|
"wires": [
|
|
[
|
|
"wrap_pump_b_stop"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "wrap_pump_b_stop",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "build stop (Pump B)",
|
|
"func": "msg.topic = 'execSequence';\nmsg.payload = { source:'GUI', action:'execSequence', parameter:'shutdown' };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 480,
|
|
"y": 1780,
|
|
"wires": [
|
|
[
|
|
"lout_seq_pump_b_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_seq_pump_b_dash",
|
|
"type": "link out",
|
|
"z": "tab_ui",
|
|
"name": "cmd:pump-B-seq",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_seq_pump_b"
|
|
],
|
|
"x": 640,
|
|
"y": 1755,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_ui_pump_c",
|
|
"type": "comment",
|
|
"z": "tab_ui",
|
|
"name": "\u2500\u2500 Pump C \u2500\u2500",
|
|
"info": "",
|
|
"x": 640,
|
|
"y": 1800,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "lin_evt_pump_c_dash",
|
|
"type": "link in",
|
|
"z": "tab_ui",
|
|
"name": "evt:pump-C",
|
|
"links": [
|
|
"lout_evt_pump_c"
|
|
],
|
|
"x": 120,
|
|
"y": 1840,
|
|
"wires": [
|
|
[
|
|
"dispatch_pump_c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "dispatch_pump_c",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "dispatch Pump C",
|
|
"func": "const p = msg.payload || {};\nconst ts = Date.now();\nreturn [\n {payload: String(p.state || 'idle')},\n {payload: String(p.mode || 'auto')},\n {payload: String(p.ctrl || 'n/a')},\n {payload: String(p.flow || 'n/a')},\n {payload: String(p.power || 'n/a')},\n {payload: String(p.pUp || 'n/a')},\n {payload: String(p.pDn || 'n/a')},\n p.flowNum != null ? {topic: 'Pump C', payload: p.flowNum, timestamp: ts} : null,\n p.powerNum != null ? {topic: 'Pump C', payload: p.powerNum, timestamp: ts} : null,\n];",
|
|
"outputs": 9,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 380,
|
|
"y": 1840,
|
|
"wires": [
|
|
[
|
|
"ui_pump_c_state"
|
|
],
|
|
[
|
|
"ui_pump_c_mode"
|
|
],
|
|
[
|
|
"ui_pump_c_ctrl"
|
|
],
|
|
[
|
|
"ui_pump_c_flow"
|
|
],
|
|
[
|
|
"ui_pump_c_power"
|
|
],
|
|
[
|
|
"ui_pump_c_pUp"
|
|
],
|
|
[
|
|
"ui_pump_c_pDn"
|
|
],
|
|
[
|
|
"trend_short_flow",
|
|
"trend_long_flow"
|
|
],
|
|
[
|
|
"trend_short_power",
|
|
"trend_long_power"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "ui_pump_c_state",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_c",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump C State",
|
|
"label": "State",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1840,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_c_mode",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_c",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump C Mode",
|
|
"label": "Mode",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1880,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_c_ctrl",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_c",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump C Controller %",
|
|
"label": "Controller %",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1920,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_c_flow",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_c",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump C Flow",
|
|
"label": "Flow",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 1960,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_c_power",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_c",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump C Power",
|
|
"label": "Power",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 2000,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_c_pUp",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_c",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump C p Upstream",
|
|
"label": "p Upstream",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 2040,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_c_pDn",
|
|
"type": "ui-text",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_c",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"name": "Pump C p Downstream",
|
|
"label": "p Downstream",
|
|
"format": "{{msg.payload}}",
|
|
"layout": "row-left",
|
|
"style": false,
|
|
"font": "",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
"x": 640,
|
|
"y": 2080,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "ui_pump_c_setpoint",
|
|
"type": "ui-slider",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_c",
|
|
"name": "Pump C setpoint",
|
|
"label": "Setpoint % (manual mode)",
|
|
"tooltip": "",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"passthru": true,
|
|
"outs": "end",
|
|
"topic": "setpoint_pump_c",
|
|
"topicType": "str",
|
|
"min": "0",
|
|
"max": "100",
|
|
"step": "5.0",
|
|
"showLabel": true,
|
|
"showValue": true,
|
|
"labelPosition": "top",
|
|
"valuePosition": "left",
|
|
"thumbLabel": false,
|
|
"iconStart": "",
|
|
"iconEnd": "",
|
|
"x": 120,
|
|
"y": 2080,
|
|
"wires": [
|
|
[
|
|
"lout_setpoint_pump_c_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_setpoint_pump_c_dash",
|
|
"type": "link out",
|
|
"z": "tab_ui",
|
|
"name": "cmd:setpoint-C",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_setpoint_pump_c"
|
|
],
|
|
"x": 380,
|
|
"y": 2080,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "btn_pump_c_start",
|
|
"type": "ui-button",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_c",
|
|
"name": "Pump C startup",
|
|
"label": "Startup",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"tooltip": "",
|
|
"color": "#ffffff",
|
|
"bgcolor": "#16a34a",
|
|
"className": "",
|
|
"icon": "play_arrow",
|
|
"iconPosition": "left",
|
|
"payload": "fired",
|
|
"payloadType": "str",
|
|
"topic": "start_pump_c",
|
|
"topicType": "str",
|
|
"buttonType": "default",
|
|
"x": 120,
|
|
"y": 2130,
|
|
"wires": [
|
|
[
|
|
"wrap_pump_c_start"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "wrap_pump_c_start",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "build start (Pump C)",
|
|
"func": "msg.topic = 'execSequence';\nmsg.payload = { source:'GUI', action:'execSequence', parameter:'startup' };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 480,
|
|
"y": 2130,
|
|
"wires": [
|
|
[
|
|
"lout_seq_pump_c_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "btn_pump_c_stop",
|
|
"type": "ui-button",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_pump_c",
|
|
"name": "Pump C shutdown",
|
|
"label": "Shutdown",
|
|
"order": 1,
|
|
"width": "0",
|
|
"height": "0",
|
|
"tooltip": "",
|
|
"color": "#ffffff",
|
|
"bgcolor": "#ea580c",
|
|
"className": "",
|
|
"icon": "stop",
|
|
"iconPosition": "left",
|
|
"payload": "fired",
|
|
"payloadType": "str",
|
|
"topic": "stop_pump_c",
|
|
"topicType": "str",
|
|
"buttonType": "default",
|
|
"x": 120,
|
|
"y": 2180,
|
|
"wires": [
|
|
[
|
|
"wrap_pump_c_stop"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "wrap_pump_c_stop",
|
|
"type": "function",
|
|
"z": "tab_ui",
|
|
"name": "build stop (Pump C)",
|
|
"func": "msg.topic = 'execSequence';\nmsg.payload = { source:'GUI', action:'execSequence', parameter:'shutdown' };\nreturn msg;",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 480,
|
|
"y": 2180,
|
|
"wires": [
|
|
[
|
|
"lout_seq_pump_c_dash"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_seq_pump_c_dash",
|
|
"type": "link out",
|
|
"z": "tab_ui",
|
|
"name": "cmd:pump-C-seq",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_seq_pump_c"
|
|
],
|
|
"x": 640,
|
|
"y": 2155,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_ui_trends",
|
|
"type": "comment",
|
|
"z": "tab_ui",
|
|
"name": "\u2500\u2500 Trend charts \u2500\u2500 (feed to 4 charts on 2 pages)",
|
|
"info": "Short-term (10 min) and long-term (1 h) trends share the same feed.\nEach chart on its own page.",
|
|
"x": 640,
|
|
"y": 2280,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "trend_short_flow",
|
|
"type": "ui-chart",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_trend_short_flow",
|
|
"name": "Flow per pump \u2014 10 min",
|
|
"label": "Flow per pump (m\u00b3/h)",
|
|
"order": 1,
|
|
"chartType": "line",
|
|
"interpolation": "linear",
|
|
"category": "topic",
|
|
"categoryType": "msg",
|
|
"xAxisLabel": "",
|
|
"xAxisType": "time",
|
|
"xAxisProperty": "",
|
|
"xAxisPropertyType": "timestamp",
|
|
"xAxisFormat": "",
|
|
"xAxisFormatType": "auto",
|
|
"xmin": "",
|
|
"xmax": "",
|
|
"yAxisLabel": "",
|
|
"yAxisProperty": "payload",
|
|
"yAxisPropertyType": "msg",
|
|
"ymin": "",
|
|
"ymax": "",
|
|
"removeOlder": "10",
|
|
"removeOlderUnit": "60",
|
|
"removeOlderPoints": "300",
|
|
"action": "append",
|
|
"stackSeries": false,
|
|
"pointShape": "circle",
|
|
"pointRadius": 4,
|
|
"showLegend": true,
|
|
"bins": 10,
|
|
"colors": [
|
|
"#0095FF",
|
|
"#FF0000",
|
|
"#FF7F0E",
|
|
"#2CA02C",
|
|
"#A347E1",
|
|
"#D62728",
|
|
"#FF9896",
|
|
"#9467BD",
|
|
"#C5B0D5"
|
|
],
|
|
"textColor": [
|
|
"#666666"
|
|
],
|
|
"textColorDefault": true,
|
|
"gridColor": [
|
|
"#e5e5e5"
|
|
],
|
|
"gridColorDefault": true,
|
|
"width": 12,
|
|
"height": 8,
|
|
"className": "",
|
|
"x": 900,
|
|
"y": 2320,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "trend_short_power",
|
|
"type": "ui-chart",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_trend_short_power",
|
|
"name": "Power per pump \u2014 10 min",
|
|
"label": "Power per pump (kW)",
|
|
"order": 1,
|
|
"chartType": "line",
|
|
"interpolation": "linear",
|
|
"category": "topic",
|
|
"categoryType": "msg",
|
|
"xAxisLabel": "",
|
|
"xAxisType": "time",
|
|
"xAxisProperty": "",
|
|
"xAxisPropertyType": "timestamp",
|
|
"xAxisFormat": "",
|
|
"xAxisFormatType": "auto",
|
|
"xmin": "",
|
|
"xmax": "",
|
|
"yAxisLabel": "",
|
|
"yAxisProperty": "payload",
|
|
"yAxisPropertyType": "msg",
|
|
"ymin": "",
|
|
"ymax": "",
|
|
"removeOlder": "10",
|
|
"removeOlderUnit": "60",
|
|
"removeOlderPoints": "300",
|
|
"action": "append",
|
|
"stackSeries": false,
|
|
"pointShape": "circle",
|
|
"pointRadius": 4,
|
|
"showLegend": true,
|
|
"bins": 10,
|
|
"colors": [
|
|
"#0095FF",
|
|
"#FF0000",
|
|
"#FF7F0E",
|
|
"#2CA02C",
|
|
"#A347E1",
|
|
"#D62728",
|
|
"#FF9896",
|
|
"#9467BD",
|
|
"#C5B0D5"
|
|
],
|
|
"textColor": [
|
|
"#666666"
|
|
],
|
|
"textColorDefault": true,
|
|
"gridColor": [
|
|
"#e5e5e5"
|
|
],
|
|
"gridColorDefault": true,
|
|
"width": 12,
|
|
"height": 8,
|
|
"className": "",
|
|
"x": 900,
|
|
"y": 2400,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "trend_long_flow",
|
|
"type": "ui-chart",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_trend_long_flow",
|
|
"name": "Flow per pump \u2014 1 hour",
|
|
"label": "Flow per pump (m\u00b3/h)",
|
|
"order": 1,
|
|
"chartType": "line",
|
|
"interpolation": "linear",
|
|
"category": "topic",
|
|
"categoryType": "msg",
|
|
"xAxisLabel": "",
|
|
"xAxisType": "time",
|
|
"xAxisProperty": "",
|
|
"xAxisPropertyType": "timestamp",
|
|
"xAxisFormat": "",
|
|
"xAxisFormatType": "auto",
|
|
"xmin": "",
|
|
"xmax": "",
|
|
"yAxisLabel": "",
|
|
"yAxisProperty": "payload",
|
|
"yAxisPropertyType": "msg",
|
|
"ymin": "",
|
|
"ymax": "",
|
|
"removeOlder": "60",
|
|
"removeOlderUnit": "60",
|
|
"removeOlderPoints": "1800",
|
|
"action": "append",
|
|
"stackSeries": false,
|
|
"pointShape": "circle",
|
|
"pointRadius": 4,
|
|
"showLegend": true,
|
|
"bins": 10,
|
|
"colors": [
|
|
"#0095FF",
|
|
"#FF0000",
|
|
"#FF7F0E",
|
|
"#2CA02C",
|
|
"#A347E1",
|
|
"#D62728",
|
|
"#FF9896",
|
|
"#9467BD",
|
|
"#C5B0D5"
|
|
],
|
|
"textColor": [
|
|
"#666666"
|
|
],
|
|
"textColorDefault": true,
|
|
"gridColor": [
|
|
"#e5e5e5"
|
|
],
|
|
"gridColorDefault": true,
|
|
"width": 12,
|
|
"height": 8,
|
|
"className": "",
|
|
"x": 900,
|
|
"y": 2480,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "trend_long_power",
|
|
"type": "ui-chart",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_trend_long_power",
|
|
"name": "Power per pump \u2014 1 hour",
|
|
"label": "Power per pump (kW)",
|
|
"order": 1,
|
|
"chartType": "line",
|
|
"interpolation": "linear",
|
|
"category": "topic",
|
|
"categoryType": "msg",
|
|
"xAxisLabel": "",
|
|
"xAxisType": "time",
|
|
"xAxisProperty": "",
|
|
"xAxisPropertyType": "timestamp",
|
|
"xAxisFormat": "",
|
|
"xAxisFormatType": "auto",
|
|
"xmin": "",
|
|
"xmax": "",
|
|
"yAxisLabel": "",
|
|
"yAxisProperty": "payload",
|
|
"yAxisPropertyType": "msg",
|
|
"ymin": "",
|
|
"ymax": "",
|
|
"removeOlder": "60",
|
|
"removeOlderUnit": "60",
|
|
"removeOlderPoints": "1800",
|
|
"action": "append",
|
|
"stackSeries": false,
|
|
"pointShape": "circle",
|
|
"pointRadius": 4,
|
|
"showLegend": true,
|
|
"bins": 10,
|
|
"colors": [
|
|
"#0095FF",
|
|
"#FF0000",
|
|
"#FF7F0E",
|
|
"#2CA02C",
|
|
"#A347E1",
|
|
"#D62728",
|
|
"#FF9896",
|
|
"#9467BD",
|
|
"#C5B0D5"
|
|
],
|
|
"textColor": [
|
|
"#666666"
|
|
],
|
|
"textColorDefault": true,
|
|
"gridColor": [
|
|
"#e5e5e5"
|
|
],
|
|
"gridColorDefault": true,
|
|
"width": 12,
|
|
"height": 8,
|
|
"className": "",
|
|
"x": 900,
|
|
"y": 2560,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "trend_short_basin",
|
|
"type": "ui-chart",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_trend_short_basin",
|
|
"name": "Basin \u2014 10 min",
|
|
"label": "Basin metrics",
|
|
"order": 1,
|
|
"chartType": "line",
|
|
"interpolation": "linear",
|
|
"category": "topic",
|
|
"categoryType": "msg",
|
|
"xAxisLabel": "",
|
|
"xAxisType": "time",
|
|
"xAxisProperty": "",
|
|
"xAxisPropertyType": "timestamp",
|
|
"xAxisFormat": "",
|
|
"xAxisFormatType": "auto",
|
|
"xmin": "",
|
|
"xmax": "",
|
|
"yAxisLabel": "",
|
|
"yAxisProperty": "payload",
|
|
"yAxisPropertyType": "msg",
|
|
"ymin": "",
|
|
"ymax": "",
|
|
"removeOlder": "10",
|
|
"removeOlderUnit": "60",
|
|
"removeOlderPoints": "300",
|
|
"action": "append",
|
|
"stackSeries": false,
|
|
"pointShape": "circle",
|
|
"pointRadius": 4,
|
|
"showLegend": true,
|
|
"bins": 10,
|
|
"colors": [
|
|
"#0095FF",
|
|
"#FF0000",
|
|
"#FF7F0E",
|
|
"#2CA02C",
|
|
"#A347E1",
|
|
"#D62728",
|
|
"#FF9896",
|
|
"#9467BD",
|
|
"#C5B0D5"
|
|
],
|
|
"textColor": [
|
|
"#666666"
|
|
],
|
|
"textColorDefault": true,
|
|
"gridColor": [
|
|
"#e5e5e5"
|
|
],
|
|
"gridColorDefault": true,
|
|
"width": 8,
|
|
"height": 8,
|
|
"className": "",
|
|
"x": 900,
|
|
"y": 2640,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "gauge_ps_level",
|
|
"type": "ui-gauge",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_trend_short_basin",
|
|
"name": "Basin level gauge (short)",
|
|
"gtype": "gauge-tank",
|
|
"gstyle": "Rounded",
|
|
"title": "Level",
|
|
"units": "m",
|
|
"prefix": "",
|
|
"suffix": " m",
|
|
"min": 0,
|
|
"max": 3,
|
|
"segments": [
|
|
{
|
|
"color": "#f44336",
|
|
"from": 0
|
|
},
|
|
{
|
|
"color": "#ff9800",
|
|
"from": 0.6
|
|
},
|
|
{
|
|
"color": "#2196f3",
|
|
"from": 1.2
|
|
},
|
|
{
|
|
"color": "#ff9800",
|
|
"from": 2.5
|
|
},
|
|
{
|
|
"color": "#f44336",
|
|
"from": 2.8
|
|
}
|
|
],
|
|
"width": 2,
|
|
"height": 5,
|
|
"order": 2,
|
|
"icon": "",
|
|
"sizeGauge": 20,
|
|
"sizeGap": 2,
|
|
"sizeSegments": 10,
|
|
"x": 1160,
|
|
"y": 2640,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "gauge_ps_fill",
|
|
"type": "ui-gauge",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_trend_short_basin",
|
|
"name": "Basin fill gauge (short)",
|
|
"gtype": "gauge-34",
|
|
"gstyle": "Rounded",
|
|
"title": "Fill",
|
|
"units": "%",
|
|
"prefix": "",
|
|
"suffix": "%",
|
|
"min": 0,
|
|
"max": 100,
|
|
"segments": [
|
|
{
|
|
"color": "#f44336",
|
|
"from": 0
|
|
},
|
|
{
|
|
"color": "#ff9800",
|
|
"from": 10
|
|
},
|
|
{
|
|
"color": "#4caf50",
|
|
"from": 30
|
|
},
|
|
{
|
|
"color": "#ff9800",
|
|
"from": 80
|
|
},
|
|
{
|
|
"color": "#f44336",
|
|
"from": 95
|
|
}
|
|
],
|
|
"width": 2,
|
|
"height": 4,
|
|
"order": 3,
|
|
"icon": "water_drop",
|
|
"sizeGauge": 20,
|
|
"sizeGap": 2,
|
|
"sizeSegments": 10,
|
|
"x": 1420,
|
|
"y": 2640,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "trend_long_basin",
|
|
"type": "ui-chart",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_trend_long_basin",
|
|
"name": "Basin \u2014 1 hour",
|
|
"label": "Basin metrics",
|
|
"order": 1,
|
|
"chartType": "line",
|
|
"interpolation": "linear",
|
|
"category": "topic",
|
|
"categoryType": "msg",
|
|
"xAxisLabel": "",
|
|
"xAxisType": "time",
|
|
"xAxisProperty": "",
|
|
"xAxisPropertyType": "timestamp",
|
|
"xAxisFormat": "",
|
|
"xAxisFormatType": "auto",
|
|
"xmin": "",
|
|
"xmax": "",
|
|
"yAxisLabel": "",
|
|
"yAxisProperty": "payload",
|
|
"yAxisPropertyType": "msg",
|
|
"ymin": "",
|
|
"ymax": "",
|
|
"removeOlder": "60",
|
|
"removeOlderUnit": "60",
|
|
"removeOlderPoints": "1800",
|
|
"action": "append",
|
|
"stackSeries": false,
|
|
"pointShape": "circle",
|
|
"pointRadius": 4,
|
|
"showLegend": true,
|
|
"bins": 10,
|
|
"colors": [
|
|
"#0095FF",
|
|
"#FF0000",
|
|
"#FF7F0E",
|
|
"#2CA02C",
|
|
"#A347E1",
|
|
"#D62728",
|
|
"#FF9896",
|
|
"#9467BD",
|
|
"#C5B0D5"
|
|
],
|
|
"textColor": [
|
|
"#666666"
|
|
],
|
|
"textColorDefault": true,
|
|
"gridColor": [
|
|
"#e5e5e5"
|
|
],
|
|
"gridColorDefault": true,
|
|
"width": 8,
|
|
"height": 8,
|
|
"className": "",
|
|
"x": 900,
|
|
"y": 2820,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "gauge_ps_level_long",
|
|
"type": "ui-gauge",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_trend_long_basin",
|
|
"name": "Basin level gauge (long)",
|
|
"gtype": "gauge-tank",
|
|
"gstyle": "Rounded",
|
|
"title": "Level",
|
|
"units": "m",
|
|
"prefix": "",
|
|
"suffix": " m",
|
|
"min": 0,
|
|
"max": 3,
|
|
"segments": [
|
|
{
|
|
"color": "#f44336",
|
|
"from": 0
|
|
},
|
|
{
|
|
"color": "#ff9800",
|
|
"from": 0.6
|
|
},
|
|
{
|
|
"color": "#2196f3",
|
|
"from": 1.2
|
|
},
|
|
{
|
|
"color": "#ff9800",
|
|
"from": 2.5
|
|
},
|
|
{
|
|
"color": "#f44336",
|
|
"from": 2.8
|
|
}
|
|
],
|
|
"width": 2,
|
|
"height": 5,
|
|
"order": 2,
|
|
"icon": "",
|
|
"sizeGauge": 20,
|
|
"sizeGap": 2,
|
|
"sizeSegments": 10,
|
|
"x": 1160,
|
|
"y": 2820,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "gauge_ps_fill_long",
|
|
"type": "ui-gauge",
|
|
"z": "tab_ui",
|
|
"group": "ui_grp_trend_long_basin",
|
|
"name": "Basin fill gauge (long)",
|
|
"gtype": "gauge-34",
|
|
"gstyle": "Rounded",
|
|
"title": "Fill",
|
|
"units": "%",
|
|
"prefix": "",
|
|
"suffix": "%",
|
|
"min": 0,
|
|
"max": 100,
|
|
"segments": [
|
|
{
|
|
"color": "#f44336",
|
|
"from": 0
|
|
},
|
|
{
|
|
"color": "#ff9800",
|
|
"from": 10
|
|
},
|
|
{
|
|
"color": "#4caf50",
|
|
"from": 30
|
|
},
|
|
{
|
|
"color": "#ff9800",
|
|
"from": 80
|
|
},
|
|
{
|
|
"color": "#f44336",
|
|
"from": 95
|
|
}
|
|
],
|
|
"width": 2,
|
|
"height": 4,
|
|
"order": 3,
|
|
"icon": "water_drop",
|
|
"sizeGauge": 20,
|
|
"sizeGap": 2,
|
|
"sizeSegments": 10,
|
|
"x": 1420,
|
|
"y": 2820,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "tab_drivers",
|
|
"type": "tab",
|
|
"label": "\ud83c\udf9b\ufe0f Demo Drivers",
|
|
"disabled": false,
|
|
"info": "Simulated inflow for the demo. A slow sinusoid generates inflow into the pumping station basin, which then drives the level-based pump control automatically.\n\nIn production, delete this tab \u2014 real inflow comes from upstream measurement sensors."
|
|
},
|
|
{
|
|
"id": "c_drv_title",
|
|
"type": "comment",
|
|
"z": "tab_drivers",
|
|
"name": "\ud83c\udf9b\ufe0f DEMO DRIVERS \u2014 simulated basin inflow",
|
|
"info": "Sinus generator \u2192 q_in to pumpingStation. Basin fills \u2192 level-based\ncontrol starts pumps \u2192 basin drains \u2192 pumps stop \u2192 cycle repeats.",
|
|
"x": 640,
|
|
"y": 20,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "c_drv_sinus",
|
|
"type": "comment",
|
|
"z": "tab_drivers",
|
|
"name": "\u2500\u2500 Sinusoidal inflow generator \u2500\u2500",
|
|
"info": "Produces a smooth inflow curve (m\u00b3/s) and sends to pumpingStation\nvia the cmd:q_in link channel. Period = 120s.",
|
|
"x": 640,
|
|
"y": 100,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "sinus_tick",
|
|
"type": "inject",
|
|
"z": "tab_drivers",
|
|
"name": "tick (1s inflow)",
|
|
"props": [
|
|
{
|
|
"p": "topic",
|
|
"vt": "str"
|
|
},
|
|
{
|
|
"p": "payload",
|
|
"v": "",
|
|
"vt": "date"
|
|
}
|
|
],
|
|
"topic": "sinusTick",
|
|
"payload": "",
|
|
"payloadType": "date",
|
|
"repeat": "1",
|
|
"crontab": "",
|
|
"once": false,
|
|
"onceDelay": "0.5",
|
|
"x": 120,
|
|
"y": 140,
|
|
"wires": [
|
|
[
|
|
"sinus_fn"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "sinus_fn",
|
|
"type": "function",
|
|
"z": "tab_drivers",
|
|
"name": "sinus inflow (m\u00b3/s)",
|
|
"func": "const base = 0.005; // m\u00b3/s (~18 m\u00b3/h always)\nconst amplitude = 0.03; // m\u00b3/s (~108 m\u00b3/h peak)\nconst period = 120; // seconds per full cycle\nconst t = Date.now() / 1000; // seconds since epoch\nconst q = base + amplitude * (1 + Math.sin(2 * Math.PI * t / period)) / 2;\nreturn { topic: 'q_in', payload: q, unit: 'm3/s', timestamp: Date.now() };",
|
|
"outputs": 1,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 600,
|
|
"y": 140,
|
|
"wires": [
|
|
[
|
|
"lout_qin_drivers"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_qin_drivers",
|
|
"type": "link out",
|
|
"z": "tab_drivers",
|
|
"name": "cmd:q_in",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_qin_at_ps"
|
|
],
|
|
"x": 900,
|
|
"y": 140,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "tab_setup",
|
|
"type": "tab",
|
|
"label": "\u2699\ufe0f Setup & Init",
|
|
"disabled": false,
|
|
"info": "One-shot deploy-time injects. Sets MGC scaling/mode, broadcasts pumps mode = auto, and auto-starts the pumps + random demand."
|
|
},
|
|
{
|
|
"id": "c_setup_title",
|
|
"type": "comment",
|
|
"z": "tab_setup",
|
|
"name": "\u2699\ufe0f SETUP & INIT \u2014 one-shot deploy-time injects",
|
|
"info": "Disable this tab in production \u2014 the runtime should be persistent.",
|
|
"x": 640,
|
|
"y": 20,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "setup_mgc_scaling",
|
|
"type": "inject",
|
|
"z": "tab_setup",
|
|
"name": "MGC scaling = normalized",
|
|
"props": [
|
|
{
|
|
"p": "topic",
|
|
"vt": "str"
|
|
},
|
|
{
|
|
"p": "payload",
|
|
"v": "normalized",
|
|
"vt": "str"
|
|
}
|
|
],
|
|
"topic": "setScaling",
|
|
"payload": "normalized",
|
|
"payloadType": "str",
|
|
"repeat": "",
|
|
"crontab": "",
|
|
"once": true,
|
|
"onceDelay": "1.5",
|
|
"x": 120,
|
|
"y": 100,
|
|
"wires": [
|
|
[
|
|
"lout_setup_to_mgc"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "setup_mgc_mode",
|
|
"type": "inject",
|
|
"z": "tab_setup",
|
|
"name": "MGC mode = optimalcontrol",
|
|
"props": [
|
|
{
|
|
"p": "topic",
|
|
"vt": "str"
|
|
},
|
|
{
|
|
"p": "payload",
|
|
"v": "optimalcontrol",
|
|
"vt": "str"
|
|
}
|
|
],
|
|
"topic": "setMode",
|
|
"payload": "optimalcontrol",
|
|
"payloadType": "str",
|
|
"repeat": "",
|
|
"crontab": "",
|
|
"once": true,
|
|
"onceDelay": "1.7",
|
|
"x": 120,
|
|
"y": 160,
|
|
"wires": [
|
|
[
|
|
"lout_setup_to_mgc"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_setup_to_mgc",
|
|
"type": "link out",
|
|
"z": "tab_setup",
|
|
"name": "setup:to-mgc",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_setup_at_mgc"
|
|
],
|
|
"x": 380,
|
|
"y": 130,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "setup_pumps_mode",
|
|
"type": "inject",
|
|
"z": "tab_setup",
|
|
"name": "pumps mode = auto",
|
|
"props": [
|
|
{
|
|
"p": "topic",
|
|
"vt": "str"
|
|
},
|
|
{
|
|
"p": "payload",
|
|
"v": "auto",
|
|
"vt": "str"
|
|
}
|
|
],
|
|
"topic": "setMode",
|
|
"payload": "auto",
|
|
"payloadType": "str",
|
|
"repeat": "",
|
|
"crontab": "",
|
|
"once": true,
|
|
"onceDelay": "2.0",
|
|
"x": 120,
|
|
"y": 250,
|
|
"wires": [
|
|
[
|
|
"lout_mode_setup"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_mode_setup",
|
|
"type": "link out",
|
|
"z": "tab_setup",
|
|
"name": "cmd:mode",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_mode"
|
|
],
|
|
"x": 380,
|
|
"y": 250,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "setup_pumps_startup",
|
|
"type": "inject",
|
|
"z": "tab_setup",
|
|
"name": "auto-startup all pumps",
|
|
"props": [
|
|
{
|
|
"p": "topic",
|
|
"vt": "str"
|
|
},
|
|
{
|
|
"p": "payload",
|
|
"v": "{\"source\":\"GUI\",\"action\":\"execSequence\",\"parameter\":\"startup\"}",
|
|
"vt": "json"
|
|
}
|
|
],
|
|
"topic": "execSequence",
|
|
"payload": "{\"source\":\"GUI\",\"action\":\"execSequence\",\"parameter\":\"startup\"}",
|
|
"payloadType": "json",
|
|
"repeat": "",
|
|
"crontab": "",
|
|
"once": true,
|
|
"onceDelay": "4",
|
|
"x": 120,
|
|
"y": 350,
|
|
"wires": [
|
|
[
|
|
"lout_setup_station_start"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "lout_setup_station_start",
|
|
"type": "link out",
|
|
"z": "tab_setup",
|
|
"name": "cmd:station-startup",
|
|
"mode": "link",
|
|
"links": [
|
|
"lin_station_start"
|
|
],
|
|
"x": 380,
|
|
"y": 350,
|
|
"wires": []
|
|
}
|
|
]
|