Editor + schema defaults - pumpingStation.html: drag-in defaults now reflect a realistic basin (volume=50 m³, height=4 m, inflowLevel=1.5, outflowLevel=0.2, overflowLevel=3.8, startLevel=1, stopLevel=0.5, minLevel=0.3, maxLevel=3.8). Old defaults left every level field null. Visual bug fix - src/editor/mode-preview.js: the level-based ramp curve in the editor was being drawn with foot=startLevel via buildPath(start, start, max). The runtime in control/levelBased.js has always used inflowLevel as the ramp foot. Pass buildPath(start, upFoot, max) where upFoot falls back to start when inflowLevel is missing, matching the runtime. Manual mode observability - src/specificClass.js: store last forwarded demand on this._manualDemand; surface as `mode` and `manualDemand` in getOutput(); call notifyOutputChanged() on forwardDemandToChildren and on changeMode so Port 0/1 emit even with no children registered. Status badge compacted to `mode | dir% | net m³/h` + `Qd=X m³/h` in manual mode. Examples cleanup - Drop stale 02-Integration.json, 03-Dashboard.json, basic-dashboard.flow.json, standalone-demo.js. - 01-Basic.json: numbered driver groups (1. Control mode … 4. Calibration), Debug-outputs group, fixed typos and HOW-TO-USE; Port 1 debug now active. - New 02-Dashboard.json: FlowFuse Dashboard 2.0 with Controls (7 buttons), Status (7 ui-text rows), Trends (4 ui-charts: level / volume / volume% / flow in-out-net), Raw output (ui-template dumping every Port 0 field). Fan-out function pattern-matches the 4-segment measurement keys by prefix instead of hardcoding childId, converts flow m³/s → m³/h, and caches last-known values so deltas never blank a row. - examples/README.md realigned to the two-file set. Wiki - Home.md: 5 image placeholders replaced with the provided screenshots (01-node-and-editor, 02-basic-flow, 03-wiring-standalone, 04-wiring-integrated) and the demo GIF (01-basic-demo). - Reference-Examples.md: shipped-files table reduced to 01-Basic + 02-Dashboard, Example-01 section uses the screenshot + GIF, Example-02 rewritten as Dashboard (kept screenshot/GIF callouts open for those captures), Example-03/Integration sections + their debug-recipes row removed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1071 lines
30 KiB
JSON
1071 lines
30 KiB
JSON
[
|
||
{
|
||
"id": "77f00aef1c966167",
|
||
"type": "tab",
|
||
"label": "PumpingStation - Dashboard",
|
||
"disabled": false,
|
||
"info": "Tier 2: single pumpingStation node driven by a FlowFuse dashboard. Same command surface as the Basic flow, plus live status rows, four trend charts, and a raw-output table."
|
||
},
|
||
{
|
||
"id": "aa3381b896eb2cfb",
|
||
"type": "group",
|
||
"z": "77f00aef1c966167",
|
||
"name": "Pumping Station (Process Cell)",
|
||
"style": {
|
||
"label": true,
|
||
"stroke": "#000000",
|
||
"fill": "#0c99d9",
|
||
"fill-opacity": "0.10"
|
||
},
|
||
"nodes": [
|
||
"8e78b6607deb33a7"
|
||
],
|
||
"x": 534,
|
||
"y": 371.5,
|
||
"w": 232,
|
||
"h": 97
|
||
},
|
||
{
|
||
"id": "4996420d47442fad",
|
||
"type": "group",
|
||
"z": "77f00aef1c966167",
|
||
"name": "1. Control mode",
|
||
"style": {
|
||
"stroke": "#666666",
|
||
"fill": "#ffdf7f",
|
||
"fill-opacity": "0.15",
|
||
"label": true,
|
||
"color": "#333333"
|
||
},
|
||
"nodes": [
|
||
"ui_btn_mode_manual",
|
||
"ui_btn_mode_lvl"
|
||
],
|
||
"x": 94,
|
||
"y": 119,
|
||
"w": 272,
|
||
"h": 122
|
||
},
|
||
{
|
||
"id": "a9f9b38b0e00c1d7",
|
||
"type": "group",
|
||
"z": "77f00aef1c966167",
|
||
"name": "2. Flow signals (inflow / outflow)",
|
||
"style": {
|
||
"stroke": "#666666",
|
||
"fill": "#ffdf7f",
|
||
"fill-opacity": "0.15",
|
||
"label": true,
|
||
"color": "#333333"
|
||
},
|
||
"nodes": [
|
||
"ui_btn_inflow",
|
||
"ui_btn_outflow"
|
||
],
|
||
"x": 94,
|
||
"y": 279,
|
||
"w": 272,
|
||
"h": 122
|
||
},
|
||
{
|
||
"id": "42bf82c87d05f498",
|
||
"type": "group",
|
||
"z": "77f00aef1c966167",
|
||
"name": "3. Operator demand (manual mode only)",
|
||
"style": {
|
||
"stroke": "#666666",
|
||
"fill": "#ffdf7f",
|
||
"fill-opacity": "0.15",
|
||
"label": true,
|
||
"color": "#333333"
|
||
},
|
||
"nodes": [
|
||
"ui_btn_demand"
|
||
],
|
||
"x": 94,
|
||
"y": 459,
|
||
"w": 261,
|
||
"h": 82
|
||
},
|
||
{
|
||
"id": "234bdce20170061a",
|
||
"type": "group",
|
||
"z": "77f00aef1c966167",
|
||
"name": "4. Calibration",
|
||
"style": {
|
||
"stroke": "#666666",
|
||
"fill": "#ffdf7f",
|
||
"fill-opacity": "0.15",
|
||
"label": true,
|
||
"color": "#333333"
|
||
},
|
||
"nodes": [
|
||
"ui_btn_cal_vol",
|
||
"ui_btn_cal_lvl"
|
||
],
|
||
"x": 94,
|
||
"y": 579,
|
||
"w": 272,
|
||
"h": 122
|
||
},
|
||
{
|
||
"id": "grp_status_panel",
|
||
"type": "group",
|
||
"z": "77f00aef1c966167",
|
||
"name": "Live status, trends, raw output",
|
||
"style": {
|
||
"stroke": "#666666",
|
||
"fill": "#bde0fe",
|
||
"fill-opacity": "0.20",
|
||
"label": true,
|
||
"color": "#333333"
|
||
},
|
||
"nodes": [
|
||
"fn_status_split",
|
||
"ui_txt_mode",
|
||
"ui_txt_direction",
|
||
"ui_txt_level",
|
||
"ui_txt_volume",
|
||
"ui_txt_volpct",
|
||
"ui_txt_pct",
|
||
"ui_txt_demand",
|
||
"ui_chart_level",
|
||
"ui_chart_volume",
|
||
"ui_chart_volpct",
|
||
"ui_chart_flow",
|
||
"ui_tpl_raw"
|
||
],
|
||
"x": 854,
|
||
"y": 99,
|
||
"w": 712,
|
||
"h": 642
|
||
},
|
||
{
|
||
"id": "f4ba4542514ed853",
|
||
"type": "group",
|
||
"z": "77f00aef1c966167",
|
||
"name": "Debug outputs (sidebar)",
|
||
"style": {
|
||
"stroke": "#666666",
|
||
"fill": "#d1d1d1",
|
||
"fill-opacity": "0.2",
|
||
"label": true,
|
||
"color": "#333333"
|
||
},
|
||
"nodes": [
|
||
"b2450e5ee2eebfaa",
|
||
"386af1ad8aa8ed12",
|
||
"c27c2655f199b530"
|
||
],
|
||
"x": 854,
|
||
"y": 779,
|
||
"w": 252,
|
||
"h": 202
|
||
},
|
||
{
|
||
"id": "b30af582f935bcb7",
|
||
"type": "comment",
|
||
"z": "77f00aef1c966167",
|
||
"name": "PumpingStation — Dashboard (Tier 2)",
|
||
"info": "Same command surface as the Basic example, driven by a FlowFuse dashboard.\n\nOpen /dashboard/pumpingstation-basic after deploy.\n\nCONTROLS panel\n- Mode buttons → set.mode (manual / levelbased)\n- Inflow / Outflow buttons → set.inflow / set.outflow (60 / 80 m³/h)\n- Demand button → set.demand (40 m³/h, manual mode only)\n- Calibrate buttons → cmd.calibrate.volume / cmd.calibrate.level\n\nSTATUS panel\n- 7 text rows: Mode, Direction, Level, Volume, Volume %, percControl, Manual demand\n\nTRENDS panel\n- 4 charts: Level (m), Volume (m³), Volume %, Flow (in/out/net m³/h)\n\nRAW OUTPUT panel\n- Full key/value dump of the latest Port 0 cache (sorted). Shows every field the node emits including basin geometry, safety thresholds, predicted overflow/underflow.\n\nThe fan-out function caches last-known values so delta-only Port 0 updates never blank a row.",
|
||
"x": 660,
|
||
"y": 320,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_base_ps",
|
||
"type": "ui-base",
|
||
"name": "EVOLV Demo",
|
||
"path": "/dashboard",
|
||
"appIcon": "",
|
||
"includeClientData": true,
|
||
"acceptsClientConfig": [
|
||
"ui-notification",
|
||
"ui-control"
|
||
],
|
||
"showPathInSidebar": false,
|
||
"headerContent": "page",
|
||
"navigationStyle": "default",
|
||
"titleBarStyle": "default"
|
||
},
|
||
{
|
||
"id": "ui_theme_ps",
|
||
"type": "ui-theme",
|
||
"name": "EVOLV Basic Theme",
|
||
"colors": {
|
||
"surface": "#ffffff",
|
||
"primary": "#0c99d9",
|
||
"bgPage": "#eeeeee",
|
||
"groupBg": "#ffffff",
|
||
"groupOutline": "#cccccc"
|
||
},
|
||
"sizes": {
|
||
"density": "default",
|
||
"pagePadding": "14px",
|
||
"groupGap": "14px",
|
||
"groupBorderRadius": "6px",
|
||
"widgetGap": "12px"
|
||
}
|
||
},
|
||
{
|
||
"id": "ui_page_ps",
|
||
"type": "ui-page",
|
||
"name": "PumpingStation Basic",
|
||
"ui": "ui_base_ps",
|
||
"path": "/pumpingstation-basic",
|
||
"icon": "water-pump",
|
||
"layout": "grid",
|
||
"theme": "ui_theme_ps",
|
||
"breakpoints": [
|
||
{
|
||
"name": "Default",
|
||
"px": "0",
|
||
"cols": "12"
|
||
}
|
||
],
|
||
"order": 1,
|
||
"className": ""
|
||
},
|
||
{
|
||
"id": "ui_group_ctrl",
|
||
"type": "ui-group",
|
||
"name": "Controls",
|
||
"page": "ui_page_ps",
|
||
"width": "6",
|
||
"height": "1",
|
||
"order": 1,
|
||
"showTitle": true,
|
||
"className": ""
|
||
},
|
||
{
|
||
"id": "ui_group_status",
|
||
"type": "ui-group",
|
||
"name": "Status",
|
||
"page": "ui_page_ps",
|
||
"width": "6",
|
||
"height": "1",
|
||
"order": 2,
|
||
"showTitle": true,
|
||
"className": ""
|
||
},
|
||
{
|
||
"id": "ui_group_trends",
|
||
"type": "ui-group",
|
||
"name": "Trends",
|
||
"page": "ui_page_ps",
|
||
"width": "12",
|
||
"height": "1",
|
||
"order": 3,
|
||
"showTitle": true,
|
||
"className": ""
|
||
},
|
||
{
|
||
"id": "ui_group_raw",
|
||
"type": "ui-group",
|
||
"name": "Raw output (Port 0 cache)",
|
||
"page": "ui_page_ps",
|
||
"width": "12",
|
||
"height": "1",
|
||
"order": 4,
|
||
"showTitle": true,
|
||
"className": ""
|
||
},
|
||
{
|
||
"id": "ui_btn_mode_manual",
|
||
"type": "ui-button",
|
||
"z": "77f00aef1c966167",
|
||
"g": "4996420d47442fad",
|
||
"group": "ui_group_ctrl",
|
||
"name": "Mode: Manual",
|
||
"label": "Mode: Manual",
|
||
"order": 1,
|
||
"width": "3",
|
||
"height": "1",
|
||
"emulateClick": false,
|
||
"tooltip": "Switch control mode to manual (set.demand is honoured)",
|
||
"color": "",
|
||
"bgcolor": "",
|
||
"icon": "pan_tool",
|
||
"payload": "manual",
|
||
"payloadType": "str",
|
||
"topic": "set.mode",
|
||
"topicType": "str",
|
||
"x": 230,
|
||
"y": 160,
|
||
"wires": [
|
||
[
|
||
"8e78b6607deb33a7"
|
||
]
|
||
]
|
||
},
|
||
{
|
||
"id": "ui_btn_mode_lvl",
|
||
"type": "ui-button",
|
||
"z": "77f00aef1c966167",
|
||
"g": "4996420d47442fad",
|
||
"group": "ui_group_ctrl",
|
||
"name": "Mode: Levelbased",
|
||
"label": "Mode: Levelbased",
|
||
"order": 2,
|
||
"width": "3",
|
||
"height": "1",
|
||
"emulateClick": false,
|
||
"tooltip": "Switch control mode to levelbased (ramp drives demand from level)",
|
||
"color": "",
|
||
"bgcolor": "",
|
||
"icon": "stacked_line_chart",
|
||
"payload": "levelbased",
|
||
"payloadType": "str",
|
||
"topic": "set.mode",
|
||
"topicType": "str",
|
||
"x": 240,
|
||
"y": 200,
|
||
"wires": [
|
||
[
|
||
"8e78b6607deb33a7"
|
||
]
|
||
]
|
||
},
|
||
{
|
||
"id": "ui_btn_inflow",
|
||
"type": "ui-button",
|
||
"z": "77f00aef1c966167",
|
||
"g": "a9f9b38b0e00c1d7",
|
||
"group": "ui_group_ctrl",
|
||
"name": "Inflow 60 m³/h",
|
||
"label": "Inflow 60 m³/h",
|
||
"order": 3,
|
||
"width": "3",
|
||
"height": "1",
|
||
"emulateClick": false,
|
||
"tooltip": "Push a measured inflow of 60 m³/h into the basin balance",
|
||
"color": "",
|
||
"bgcolor": "",
|
||
"icon": "south",
|
||
"payload": "60",
|
||
"payloadType": "num",
|
||
"topic": "set.inflow",
|
||
"topicType": "str",
|
||
"x": 240,
|
||
"y": 320,
|
||
"wires": [
|
||
[
|
||
"8e78b6607deb33a7"
|
||
]
|
||
]
|
||
},
|
||
{
|
||
"id": "ui_btn_outflow",
|
||
"type": "ui-button",
|
||
"z": "77f00aef1c966167",
|
||
"g": "a9f9b38b0e00c1d7",
|
||
"group": "ui_group_ctrl",
|
||
"name": "Outflow 80 m³/h",
|
||
"label": "Outflow 80 m³/h",
|
||
"order": 4,
|
||
"width": "3",
|
||
"height": "1",
|
||
"emulateClick": false,
|
||
"tooltip": "Push a measured outflow of 80 m³/h into the basin balance",
|
||
"color": "",
|
||
"bgcolor": "",
|
||
"icon": "north",
|
||
"payload": "80",
|
||
"payloadType": "num",
|
||
"topic": "set.outflow",
|
||
"topicType": "str",
|
||
"x": 240,
|
||
"y": 360,
|
||
"wires": [
|
||
[
|
||
"8e78b6607deb33a7"
|
||
]
|
||
]
|
||
},
|
||
{
|
||
"id": "ui_btn_demand",
|
||
"type": "ui-button",
|
||
"z": "77f00aef1c966167",
|
||
"g": "42bf82c87d05f498",
|
||
"group": "ui_group_ctrl",
|
||
"name": "Demand 40 m³/h",
|
||
"label": "Demand 40 m³/h (manual)",
|
||
"order": 5,
|
||
"width": "6",
|
||
"height": "1",
|
||
"emulateClick": false,
|
||
"tooltip": "Operator outflow demand — only forwarded when mode = manual",
|
||
"color": "",
|
||
"bgcolor": "",
|
||
"icon": "speed",
|
||
"payload": "40",
|
||
"payloadType": "num",
|
||
"topic": "set.demand",
|
||
"topicType": "str",
|
||
"x": 240,
|
||
"y": 500,
|
||
"wires": [
|
||
[
|
||
"8e78b6607deb33a7"
|
||
]
|
||
]
|
||
},
|
||
{
|
||
"id": "ui_btn_cal_vol",
|
||
"type": "ui-button",
|
||
"z": "77f00aef1c966167",
|
||
"g": "234bdce20170061a",
|
||
"group": "ui_group_ctrl",
|
||
"name": "Calibrate V=25 m³",
|
||
"label": "Calibrate V = 25 m³",
|
||
"order": 6,
|
||
"width": "3",
|
||
"height": "1",
|
||
"emulateClick": false,
|
||
"tooltip": "Snap the predicted-volume integrator to 25 m³",
|
||
"color": "",
|
||
"bgcolor": "",
|
||
"icon": "tune",
|
||
"payload": "25",
|
||
"payloadType": "num",
|
||
"topic": "cmd.calibrate.volume",
|
||
"topicType": "str",
|
||
"x": 240,
|
||
"y": 620,
|
||
"wires": [
|
||
[
|
||
"8e78b6607deb33a7"
|
||
]
|
||
]
|
||
},
|
||
{
|
||
"id": "ui_btn_cal_lvl",
|
||
"type": "ui-button",
|
||
"z": "77f00aef1c966167",
|
||
"g": "234bdce20170061a",
|
||
"group": "ui_group_ctrl",
|
||
"name": "Calibrate L=1.5 m",
|
||
"label": "Calibrate L = 1.5 m",
|
||
"order": 7,
|
||
"width": "3",
|
||
"height": "1",
|
||
"emulateClick": false,
|
||
"tooltip": "Snap the predicted-volume integrator to a known level of 1.5 m",
|
||
"color": "",
|
||
"bgcolor": "",
|
||
"icon": "tune",
|
||
"payload": "1.5",
|
||
"payloadType": "num",
|
||
"topic": "cmd.calibrate.level",
|
||
"topicType": "str",
|
||
"x": 240,
|
||
"y": 660,
|
||
"wires": [
|
||
[
|
||
"8e78b6607deb33a7"
|
||
]
|
||
]
|
||
},
|
||
{
|
||
"id": "fn_status_split",
|
||
"type": "function",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"name": "fan-out Port 0 (status + charts + raw)",
|
||
"func": "// Port 0 emits delta-only — cache last-known so deltas never blank a row.\n// Keys with dots use the runtime childId (= node id), so we pattern-match\n// by prefix rather than hardcoding.\nconst cache = context.get('cache') || {};\nconst p = msg.payload || {};\nfor (const k in p) cache[k] = p[k];\ncontext.set('cache', cache);\n\nconst findByPrefix = (prefix) => {\n for (const k of Object.keys(cache)) if (k.startsWith(prefix)) return cache[k];\n return null;\n};\nconst num = (v, dp, unit) => {\n const n = +v;\n if (!Number.isFinite(n)) return '—';\n return n.toFixed(dp) + (unit ? ' ' + unit : '');\n};\n\nconst level = findByPrefix('level.predicted.atequipment.');\nconst volume = findByPrefix('volume.predicted.atequipment.');\nconst volPct = findByPrefix('volumePercent.predicted.atequipment.');\nconst qInS = findByPrefix('flow.predicted.in.');\nconst qOutS = findByPrefix('flow.predicted.out.');\nconst qNetS = findByPrefix('netFlowRate.predicted.atequipment.');\nconst qInH = Number.isFinite(+qInS) ? +qInS * 3600 : null;\nconst qOutH = Number.isFinite(+qOutS) ? +qOutS * 3600 : null;\nconst qNetH = Number.isFinite(+qNetS) ? +qNetS * 3600 : null;\nconst pct = cache.percControl;\nconst dem = cache.manualDemand;\nconst mode = cache.mode || '—';\nconst dir = cache.direction || '—';\n\nconst chart = (topic, v) => Number.isFinite(+v) ? { topic, payload: +v } : null;\n\n// Raw view: every cached key, sorted, with values prettified for display.\nconst rawRows = Object.keys(cache).sort().map((k) => {\n const v = cache[k];\n let display;\n if (v === null || v === undefined) display = '—';\n else if (typeof v === 'number') display = Number.isInteger(v) ? String(v) : v.toFixed(4);\n else display = String(v);\n return { key: k, value: display };\n});\n\nreturn [\n // 0–6: status text widgets\n { payload: mode },\n { payload: dir },\n { payload: num(level, 2, 'm') },\n { payload: num(volume, 2, 'm³') },\n { payload: num(volPct, 2, '%') },\n { payload: num(pct, 1, '%') },\n { payload: mode === 'manual'\n ? (Number.isFinite(+dem) ? num(dem, 1, 'm³/h') : 'not set')\n : '—' },\n // 7–9: single-series charts\n chart('Level', level),\n chart('Volume', volume),\n chart('Volume %', volPct),\n // 10–12: flow chart (three series share the same chart node)\n chart('Inflow', qInH),\n chart('Outflow', qOutH),\n chart('Net', qNetH),\n // 13: raw key/value rows for the ui-template\n { payload: rawRows },\n];\n",
|
||
"outputs": 14,
|
||
"timeout": 0,
|
||
"noerr": 0,
|
||
"initialize": "",
|
||
"finalize": "",
|
||
"libs": [],
|
||
"x": 980,
|
||
"y": 140,
|
||
"wires": [
|
||
[
|
||
"ui_txt_mode"
|
||
],
|
||
[
|
||
"ui_txt_direction"
|
||
],
|
||
[
|
||
"ui_txt_level"
|
||
],
|
||
[
|
||
"ui_txt_volume"
|
||
],
|
||
[
|
||
"ui_txt_volpct"
|
||
],
|
||
[
|
||
"ui_txt_pct"
|
||
],
|
||
[
|
||
"ui_txt_demand"
|
||
],
|
||
[
|
||
"ui_chart_level"
|
||
],
|
||
[
|
||
"ui_chart_volume"
|
||
],
|
||
[
|
||
"ui_chart_volpct"
|
||
],
|
||
[
|
||
"ui_chart_flow"
|
||
],
|
||
[
|
||
"ui_chart_flow"
|
||
],
|
||
[
|
||
"ui_chart_flow"
|
||
],
|
||
[
|
||
"ui_tpl_raw"
|
||
]
|
||
]
|
||
},
|
||
{
|
||
"id": "ui_txt_mode",
|
||
"type": "ui-text",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_status",
|
||
"order": 1,
|
||
"width": "6",
|
||
"height": "1",
|
||
"name": "Mode",
|
||
"label": "Mode",
|
||
"format": "{{msg.payload}}",
|
||
"layout": "row-spread",
|
||
"style": false,
|
||
"font": "",
|
||
"fontSize": 14,
|
||
"color": "#1F4E79",
|
||
"x": 1240,
|
||
"y": 100,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_txt_direction",
|
||
"type": "ui-text",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_status",
|
||
"order": 2,
|
||
"width": "6",
|
||
"height": "1",
|
||
"name": "Direction",
|
||
"label": "Direction",
|
||
"format": "{{msg.payload}}",
|
||
"layout": "row-spread",
|
||
"style": false,
|
||
"font": "",
|
||
"fontSize": 14,
|
||
"color": "#1F4E79",
|
||
"x": 1250,
|
||
"y": 140,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_txt_level",
|
||
"type": "ui-text",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_status",
|
||
"order": 3,
|
||
"width": "6",
|
||
"height": "1",
|
||
"name": "Level",
|
||
"label": "Level",
|
||
"format": "{{msg.payload}}",
|
||
"layout": "row-spread",
|
||
"style": false,
|
||
"font": "",
|
||
"fontSize": 14,
|
||
"color": "#1F4E79",
|
||
"x": 1240,
|
||
"y": 180,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_txt_volume",
|
||
"type": "ui-text",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_status",
|
||
"order": 4,
|
||
"width": "6",
|
||
"height": "1",
|
||
"name": "Volume",
|
||
"label": "Volume",
|
||
"format": "{{msg.payload}}",
|
||
"layout": "row-spread",
|
||
"style": false,
|
||
"font": "",
|
||
"fontSize": 14,
|
||
"color": "#1F4E79",
|
||
"x": 1250,
|
||
"y": 220,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_txt_volpct",
|
||
"type": "ui-text",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_status",
|
||
"order": 5,
|
||
"width": "6",
|
||
"height": "1",
|
||
"name": "Volume %",
|
||
"label": "Volume %",
|
||
"format": "{{msg.payload}}",
|
||
"layout": "row-spread",
|
||
"style": false,
|
||
"font": "",
|
||
"fontSize": 14,
|
||
"color": "#1F4E79",
|
||
"x": 1250,
|
||
"y": 260,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_txt_pct",
|
||
"type": "ui-text",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_status",
|
||
"order": 6,
|
||
"width": "6",
|
||
"height": "1",
|
||
"name": "percControl",
|
||
"label": "percControl",
|
||
"format": "{{msg.payload}}",
|
||
"layout": "row-spread",
|
||
"style": false,
|
||
"font": "",
|
||
"fontSize": 14,
|
||
"color": "#1F4E79",
|
||
"x": 1260,
|
||
"y": 300,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_txt_demand",
|
||
"type": "ui-text",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_status",
|
||
"order": 7,
|
||
"width": "6",
|
||
"height": "1",
|
||
"name": "Manual demand",
|
||
"label": "Manual demand",
|
||
"format": "{{msg.payload}}",
|
||
"layout": "row-spread",
|
||
"style": false,
|
||
"font": "",
|
||
"fontSize": 14,
|
||
"color": "#7D3C98",
|
||
"x": 1270,
|
||
"y": 340,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_chart_level",
|
||
"type": "ui-chart",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_trends",
|
||
"name": "Level (m)",
|
||
"label": "Level (m)",
|
||
"order": 1,
|
||
"width": 6,
|
||
"height": 4,
|
||
"chartType": "line",
|
||
"category": "topic",
|
||
"categoryType": "msg",
|
||
"xAxisLabel": "time",
|
||
"xAxisType": "time",
|
||
"xAxisProperty": "",
|
||
"xAxisPropertyType": "timestamp",
|
||
"xAxisFormat": "",
|
||
"xAxisFormatType": "auto",
|
||
"yAxisLabel": "m",
|
||
"yAxisProperty": "payload",
|
||
"yAxisPropertyType": "msg",
|
||
"xmin": "",
|
||
"xmax": "",
|
||
"ymin": "",
|
||
"ymax": "",
|
||
"removeOlder": "15",
|
||
"removeOlderUnit": "60",
|
||
"removeOlderPoints": "",
|
||
"bins": 10,
|
||
"action": "append",
|
||
"stackSeries": false,
|
||
"pointShape": "circle",
|
||
"pointRadius": 4,
|
||
"interpolation": "linear",
|
||
"showLegend": false,
|
||
"className": "",
|
||
"colors": [
|
||
"#0095FF",
|
||
"#FF0000",
|
||
"#FF7F0E",
|
||
"#2CA02C",
|
||
"#A347E1",
|
||
"#D62728",
|
||
"#FF9896",
|
||
"#9467BD",
|
||
"#C5B0D5"
|
||
],
|
||
"textColor": [
|
||
"#666666"
|
||
],
|
||
"textColorDefault": true,
|
||
"gridColor": [
|
||
"#e5e5e5"
|
||
],
|
||
"gridColorDefault": true,
|
||
"x": 1240,
|
||
"y": 400,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_chart_volume",
|
||
"type": "ui-chart",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_trends",
|
||
"name": "Volume (m³)",
|
||
"label": "Volume (m³)",
|
||
"order": 2,
|
||
"width": 6,
|
||
"height": 4,
|
||
"chartType": "line",
|
||
"category": "topic",
|
||
"categoryType": "msg",
|
||
"xAxisLabel": "time",
|
||
"xAxisType": "time",
|
||
"xAxisProperty": "",
|
||
"xAxisPropertyType": "timestamp",
|
||
"xAxisFormat": "",
|
||
"xAxisFormatType": "auto",
|
||
"yAxisLabel": "m³",
|
||
"yAxisProperty": "payload",
|
||
"yAxisPropertyType": "msg",
|
||
"xmin": "",
|
||
"xmax": "",
|
||
"ymin": "",
|
||
"ymax": "",
|
||
"removeOlder": "15",
|
||
"removeOlderUnit": "60",
|
||
"removeOlderPoints": "",
|
||
"bins": 10,
|
||
"action": "append",
|
||
"stackSeries": false,
|
||
"pointShape": "circle",
|
||
"pointRadius": 4,
|
||
"interpolation": "linear",
|
||
"showLegend": false,
|
||
"className": "",
|
||
"colors": [
|
||
"#2CA02C",
|
||
"#FF0000",
|
||
"#FF7F0E",
|
||
"#0095FF",
|
||
"#A347E1",
|
||
"#D62728",
|
||
"#FF9896",
|
||
"#9467BD",
|
||
"#C5B0D5"
|
||
],
|
||
"textColor": [
|
||
"#666666"
|
||
],
|
||
"textColorDefault": true,
|
||
"gridColor": [
|
||
"#e5e5e5"
|
||
],
|
||
"gridColorDefault": true,
|
||
"x": 1250,
|
||
"y": 440,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_chart_volpct",
|
||
"type": "ui-chart",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_trends",
|
||
"name": "Volume %",
|
||
"label": "Volume %",
|
||
"order": 3,
|
||
"width": 6,
|
||
"height": 4,
|
||
"chartType": "line",
|
||
"category": "topic",
|
||
"categoryType": "msg",
|
||
"xAxisLabel": "time",
|
||
"xAxisType": "time",
|
||
"xAxisProperty": "",
|
||
"xAxisPropertyType": "timestamp",
|
||
"xAxisFormat": "",
|
||
"xAxisFormatType": "auto",
|
||
"yAxisLabel": "%",
|
||
"yAxisProperty": "payload",
|
||
"yAxisPropertyType": "msg",
|
||
"xmin": "",
|
||
"xmax": "",
|
||
"ymin": "0",
|
||
"ymax": "100",
|
||
"removeOlder": "15",
|
||
"removeOlderUnit": "60",
|
||
"removeOlderPoints": "",
|
||
"bins": 10,
|
||
"action": "append",
|
||
"stackSeries": false,
|
||
"pointShape": "circle",
|
||
"pointRadius": 4,
|
||
"interpolation": "linear",
|
||
"showLegend": false,
|
||
"className": "",
|
||
"colors": [
|
||
"#A347E1",
|
||
"#FF0000",
|
||
"#FF7F0E",
|
||
"#2CA02C",
|
||
"#0095FF",
|
||
"#D62728",
|
||
"#FF9896",
|
||
"#9467BD",
|
||
"#C5B0D5"
|
||
],
|
||
"textColor": [
|
||
"#666666"
|
||
],
|
||
"textColorDefault": true,
|
||
"gridColor": [
|
||
"#e5e5e5"
|
||
],
|
||
"gridColorDefault": true,
|
||
"x": 1240,
|
||
"y": 480,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_chart_flow",
|
||
"type": "ui-chart",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_trends",
|
||
"name": "Flow (m³/h)",
|
||
"label": "Flow (m³/h) — Inflow / Outflow / Net",
|
||
"order": 4,
|
||
"width": 6,
|
||
"height": 4,
|
||
"chartType": "line",
|
||
"category": "topic",
|
||
"categoryType": "msg",
|
||
"xAxisLabel": "time",
|
||
"xAxisType": "time",
|
||
"xAxisProperty": "",
|
||
"xAxisPropertyType": "timestamp",
|
||
"xAxisFormat": "",
|
||
"xAxisFormatType": "auto",
|
||
"yAxisLabel": "m³/h",
|
||
"yAxisProperty": "payload",
|
||
"yAxisPropertyType": "msg",
|
||
"xmin": "",
|
||
"xmax": "",
|
||
"ymin": "",
|
||
"ymax": "",
|
||
"removeOlder": "15",
|
||
"removeOlderUnit": "60",
|
||
"removeOlderPoints": "",
|
||
"bins": 10,
|
||
"action": "append",
|
||
"stackSeries": false,
|
||
"pointShape": "circle",
|
||
"pointRadius": 4,
|
||
"interpolation": "linear",
|
||
"showLegend": true,
|
||
"className": "",
|
||
"colors": [
|
||
"#0095FF",
|
||
"#FF7F0E",
|
||
"#2CA02C",
|
||
"#FF0000",
|
||
"#A347E1",
|
||
"#D62728",
|
||
"#FF9896",
|
||
"#9467BD",
|
||
"#C5B0D5"
|
||
],
|
||
"textColor": [
|
||
"#666666"
|
||
],
|
||
"textColorDefault": true,
|
||
"gridColor": [
|
||
"#e5e5e5"
|
||
],
|
||
"gridColorDefault": true,
|
||
"x": 1250,
|
||
"y": 520,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "ui_tpl_raw",
|
||
"type": "ui-template",
|
||
"z": "77f00aef1c966167",
|
||
"g": "grp_status_panel",
|
||
"group": "ui_group_raw",
|
||
"name": "Raw output table",
|
||
"order": 1,
|
||
"width": "12",
|
||
"height": "8",
|
||
"head": "",
|
||
"format": "<template>\n <div style=\"font-family:monospace;font-size:12px\">\n <table style=\"width:100%;border-collapse:collapse\">\n <tr v-for=\"row in rows\" :key=\"row.key\" style=\"border-bottom:1px solid #eee\">\n <td style=\"padding:2px 8px;color:#444;white-space:nowrap\">{{ row.key }}</td>\n <td style=\"padding:2px 8px;text-align:right;color:#0c4a72\">{{ row.value }}</td>\n </tr>\n </table>\n </div>\n</template>\n\n<script>\nexport default {\n data() { return { rows: [] }; },\n watch: {\n msg(m) {\n if (m && Array.isArray(m.payload)) this.rows = m.payload;\n }\n }\n}\n</script>\n",
|
||
"storeOutMessages": true,
|
||
"passthru": true,
|
||
"resendOnRefresh": true,
|
||
"templateScope": "local",
|
||
"className": "",
|
||
"x": 1260,
|
||
"y": 580,
|
||
"wires": [
|
||
[]
|
||
]
|
||
},
|
||
{
|
||
"id": "b2450e5ee2eebfaa",
|
||
"type": "debug",
|
||
"z": "77f00aef1c966167",
|
||
"g": "f4ba4542514ed853",
|
||
"name": "Port 0: Process",
|
||
"active": true,
|
||
"tosidebar": true,
|
||
"console": false,
|
||
"tostatus": false,
|
||
"complete": "payload",
|
||
"targetType": "msg",
|
||
"x": 980,
|
||
"y": 820,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "386af1ad8aa8ed12",
|
||
"type": "debug",
|
||
"z": "77f00aef1c966167",
|
||
"g": "f4ba4542514ed853",
|
||
"name": "Port 1: InfluxDB",
|
||
"active": true,
|
||
"tosidebar": true,
|
||
"console": false,
|
||
"tostatus": false,
|
||
"complete": "true",
|
||
"targetType": "full",
|
||
"x": 980,
|
||
"y": 880,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "c27c2655f199b530",
|
||
"type": "debug",
|
||
"z": "77f00aef1c966167",
|
||
"g": "f4ba4542514ed853",
|
||
"name": "Port 2: Parent reg",
|
||
"active": true,
|
||
"tosidebar": true,
|
||
"console": false,
|
||
"tostatus": false,
|
||
"complete": "true",
|
||
"targetType": "full",
|
||
"x": 990,
|
||
"y": 940,
|
||
"wires": []
|
||
},
|
||
{
|
||
"id": "8e78b6607deb33a7",
|
||
"type": "pumpingStation",
|
||
"z": "77f00aef1c966167",
|
||
"g": "aa3381b896eb2cfb",
|
||
"name": "",
|
||
"simulator": false,
|
||
"basinVolume": 50,
|
||
"basinHeight": 4,
|
||
"inflowLevel": 1.5,
|
||
"outflowLevel": 0.2,
|
||
"overflowLevel": 3.8,
|
||
"defaultFluid": "wastewater",
|
||
"inletPipeDiameter": 0.3,
|
||
"outletPipeDiameter": 0.3,
|
||
"pipelineLength": 80,
|
||
"maxDischargeHead": 24,
|
||
"staticHead": 12,
|
||
"maxInflowRate": 200,
|
||
"temperatureReferenceDegC": 15,
|
||
"timeleftToFullOrEmptyThresholdSeconds": 0,
|
||
"enableDryRunProtection": true,
|
||
"enableHighVolumeSafety": true,
|
||
"enableOverfillProtection": true,
|
||
"dryRunThresholdPercent": 2,
|
||
"highVolumeSafetyThresholdPercent": 98,
|
||
"overfillThresholdPercent": 98,
|
||
"minHeightBasedOn": "outlet",
|
||
"processOutputFormat": "process",
|
||
"dbaseOutputFormat": "influxdb",
|
||
"refHeight": "NAP",
|
||
"basinBottomRef": 1,
|
||
"uuid": "",
|
||
"supplier": "",
|
||
"category": "",
|
||
"assetType": "",
|
||
"model": "",
|
||
"unit": "",
|
||
"enableLog": false,
|
||
"logLevel": "error",
|
||
"positionVsParent": "atEquipment",
|
||
"positionIcon": "⊥",
|
||
"hasDistance": false,
|
||
"distance": "",
|
||
"controlMode": "levelbased",
|
||
"levelCurveType": "linear",
|
||
"logCurveFactor": 9,
|
||
"enableShiftedRamp": false,
|
||
"shiftLevel": 0,
|
||
"shiftArmPercent": 95,
|
||
"startLevel": 1,
|
||
"stopLevel": 0.5,
|
||
"minLevel": 0.3,
|
||
"maxLevel": 3.8,
|
||
"flowSetpoint": null,
|
||
"flowDeadband": null,
|
||
"x": 650,
|
||
"y": 420,
|
||
"wires": [
|
||
[
|
||
"b2450e5ee2eebfaa",
|
||
"fn_status_split"
|
||
],
|
||
[
|
||
"386af1ad8aa8ed12"
|
||
],
|
||
[
|
||
"c27c2655f199b530"
|
||
]
|
||
]
|
||
},
|
||
{
|
||
"id": "ef77c1819422a098",
|
||
"type": "global-config",
|
||
"env": [],
|
||
"modules": {
|
||
"EVOLV": "1.0.29"
|
||
}
|
||
}
|
||
]
|