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