2025-10-14 13:51:32 +02:00
<!--
| S88-niveau | Primair (blokkleur) | Tekstkleur |
| ---------------------- | ------------------- | ---------- |
| **Area** | `#0f52a5` | wit |
| **Process Cell** | `#0c99d9` | wit |
| **Unit** | `#50a8d9` | zwart |
| **Equipment (Module)** | `#86bbdd` | zwart |
| **Control Module** | `#a9daee` | zwart |
-->
2026-05-10 20:18:49 +02:00
< script src = "/pumpingStation/menu.js" > < / script > <!-- Load the menu script for dynamic dropdowns -->
< script src = "/pumpingStation/configData.js" > < / script > <!-- Load the config script for node information -->
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
<!-- Editor JS modules — see nodes/pumpingStation/src/editor/. Loaded in
dependency order: index.js (namespace + helpers) → diagrams → handlers. -->
< script src = "/pumpingStation/editor/index.js" > < / script >
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< script src = "/pumpingStation/editor/bounds.js" > < / script >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< script src = "/pumpingStation/editor/basin-diagram.js" > < / script >
< script src = "/pumpingStation/editor/mode-preview.js" > < / script >
< script src = "/pumpingStation/editor/hover-couple.js" > < / script >
< script src = "/pumpingStation/editor/oneditprepare.js" > < / script >
< script src = "/pumpingStation/editor/oneditsave.js" > < / script >
2025-10-07 18:05:54 +02:00
2025-10-13 11:50:54 +02:00
< script > / / t e s t
2025-10-14 08:36:45 +02:00
RED.nodes.registerType("pumpingStation", {
2025-10-07 18:05:54 +02:00
category: "EVOLV",
2025-10-14 13:51:32 +02:00
color: "#0c99d9", // color for the node based on the S88 schema
2025-10-07 18:05:54 +02:00
defaults: {
2026-04-22 16:13:59 +02:00
name: { value: "" },
2025-10-07 18:05:54 +02:00
2025-10-14 16:32:44 +02:00
// Define station-specific properties
simulator: { value: false },
feat(pumpingStation): realistic defaults, ramp-foot visual fix, manual-mode visibility, dashboard example
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>
2026-05-12 14:52:00 +02:00
basinVolume: { value: 50 }, // m³, total empty basin
basinHeight: { value: 4 }, // m, floor to top
inflowLevel: { value: 1.5 }, // m, bottom/invert of inlet pipe above floor
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
outflowLevel: { value: 0.2 }, // m, top of outlet/suction pipe above floor
feat(pumpingStation): realistic defaults, ramp-foot visual fix, manual-mode visibility, dashboard example
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>
2026-05-12 14:52:00 +02:00
overflowLevel: { value: 3.8 }, // m, overflow elevation
2026-04-22 16:13:59 +02:00
defaultFluid: { value: "wastewater" },
inletPipeDiameter: { value: 0.3 }, // m
outletPipeDiameter: { value: 0.3 }, // m
pipelineLength: { value: 80 }, // m
maxDischargeHead: { value: 24 }, // m
staticHead: { value: 12 }, // m
maxInflowRate: { value: 200 }, // m³/h
temperatureReferenceDegC: { value: 15 },
2025-11-25 14:57:39 +01:00
timeleftToFullOrEmptyThresholdSeconds:{value:0}, // time threshold to safeguard starting or stopping pumps in seconds
enableDryRunProtection: { value: true },
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
enableHighVolumeSafety: { value: true },
enableOverfillProtection: { value: true }, // deprecated alias
2025-11-25 14:57:39 +01:00
dryRunThresholdPercent: { value: 2 },
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
highVolumeSafetyThresholdPercent: { value: 98 },
overfillThresholdPercent: { value: 98 }, // deprecated alias
2025-11-20 12:15:46 +01:00
minHeightBasedOn: { value: "outlet" }, // basis for minimum height check: inlet or outlet
2026-03-12 16:39:25 +01:00
processOutputFormat: { value: "process" },
dbaseOutputFormat: { value: "influxdb" },
2025-10-14 16:32:44 +02:00
// Advanced reference information
refHeight: { value: "NAP" }, // reference height
basinBottomRef: { value: 1 }, // absolute elevation of basin floor
2025-10-07 18:05:54 +02:00
//define asset properties
uuid: { value: "" },
supplier: { value: "" },
category: { value: "" },
assetType: { value: "" },
model: { value: "" },
unit: { value: "" },
//logger properties
enableLog: { value: false },
logLevel: { value: "error" },
//physicalAspect
positionVsParent: { value: "" },
positionIcon: { value: "" },
hasDistance: { value: false },
distance: { value: 0 },
distanceUnit: { value: "m" },
2025-11-27 17:46:24 +01:00
distanceDescription: { value: "" },
// control strategy
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
controlMode: { value: "levelbased" },
levelCurveType: { value: "linear" },
logCurveFactor: { value: 9 },
enableShiftedRamp: { value: false },
shiftLevel: { value: 0 },
Hold-then-ramp shift semantics + shiftArmPercent + e2e tests
Runtime (specificClass.js):
- Replace the "shift left both ramp ends" geometry with a true
hold-then-ramp hysteresis driven by output %, not level:
• Up-curve % crosses shiftArmPercent on the way up → ARM.
• Filling→draining transition while armed → capture the up-curve %
at that moment as _shiftHoldValue.
• Draining + level ≥ shiftLevel → output stays at _shiftHoldValue
(horizontal hold, matching the dashed segment in the SVG).
• Draining + level in [start, shift] → output ramps holdValue → 0 %
along the same curve shape (linear or log) as the up curve.
• Draining + level < startLevel → 0 % AND disarm.
• Returning to filling clears holdValue, stays armed; next drain
transition captures a fresh hold so bouncing fills rearm cleanly.
• Disarm only when level ≤ startLevel.
- New _curveShape(x) helper for shared linear/log shaping.
- Removed legacy _levelBasedRampStart / _levelBasedRampTop /
_updateShiftArmed in favour of the inline state machine.
Adapter (nodeClass.js):
- Pipe shiftArmPercent through to control.levelbased.
Editor (pumpingStation.html + src/editor/):
- Add shiftArmPercent input row (% with unit) to the mode side panel
(only shown when shifted ramp is enabled). Default 95 %.
- Add the horizontal arming-% line + label inside the mode SVG —
this is the "% Threshold triggering shifted ramp down" line from
the original drawing that had been missing.
- Redraw the shifted-down curve to match the SVG geometry literally:
100 % flat from maxLevel → shiftLevel, then ramp shiftLevel →
startLevel down to 0 %, OFF below startLevel. Preview shows the
worst-case envelope (hold = 100 %); runtime hold is captured live.
- Validation extended: 0 < shiftArmPercent ≤ 100; ordering rules
preserved (start < shift ≤ max etc.).
- Auto-default shiftArmPercent to 95 when shift is enabled and the
current value is missing or out of range.
Dashboard example (examples/basic-dashboard.flow.json):
- Parser now reads `level.predicted.atequipment.default` etc. The
MeasurementContainer flatten format includes the implicit 'default'
childId; consumers must include it. Comment in the parser points
at the documenting source in generalFunctions.
Tests:
- test/basic: replace old level-armed-shift tests with two new ones
that exercise the hold-then-ramp arming, capture, hold, ramp-down,
disarm, and the bounce case (filling→draining→filling→draining
captures a fresh hold each time).
- test/integration/shifted-ramp-end-to-end.test.js: new file. Drives
Q_IN/Q_OUT through the full runtime tick with a controllable clock,
asserting the same hysteresis path the dashboard exercises.
- test/integration/basic-dashboard-flow.test.js: fixture keys updated
to the .default-suffixed form so they match the real flatten output.
56/56 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 11:46:46 +02:00
shiftArmPercent: { value: 95 },
feat(pumpingStation): realistic defaults, ramp-foot visual fix, manual-mode visibility, dashboard example
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>
2026-05-12 14:52:00 +02:00
startLevel: { value: 1 }, // m, pump-on threshold (engagement edge)
stopLevel: { value: 0.5 }, // m, pump-off threshold (hysteresis fall-back)
minLevel: { value: 0.3 }, // m, hard-stop (just above outflow pipe top)
maxLevel: { value: 3.8 }, // m, 100% demand saturation
2025-11-27 17:46:24 +01:00
flowSetpoint: { value: null },
flowDeadband: { value: null }
2025-10-07 18:05:54 +02:00
},
inputs: 1,
outputs: 3,
inputLabels: ["Input"],
outputLabels: ["process", "dbase", "parent"],
2025-10-14 13:51:32 +02:00
icon: "font-awesome/fa-tint",
2025-10-07 18:05:54 +02:00
label: function () {
2025-10-21 12:45:19 +02:00
return this.positionIcon + " PumpingStation";
2025-10-07 18:05:54 +02:00
},
2026-05-10 20:18:49 +02:00
oneditprepare: function () {
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
window.PSEditor.oneditprepare.call(this);
2025-10-07 18:05:54 +02:00
},
oneditsave: function () {
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
window.PSEditor.oneditsave.call(this);
2025-10-07 18:05:54 +02:00
},
2025-10-14 16:32:44 +02:00
2025-10-07 18:05:54 +02:00
});
< / script >
<!-- Main UI -->
2025-10-14 13:51:32 +02:00
< script type = "text/html" data-template-name = "pumpingStation" >
2025-10-07 18:05:54 +02:00
2025-11-27 17:46:24 +01:00
< h4 > Simulation< / h4 >
2025-10-07 18:05:54 +02:00
< div class = "form-row" >
2025-10-14 16:32:44 +02:00
< label for = "node-input-simulator" > < i class = "fa fa-play-circle" > < / i > Simulator< / label >
< input type = "checkbox" id = "node-input-simulator" style = "width:20px;vertical-align:baseline;" / >
< span > Run station in simulated mode< / span >
2025-10-07 18:05:54 +02:00
< / div >
2025-10-14 16:32:44 +02:00
< hr >
2025-11-27 17:46:24 +01:00
Editor: interactive basin diagram — inputs placed at each threshold line
Replaces the static parameters-diagram-above-form-rows layout with a
single interactive SVG where every threshold input sits directly on
the tank at its proportional y-position. Typing a value repositions
the corresponding line + input + label live.
What moved into the diagram (via <foreignObject> holding real
<input> elements with their existing node-input-* IDs so Node-RED
save/restore is untouched):
basinHeight — top of tank (fixed at rim by definition)
overflowLevel — weir crest (red, dashed)
maxLevel — 100 % demand line (orange, dashed)
startLevel — ramp-start line (green, dashed)
minLevel — MGC-shutdown line (purple, dashed)
inflowLevel — Inlet arrow + input on left
outflowLevel — Outlet arrow + input on right
dryRunLevel — read-only, computed from outflow × (1+dryRunPct/100)
Also in the diagram:
- Dead-volume band fills the area below outflowLevel dynamically
- Warning ribbon appears below the tank if ordering invariants break
(mirrors specificClass._validateThresholdOrdering)
- All positions scale against the user's basinHeight; if empty, a
default 5 m scale is used just to keep the diagram readable
What stayed as regular form rows:
- Basin Volume (m³) — not a height, can't be placed on a y-axis
- minLevel / startLevel / maxLevel were in the Control Strategy >
Level-based section; removed from there and moved into the diagram
(the level-based subsection now contains a one-line pointer)
- Safety % inputs (dryRun, overfill) stay in the Safety section with
their derived-level readouts, now synced with the diagram
No schema changes, no field additions, no behaviour changes in the
runtime. Pure editor-UX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 10:28:18 +02:00
< h4 > Basin parameters< / h4 >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< p style = "font-size:12px;color:#777;margin:0 0 8px 0;" > Heights are measured from the basin floor (0 m). Each input on the left controls a line in the diagram on the right — hover an input to highlight its line.< / p >
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< div id = "ps-basin-validation" style = "display:none;color:#C0392B;font-size:11px;margin:0 0 8px 0;border:1px solid #C0392B;border-radius:3px;padding:6px 8px;background:#FDECEA;" > < / div >
Editor: interactive basin diagram — inputs placed at each threshold line
Replaces the static parameters-diagram-above-form-rows layout with a
single interactive SVG where every threshold input sits directly on
the tank at its proportional y-position. Typing a value repositions
the corresponding line + input + label live.
What moved into the diagram (via <foreignObject> holding real
<input> elements with their existing node-input-* IDs so Node-RED
save/restore is untouched):
basinHeight — top of tank (fixed at rim by definition)
overflowLevel — weir crest (red, dashed)
maxLevel — 100 % demand line (orange, dashed)
startLevel — ramp-start line (green, dashed)
minLevel — MGC-shutdown line (purple, dashed)
inflowLevel — Inlet arrow + input on left
outflowLevel — Outlet arrow + input on right
dryRunLevel — read-only, computed from outflow × (1+dryRunPct/100)
Also in the diagram:
- Dead-volume band fills the area below outflowLevel dynamically
- Warning ribbon appears below the tank if ordering invariants break
(mirrors specificClass._validateThresholdOrdering)
- All positions scale against the user's basinHeight; if empty, a
default 5 m scale is used just to keep the diagram readable
What stayed as regular form rows:
- Basin Volume (m³) — not a height, can't be placed on a y-axis
- minLevel / startLevel / maxLevel were in the Control Strategy >
Level-based section; removed from there and moved into the diagram
(the level-based subsection now contains a one-line pointer)
- Safety % inputs (dryRun, overfill) stay in the Safety section with
their derived-level readouts, now synced with the diagram
No schema changes, no field additions, no behaviour changes in the
runtime. Pure editor-UX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 10:28:18 +02:00
< style >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
/* Two-column layout: stacked colour-coded inputs on the left,
SVG on the right. Hover an input row → its paired SVG line
(referenced by data-couples-line) gets a thicker stroke. */
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
.ps-diag { display:flex; gap:28px; align-items:flex-start; margin:0 0 14px 0; }
.ps-diag-side { width: 220px; flex: 0 0 220px; display:flex; flex-direction:column; gap:6px; }
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
.ps-diag-side .ps-row {
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
display:grid; grid-template-columns: minmax(0,1fr) 70px 16px; align-items:center;
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
gap:6px; padding:4px 6px 4px 10px; border-left:4px solid #ccc;
background:#fafafa; border-radius:3px; font-size:11px; cursor:pointer;
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
min-width:0;
Editor: interactive basin diagram — inputs placed at each threshold line
Replaces the static parameters-diagram-above-form-rows layout with a
single interactive SVG where every threshold input sits directly on
the tank at its proportional y-position. Typing a value repositions
the corresponding line + input + label live.
What moved into the diagram (via <foreignObject> holding real
<input> elements with their existing node-input-* IDs so Node-RED
save/restore is untouched):
basinHeight — top of tank (fixed at rim by definition)
overflowLevel — weir crest (red, dashed)
maxLevel — 100 % demand line (orange, dashed)
startLevel — ramp-start line (green, dashed)
minLevel — MGC-shutdown line (purple, dashed)
inflowLevel — Inlet arrow + input on left
outflowLevel — Outlet arrow + input on right
dryRunLevel — read-only, computed from outflow × (1+dryRunPct/100)
Also in the diagram:
- Dead-volume band fills the area below outflowLevel dynamically
- Warning ribbon appears below the tank if ordering invariants break
(mirrors specificClass._validateThresholdOrdering)
- All positions scale against the user's basinHeight; if empty, a
default 5 m scale is used just to keep the diagram readable
What stayed as regular form rows:
- Basin Volume (m³) — not a height, can't be placed on a y-axis
- minLevel / startLevel / maxLevel were in the Control Strategy >
Level-based section; removed from there and moved into the diagram
(the level-based subsection now contains a one-line pointer)
- Safety % inputs (dryRun, overfill) stay in the Safety section with
their derived-level readouts, now synced with the diagram
No schema changes, no field additions, no behaviour changes in the
runtime. Pure editor-UX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 10:28:18 +02:00
}
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
.ps-diag-side .ps-row:hover { background:#f0f0f0; }
.ps-diag-side .ps-row.ps-readonly { background:#fff; cursor:default; opacity:0.85; }
.ps-diag-side .ps-row label { font-weight:600; margin:0; line-height:1.2; }
.ps-diag-side .ps-row .ps-sub { grid-column:1; font-size:10px; color:#888; font-weight:400; }
.ps-diag-side .ps-row input[type=number] {
width:100%; height:22px; box-sizing:border-box; font-size:11px;
padding:1px 4px; margin:0; border:1px solid #ccc; border-radius:3px;
background:#fff;
}
.ps-diag-side .ps-row input[type=number]:focus { outline:1px solid #0c99d9; border-color:#0c99d9; }
.ps-diag-side .ps-row .ps-readonly-val {
font-family:monospace; font-size:11px; color:#666; text-align:right;
padding-right:4px;
}
.ps-diag-side .ps-row .ps-unit { color:#888; font-size:10px; }
.ps-diag-svg { flex:1; min-width:0; }
/* Border colours matched to each SVG line stroke. */
.ps-row[data-stroke="#333"] { border-left-color:#333; }
.ps-row[data-stroke="#C0392B"] { border-left-color:#C0392B; }
.ps-row[data-stroke="#1E8449"] { border-left-color:#1E8449; }
.ps-row[data-stroke="#1F4E79"] { border-left-color:#1F4E79; }
.ps-row[data-stroke="#D68910"] { border-left-color:#D68910; }
.ps-row[data-stroke="#888"] { border-left-color:#888; }
.ps-row[data-stroke="#333"] label { color:#333; }
.ps-row[data-stroke="#C0392B"] label { color:#C0392B; }
.ps-row[data-stroke="#1E8449"] label { color:#1E8449; }
.ps-row[data-stroke="#1F4E79"] label { color:#1F4E79; }
.ps-row[data-stroke="#D68910"] label { color:#D68910; }
.ps-row[data-stroke="#888"] label { color:#888; }
/* Highlight class applied to the SVG line during input row hover. */
.ps-line-highlight { stroke-width:3.5 !important; opacity:1 !important; }
Editor: interactive basin diagram — inputs placed at each threshold line
Replaces the static parameters-diagram-above-form-rows layout with a
single interactive SVG where every threshold input sits directly on
the tank at its proportional y-position. Typing a value repositions
the corresponding line + input + label live.
What moved into the diagram (via <foreignObject> holding real
<input> elements with their existing node-input-* IDs so Node-RED
save/restore is untouched):
basinHeight — top of tank (fixed at rim by definition)
overflowLevel — weir crest (red, dashed)
maxLevel — 100 % demand line (orange, dashed)
startLevel — ramp-start line (green, dashed)
minLevel — MGC-shutdown line (purple, dashed)
inflowLevel — Inlet arrow + input on left
outflowLevel — Outlet arrow + input on right
dryRunLevel — read-only, computed from outflow × (1+dryRunPct/100)
Also in the diagram:
- Dead-volume band fills the area below outflowLevel dynamically
- Warning ribbon appears below the tank if ordering invariants break
(mirrors specificClass._validateThresholdOrdering)
- All positions scale against the user's basinHeight; if empty, a
default 5 m scale is used just to keep the diagram readable
What stayed as regular form rows:
- Basin Volume (m³) — not a height, can't be placed on a y-axis
- minLevel / startLevel / maxLevel were in the Control Strategy >
Level-based section; removed from there and moved into the diagram
(the level-based subsection now contains a one-line pointer)
- Safety % inputs (dryRun, overfill) stay in the Safety section with
their derived-level readouts, now synced with the diagram
No schema changes, no field additions, no behaviour changes in the
runtime. Pure editor-UX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 10:28:18 +02:00
< / style >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
<!--
============================================================
BASIN DIAGRAM (ps-basin-diagram)
============================================================
Coordinate system: SVG viewBox is 520 (wide) × 430 (tall).
Origin (0,0) is top-left. +x goes right. +y goes DOWN.
Bigger y = lower on screen.
X-LANES (all viewBox units, edit any of these to shift a column):
x ≈ 5..75 left input column (inlet number input)
x = 80 inlet unit "m"
x = 135 inlet text labels (right-aligned, anchor at x)
x = 140..200 inlet arrow (line + arrow head into tank)
x = 200..320 tank body (rect.x=200 width=120) — interior 201..319
x = 195/325 threshold tick lines (extend 5 px outside tank)
x = 260 mid-tank zone labels (centered)
x = 320..360 outlet arrow
x = 330 right-side label column ("overflowLevel", "Outlet", …)
x = 365 outlet sub-text column
x = 425..495 right input column (foreignObject inputs, width=70)
x = 500 right unit column ("m", "m³")
Y-COORDINATES:
y = 40 tank rim (basinHeight line)
y = 380 tank floor / datum
y = 410 ordering warning ribbon
y = 19,44 "basin volume" / "basinHeight" labels (static)
Threshold rows (overflowLevel, highVolumeSafetyLevel, inflowLevelGuide,
dryRunLevel, outflowLevel, basinHeight tick) get y assigned
DYNAMICALLY by the redraw() function around line 250-340 below.
Their input row may be NUDGED off ideal-y to avoid overlap; a leader
line (ps-leader-*) is then drawn between threshold y and input y.
Zone-label rows (ps-zone-*) get y assigned dynamically to the midpoint
between adjacent thresholds; they hide if the gap is too small.
HOW TO NUDGE OVERLAPPING LABELS:
- For STATIC y values (hardcoded below): edit the inline y attribute.
- For DYNAMIC y values: search redraw() for the element id and adjust
the layout math (e.g. NUDGE_PX or the threshold-stack ordering).
- For x: every label column above can be shifted by editing the inline
x attribute on the relevant < text > /< line > /< foreignObject > .
Note: dynamic line/label positioning lives in oneditprepare → redraw()
further up in this file. Changing only the inline y here will be
overridden on first redraw for any element whose id appears in redraw().
============================================================
-->
< div class = "ps-diag" id = "ps-basin-wrap" >
<!-- LEFT: stacked colour - coded inputs. Hover a row → its paired SVG
line (data-couples-line) is highlighted in the diagram. -->
< div class = "ps-diag-side" >
< div class = "ps-row" data-stroke = "#333" style = "cursor:default;" >
< div > < label > basinVolume< / label > < div class = "ps-sub" > total empty volume (no marker)< / div > < / div >
< input type = "number" id = "node-input-basinVolume" min = "0" step = "0.1" / >
< span class = "ps-unit" > m³< / span >
< / div >
< div class = "ps-row" data-stroke = "#333" data-couples-line = "ps-line-basinHeight" >
< div > < label > basinHeight< / label > < div class = "ps-sub" > floor → rim< / div > < / div >
< input type = "number" id = "node-input-basinHeight" min = "0" step = "0.1" / >
< span class = "ps-unit" > m< / span >
< / div >
< div class = "ps-row" data-stroke = "#C0392B" data-couples-line = "ps-line-overflowLevel" >
< div > < label > overflowLevel< / label > < div class = "ps-sub" > spill height< / div > < / div >
< input type = "number" id = "node-input-overflowLevel" min = "0" step = "0.01" / >
< span class = "ps-unit" > m< / span >
< / div >
< div class = "ps-row ps-readonly" data-stroke = "#D68910" data-couples-line = "ps-line-highVolumeSafetyLevel" >
< div > < label > highVolumeSafety< / label > < div class = "ps-sub" > derived (overflow × %)< / div > < / div >
< span id = "derived-highVolumeSafetyLevel" class = "ps-readonly-val" > — m< / span >
< span class = "ps-unit" > m< / span >
< / div >
< div class = "ps-row" data-stroke = "#1F4E79" data-couples-line = "ps-line-inflowLevel" >
< div > < label > inflowLevel< / label > < div class = "ps-sub" > bottom of inlet pipe< / div > < / div >
< input type = "number" id = "node-input-inflowLevel" min = "0" step = "0.01" / >
< span class = "ps-unit" > m< / span >
< / div >
< div class = "ps-row ps-readonly" data-stroke = "#C0392B" data-couples-line = "ps-line-dryRunLevel" >
< div > < label > dryRunLevel< / label > < div class = "ps-sub" > derived (outflow × dry%)< / div > < / div >
< span id = "derived-dryRunLevel" class = "ps-readonly-val" > — m< / span >
< span class = "ps-unit" > m< / span >
< / div >
< div class = "ps-row" data-stroke = "#1F4E79" data-couples-line = "ps-line-outflowLevel" >
< div > < label > outflowLevel< / label > < div class = "ps-sub" > top of outlet pipe< / div > < / div >
< input type = "number" id = "node-input-outflowLevel" min = "0" step = "0.01" / >
< span class = "ps-unit" > m< / span >
< / div >
< div class = "ps-row ps-readonly" data-stroke = "#888" style = "cursor:default;" >
< div > < label > basinBottomRef< / label > < div class = "ps-sub" > floor above NAP (no marker)< / div > < / div >
< input type = "number" id = "node-input-basinBottomRef" step = "0.01" / >
< span class = "ps-unit" > m< / span >
< / div >
< / div >
<!-- RIGHT: SVG. The viewBox is now narrower (320 wide) since the right
input column is gone — labels render inside the tank's right margin. -->
< svg id = "ps-basin-diagram" class = "ps-diag-svg" xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 360 430"
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
style="display:block;width:100%;max-width:360px;background:#fff;border:1px solid #e5e5e5;border-radius:4px;"
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
font-family="Arial,sans-serif" font-size="11">
< defs >
< marker id = "ps-arrow" viewBox = "0 0 10 10" refX = "9" refY = "5" markerWidth = "7" markerHeight = "7" orient = "auto-start-reverse" >
< path d = "M 0 0 L 10 5 L 0 10 z" fill = "#1F4E79" / >
< / marker >
< / defs >
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
<!-- Tank body — shifted right (x=145, width=110) to give the inlet
sub-label "bottom of pipe" room on the left without clipping.
Threshold tick lines extend 5 px outside the tank walls. -->
< rect x = "145" y = "40" width = "110" height = "340" fill = "#F0F8FF" stroke = "#333" stroke-width = "1.5" / >
< rect id = "ps-deadvol" x = "146" width = "108" fill = "#AACCE0" / >
<!-- Mid - tank zone labels — centred at x=200 (tank centre). -->
< text id = "ps-zone-spare" x = "200" text-anchor = "middle" fill = "#B78200" font-size = "10" font-style = "italic" visibility = "hidden" > Spare< / text >
< text id = "ps-zone-sewage" x = "200" text-anchor = "middle" fill = "#1F4E79" font-size = "10" font-style = "italic" visibility = "hidden" > Sewage + buffer< / text >
< text id = "ps-zone-buffer1" x = "200" text-anchor = "middle" fill = "#1F4E79" font-size = "10" font-style = "italic" visibility = "hidden" > Buffer< / text >
< text id = "ps-zone-buffer2" x = "200" text-anchor = "middle" fill = "#1F4E79" font-size = "10" font-style = "italic" visibility = "hidden" > Buffer< / text >
< text id = "ps-zone-dead" x = "200" text-anchor = "middle" fill = "#444" font-size = "10" font-style = "italic" visibility = "hidden" > Dead vol< / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
<!-- basinHeight tick at tank rim (y=40, static). -->
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< line id = "ps-line-basinHeight" x1 = "140" y1 = "40" x2 = "260" y2 = "40" stroke = "#333" stroke-width = "1.5" / >
< text id = "ps-label-basinHeight" x = "265" y = "44" fill = "#333" > basinHeight< / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< line id = "ps-line-overflowLevel" x1 = "140" x2 = "260" stroke = "#C0392B" stroke-dasharray = "4 2" stroke-width = "1.5" / >
< text id = "ps-label-overflowLevel" x = "265" fill = "#C0392B" > overflowLevel< / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< line id = "ps-line-highVolumeSafetyLevel" x1 = "140" x2 = "260" stroke = "#D68910" stroke-dasharray = "1 2" stroke-width = "1" opacity = "0.7" / >
< text id = "ps-label-highVolumeSafetyLevel" x = "265" fill = "#D68910" font-size = "10" font-style = "italic" > highVolSafety< / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< line id = "ps-line-inflowLevelGuide" x1 = "145" x2 = "255" stroke = "#1F4E79" stroke-dasharray = "2 3" stroke-width = "1" opacity = "0.55" / >
< text id = "ps-label-inflowLevelGuide" x = "265" fill = "#1F4E79" font-size = "10" font-style = "italic" > inlet invert< / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< line id = "ps-line-inflowLevel" x1 = "85" x2 = "145" stroke = "#1F4E79" stroke-width = "2" marker-end = "url(#ps-arrow)" / >
< text id = "ps-label-inflowLevel" x = "80" text-anchor = "end" fill = "#1F4E79" font-weight = "bold" > Inlet< / text >
< text id = "ps-sub-inflowLevel" x = "80" text-anchor = "end" fill = "#777" font-size = "9" > bottom of pipe< / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< line id = "ps-line-dryRunLevel" x1 = "140" x2 = "260" stroke = "#C0392B" stroke-dasharray = "1 2" stroke-width = "1" opacity = "0.6" / >
< text id = "ps-label-dryRunLevel" x = "265" fill = "#C0392B" font-size = "10" font-style = "italic" > dryRunLevel< / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< line id = "ps-line-outflowLevel" x1 = "255" x2 = "295" stroke = "#1F4E79" stroke-width = "2" marker-end = "url(#ps-arrow)" / >
< text id = "ps-label-outflowLevel" x = "300" fill = "#1F4E79" font-weight = "bold" > Outlet< / text >
< text id = "ps-sub-outflowLevel" x = "300" fill = "#777" font-size = "9" > top of pipe< / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
<!-- Floor / datum — datum label sits BELOW the tank (y=395) so it
never collides with the Outlet / top-of-pipe sub-label when
outflowLevel is near the floor. -->
< line x1 = "140" y1 = "380" x2 = "260" y2 = "380" stroke = "#000" stroke-width = "2" / >
< text x = "200" y = "395" text-anchor = "middle" fill = "#000" font-size = "10" > 0 m (datum)< / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
<!-- Ordering - warning ribbon -->
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< text id = "ps-warning" x = "200" y = "410" text-anchor = "middle" fill = "#C0392B" font-size = "10" font-style = "italic" visibility = "hidden" > < / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< / svg >
< / div >
Editor: inline parameters diagram at top of Basin Geometry
~3 KB inline SVG showing the 5 threshold lines + inlet/outlet pipe
arrows + floor datum, using the same names as the editor fields
(basinHeight, overflowLevel, maxLevel, startLevel, minLevel,
dryRunLevel). No new inputs — purely a visual reminder of what
each field refers to, so operators don't have to alt-tab to the
wiki to figure out which pipe edge to measure.
Wrapped in <details open> so users can collapse it once they
know the layout — no forced scroll through the diagram on every
edit session.
Matches the vocabulary in wiki/diagrams/basin-model.drawio.svg
(inlet = bottom of pipe, outlet = top of pipe, 0 m datum at
basin floor, dryRunLevel derived from %).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 10:19:23 +02:00
2025-10-14 16:32:44 +02:00
< hr >
2025-11-27 17:46:24 +01:00
< h4 > Control Strategy< / h4 >
< div class = "form-row" >
< label for = "node-input-controlMode" > < i class = "fa fa-sliders" > < / i > Control mode< / label >
< select id = "node-input-controlMode" >
< option value = "levelbased" > Level-based< / option >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< option value = "manual" > Manual< / option >
2025-11-27 17:46:24 +01:00
< / select >
< / div >
< div id = "ps-mode-levelbased" class = "ps-mode-section" >
< div class = "form-row" >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< label for = "node-input-levelCurveType" > Curve< / label >
< select id = "node-input-levelCurveType" style = "width:60%;" >
< option value = "linear" > Linear< / option >
< option value = "log" > Log - fast early response< / option >
< / select >
< / div >
< div class = "form-row" id = "ps-log-factor-row" style = "display:none;" >
< label for = "node-input-logCurveFactor" > Log shape factor< / label >
< input type = "number" id = "node-input-logCurveFactor" min = "0.001" step = "0.1" style = "width:100px;" / >
2025-11-27 17:46:24 +01:00
< / div >
< div class = "form-row" >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< label for = "node-input-enableShiftedRamp" style = "width:auto;" >
< input type = "checkbox" id = "node-input-enableShiftedRamp" style = "width:auto;vertical-align:middle;margin-right:6px;" / >
Enable shifted ramp (hysteresis)
< / label >
< / div >
< div id = "ps-mode-validation" style = "display:none;color:#C0392B;font-size:11px;margin:4px 0 8px 0;border:1px solid #C0392B;border-radius:3px;padding:6px 8px;background:#FDECEA;" > < / div >
<!--
============================================================
LEVEL-BASED MODE PREVIEW (ps-levelbased-mode-diagram)
============================================================
Coordinate system: SVG viewBox is 430 (wide) × 185 (tall).
Origin (0,0) top-left. +x right. +y DOWN (so y=24 is HIGH on screen,
y=158 is at the baseline).
X-AXIS (level, in viewBox px) — controlled by redrawModeDiagram() in
the oneditprepare script above. The function maps the user's
startLevel/inflowLevel/maxLevel/shiftLevel onto the px window
x0=52 (left axis) → x1=390 (right end of plot).
DO NOT hardcode x for ps-mode-line-* / ps-mode-label-*; they're
rewritten on every input change.
Y-AXIS (process demand %):
y=24 100% (top of plot)
y=140 0% (baseline / x-axis)
y=160 OFF baseline (pink dashed)
y=180 axis labels under the plot ("dry run","start","inlet","max","overflow","shift")
y=205 legend captions (one row, BELOW axis labels — moved here to stop
colliding with the title row at y=14)
y=14 curve-type title only ("linear curve" / "log curve"), centered.
WHAT IS STATIC vs DYNAMIC:
STATIC (edit inline below): viewBox bounds, axis lines, "0%"/"100%"
tick labels, in-plot caption x/y, axis-label y=176.
DYNAMIC (edit in JS): every ps-mode-line-*, ps-mode-label-* x;
ps-mode-curve-up/down points; visibility of shift elements.
HOW TO NUDGE OVERLAPPING TEXT:
- Move the curve-type caption: edit the x="220" y="18" on
#ps-mode-curve-label.
- Move axis labels (start/inlet/max/shift) UP or DOWN: edit y="176".
(To move them left/right relative to the line, edit redrawModeDiagram
in the script — the x is set there.)
- Move the legend captions: edit x="280" y="54" / y="72" on
#ps-mode-curve-up-label / #ps-mode-curve-down-label.
- To resize the plot box, change viewBox + the x0/x1/y0/y1 constants
in redrawModeDiagram() to match.
============================================================
-->
< div class = "ps-diag" id = "ps-mode-wrap" >
<!-- LEFT side - panel: only the level - based mode's editable inputs +
read-only displays for derived/related levels (so user has all
level context in one column). Hover-coupled to the SVG markers. -->
< div class = "ps-diag-side" >
< div class = "ps-row ps-readonly" data-stroke = "#C0392B" data-couples-line = "ps-mode-line-dryRunLevel" >
< div > < label > dryRunLevel< / label > < div class = "ps-sub" > derived< / div > < / div >
< span id = "ps-mode-readout-dryRun" class = "ps-readonly-val" > — m< / span >
< span class = "ps-unit" > m< / span >
< / div >
< div class = "ps-row" data-stroke = "#1E8449" data-couples-line = "ps-mode-line-startLevel" >
< div > < label > startLevel< / label > < div class = "ps-sub" > pump-on threshold< / div > < / div >
< input type = "number" id = "node-input-startLevel" min = "0" step = "0.01" / >
< span class = "ps-unit" > m< / span >
< / div >
2026-05-08 11:20:36 +02:00
< div class = "ps-row" data-stroke = "#7D3C98" data-couples-line = "ps-mode-line-stopLevel" >
< div > < label > stopLevel< / label > < div class = "ps-sub" > pump-off threshold (optional, ≤ startLevel)< / div > < / div >
< input type = "number" id = "node-input-stopLevel" min = "0" step = "0.01" / >
< span class = "ps-unit" > m< / span >
< / div >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< div class = "ps-row ps-readonly" data-stroke = "#1F4E79" data-couples-line = "ps-mode-line-inflowLevel" >
< div > < label > inflowLevel< / label > < div class = "ps-sub" > from basin above< / div > < / div >
< span id = "ps-mode-readout-inflow" class = "ps-readonly-val" > — m< / span >
< span class = "ps-unit" > m< / span >
< / div >
< div class = "ps-row" data-stroke = "#D68910" data-couples-line = "ps-mode-line-maxLevel" >
< div > < label > maxLevel< / label > < div class = "ps-sub" > 100% saturation< / div > < / div >
< input type = "number" id = "node-input-maxLevel" min = "0" step = "0.01" / >
< span class = "ps-unit" > m< / span >
< / div >
< div class = "ps-row" id = "ps-shiftLevel-row" data-stroke = "#D68910" data-couples-line = "ps-mode-line-shiftLevel" style = "display:none;" >
Hold-then-ramp shift semantics + shiftArmPercent + e2e tests
Runtime (specificClass.js):
- Replace the "shift left both ramp ends" geometry with a true
hold-then-ramp hysteresis driven by output %, not level:
• Up-curve % crosses shiftArmPercent on the way up → ARM.
• Filling→draining transition while armed → capture the up-curve %
at that moment as _shiftHoldValue.
• Draining + level ≥ shiftLevel → output stays at _shiftHoldValue
(horizontal hold, matching the dashed segment in the SVG).
• Draining + level in [start, shift] → output ramps holdValue → 0 %
along the same curve shape (linear or log) as the up curve.
• Draining + level < startLevel → 0 % AND disarm.
• Returning to filling clears holdValue, stays armed; next drain
transition captures a fresh hold so bouncing fills rearm cleanly.
• Disarm only when level ≤ startLevel.
- New _curveShape(x) helper for shared linear/log shaping.
- Removed legacy _levelBasedRampStart / _levelBasedRampTop /
_updateShiftArmed in favour of the inline state machine.
Adapter (nodeClass.js):
- Pipe shiftArmPercent through to control.levelbased.
Editor (pumpingStation.html + src/editor/):
- Add shiftArmPercent input row (% with unit) to the mode side panel
(only shown when shifted ramp is enabled). Default 95 %.
- Add the horizontal arming-% line + label inside the mode SVG —
this is the "% Threshold triggering shifted ramp down" line from
the original drawing that had been missing.
- Redraw the shifted-down curve to match the SVG geometry literally:
100 % flat from maxLevel → shiftLevel, then ramp shiftLevel →
startLevel down to 0 %, OFF below startLevel. Preview shows the
worst-case envelope (hold = 100 %); runtime hold is captured live.
- Validation extended: 0 < shiftArmPercent ≤ 100; ordering rules
preserved (start < shift ≤ max etc.).
- Auto-default shiftArmPercent to 95 when shift is enabled and the
current value is missing or out of range.
Dashboard example (examples/basic-dashboard.flow.json):
- Parser now reads `level.predicted.atequipment.default` etc. The
MeasurementContainer flatten format includes the implicit 'default'
childId; consumers must include it. Comment in the parser points
at the documenting source in generalFunctions.
Tests:
- test/basic: replace old level-armed-shift tests with two new ones
that exercise the hold-then-ramp arming, capture, hold, ramp-down,
disarm, and the bounce case (filling→draining→filling→draining
captures a fresh hold each time).
- test/integration/shifted-ramp-end-to-end.test.js: new file. Drives
Q_IN/Q_OUT through the full runtime tick with a controllable clock,
asserting the same hysteresis path the dashboard exercises.
- test/integration/basic-dashboard-flow.test.js: fixture keys updated
to the .default-suffixed form so they match the real flatten output.
56/56 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 11:46:46 +02:00
< div > < label > shiftLevel< / label > < div class = "ps-sub" > held output drops here< / div > < / div >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< input type = "number" id = "node-input-shiftLevel" min = "0" step = "0.01" / >
< span class = "ps-unit" > m< / span >
< / div >
Hold-then-ramp shift semantics + shiftArmPercent + e2e tests
Runtime (specificClass.js):
- Replace the "shift left both ramp ends" geometry with a true
hold-then-ramp hysteresis driven by output %, not level:
• Up-curve % crosses shiftArmPercent on the way up → ARM.
• Filling→draining transition while armed → capture the up-curve %
at that moment as _shiftHoldValue.
• Draining + level ≥ shiftLevel → output stays at _shiftHoldValue
(horizontal hold, matching the dashed segment in the SVG).
• Draining + level in [start, shift] → output ramps holdValue → 0 %
along the same curve shape (linear or log) as the up curve.
• Draining + level < startLevel → 0 % AND disarm.
• Returning to filling clears holdValue, stays armed; next drain
transition captures a fresh hold so bouncing fills rearm cleanly.
• Disarm only when level ≤ startLevel.
- New _curveShape(x) helper for shared linear/log shaping.
- Removed legacy _levelBasedRampStart / _levelBasedRampTop /
_updateShiftArmed in favour of the inline state machine.
Adapter (nodeClass.js):
- Pipe shiftArmPercent through to control.levelbased.
Editor (pumpingStation.html + src/editor/):
- Add shiftArmPercent input row (% with unit) to the mode side panel
(only shown when shifted ramp is enabled). Default 95 %.
- Add the horizontal arming-% line + label inside the mode SVG —
this is the "% Threshold triggering shifted ramp down" line from
the original drawing that had been missing.
- Redraw the shifted-down curve to match the SVG geometry literally:
100 % flat from maxLevel → shiftLevel, then ramp shiftLevel →
startLevel down to 0 %, OFF below startLevel. Preview shows the
worst-case envelope (hold = 100 %); runtime hold is captured live.
- Validation extended: 0 < shiftArmPercent ≤ 100; ordering rules
preserved (start < shift ≤ max etc.).
- Auto-default shiftArmPercent to 95 when shift is enabled and the
current value is missing or out of range.
Dashboard example (examples/basic-dashboard.flow.json):
- Parser now reads `level.predicted.atequipment.default` etc. The
MeasurementContainer flatten format includes the implicit 'default'
childId; consumers must include it. Comment in the parser points
at the documenting source in generalFunctions.
Tests:
- test/basic: replace old level-armed-shift tests with two new ones
that exercise the hold-then-ramp arming, capture, hold, ramp-down,
disarm, and the bounce case (filling→draining→filling→draining
captures a fresh hold each time).
- test/integration/shifted-ramp-end-to-end.test.js: new file. Drives
Q_IN/Q_OUT through the full runtime tick with a controllable clock,
asserting the same hysteresis path the dashboard exercises.
- test/integration/basic-dashboard-flow.test.js: fixture keys updated
to the .default-suffixed form so they match the real flatten output.
56/56 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 11:46:46 +02:00
< div class = "ps-row" id = "ps-shiftArmPercent-row" data-stroke = "#D68910" data-couples-line = "ps-mode-line-armPercent" style = "display:none;" >
< div > < label > shiftArmPercent< / label > < div class = "ps-sub" > arms when output % crosses this< / div > < / div >
< input type = "number" id = "node-input-shiftArmPercent" min = "0" max = "100" step = "1" / >
< span class = "ps-unit" > %< / span >
< / div >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< div class = "ps-row ps-readonly" data-stroke = "#C0392B" data-couples-line = "ps-mode-line-overflowLevel" >
< div > < label > overflowLevel< / label > < div class = "ps-sub" > from basin above< / div > < / div >
< span id = "ps-mode-readout-overflow" class = "ps-readonly-val" > — m< / span >
< span class = "ps-unit" > m< / span >
< / div >
< / div >
< svg id = "ps-levelbased-mode-diagram" class = "ps-diag-svg" xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 430 215"
style="display:block;width:100%;max-width:540px;background:#fff;border:1px solid #e5e5e5;border-radius:4px;"
font-family="Arial,sans-serif" font-size="11">
<!-- ZONE BANDS — drawn FIRST so they sit behind axes and curves.
x is set DYNAMICALLY by redrawModeDiagram(); y/height span the full plot (24..160).
Order from leftmost to rightmost: dryRun (red) | safetyLow (orange) | safe (green) |
safetyHigh (orange) | overflow (red).
-->
< rect id = "ps-zone-dryRun" y = "24" height = "136" fill = "#fdecea" / >
< rect id = "ps-zone-safetyLow" y = "24" height = "136" fill = "#fef5e7" / >
< rect id = "ps-zone-safe" y = "24" height = "136" fill = "#eafaf1" / >
< rect id = "ps-zone-safetyHigh" y = "24" height = "136" fill = "#fef5e7" / >
< rect id = "ps-zone-overflow" y = "24" height = "136" fill = "#fdecea" / >
<!-- X - axis (0% baseline) at y=140; y axis at x=52 (top y=24). Plot range: y=24..140. -->
< line x1 = "52" y1 = "140" x2 = "402" y2 = "140" stroke = "#333" / >
< line x1 = "52" y1 = "140" x2 = "52" y2 = "24" stroke = "#333" / >
<!-- OFF tier baseline at y=160 (20px below 0% baseline). pink line drawn dynamically by curve. -->
< line x1 = "52" y1 = "160" x2 = "402" y2 = "160" stroke = "#E08080" stroke-dasharray = "2 3" / >
<!-- Y - axis tick labels (x=4, right - aligned via text - anchor="end" at x=50 for tighter alignment). -->
< text x = "50" y = "27" text-anchor = "end" fill = "#333" > 100%< / text >
< text x = "50" y = "143" text-anchor = "end" fill = "#333" > 0%< / text >
< text x = "50" y = "163" text-anchor = "end" fill = "#E08080" > OFF< / text >
<!-- Plot title above 100% line. -->
< text id = "ps-mode-curve-label" x = "220" y = "14" text-anchor = "middle" fill = "#555" > linear curve< / text >
<!-- Curves drawn dynamically. Up curve foot=inlet→top=max. Down curve foot=start→top=shiftLevel (visible when shift enabled). -->
< polyline id = "ps-mode-curve-up" fill = "none" stroke = "#1E8449" stroke-width = "2.5" points = "" / >
< polyline id = "ps-mode-curve-down" fill = "none" stroke = "#D68910" stroke-width = "2" stroke-dasharray = "5 3" points = "" style = "display:none;" / >
<!-- Vertical level - marker lines — span y=24..140 (top to baseline only, NOT into OFF tier). x set dynamically. -->
< line id = "ps-mode-line-dryRunLevel" y1 = "24" y2 = "140" stroke = "#C0392B" stroke-dasharray = "2 2" / >
< line id = "ps-mode-line-startLevel" y1 = "24" y2 = "140" stroke = "#1E8449" stroke-dasharray = "2 2" / >
2026-05-08 11:20:36 +02:00
< line id = "ps-mode-line-stopLevel" y1 = "24" y2 = "140" stroke = "#7D3C98" stroke-dasharray = "2 2" / >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< line id = "ps-mode-line-inflowLevel" y1 = "24" y2 = "140" stroke = "#1F4E79" stroke-dasharray = "2 2" / >
< line id = "ps-mode-line-maxLevel" y1 = "24" y2 = "140" stroke = "#D68910" stroke-dasharray = "2 2" / >
< line id = "ps-mode-line-overflowLevel" y1 = "24" y2 = "140" stroke = "#C0392B" stroke-dasharray = "2 2" / >
< line id = "ps-mode-line-shiftLevel" y1 = "24" y2 = "140" stroke = "#D68910" stroke-dasharray = "2 2" style = "display:none;" / >
Hold-then-ramp shift semantics + shiftArmPercent + e2e tests
Runtime (specificClass.js):
- Replace the "shift left both ramp ends" geometry with a true
hold-then-ramp hysteresis driven by output %, not level:
• Up-curve % crosses shiftArmPercent on the way up → ARM.
• Filling→draining transition while armed → capture the up-curve %
at that moment as _shiftHoldValue.
• Draining + level ≥ shiftLevel → output stays at _shiftHoldValue
(horizontal hold, matching the dashed segment in the SVG).
• Draining + level in [start, shift] → output ramps holdValue → 0 %
along the same curve shape (linear or log) as the up curve.
• Draining + level < startLevel → 0 % AND disarm.
• Returning to filling clears holdValue, stays armed; next drain
transition captures a fresh hold so bouncing fills rearm cleanly.
• Disarm only when level ≤ startLevel.
- New _curveShape(x) helper for shared linear/log shaping.
- Removed legacy _levelBasedRampStart / _levelBasedRampTop /
_updateShiftArmed in favour of the inline state machine.
Adapter (nodeClass.js):
- Pipe shiftArmPercent through to control.levelbased.
Editor (pumpingStation.html + src/editor/):
- Add shiftArmPercent input row (% with unit) to the mode side panel
(only shown when shifted ramp is enabled). Default 95 %.
- Add the horizontal arming-% line + label inside the mode SVG —
this is the "% Threshold triggering shifted ramp down" line from
the original drawing that had been missing.
- Redraw the shifted-down curve to match the SVG geometry literally:
100 % flat from maxLevel → shiftLevel, then ramp shiftLevel →
startLevel down to 0 %, OFF below startLevel. Preview shows the
worst-case envelope (hold = 100 %); runtime hold is captured live.
- Validation extended: 0 < shiftArmPercent ≤ 100; ordering rules
preserved (start < shift ≤ max etc.).
- Auto-default shiftArmPercent to 95 when shift is enabled and the
current value is missing or out of range.
Dashboard example (examples/basic-dashboard.flow.json):
- Parser now reads `level.predicted.atequipment.default` etc. The
MeasurementContainer flatten format includes the implicit 'default'
childId; consumers must include it. Comment in the parser points
at the documenting source in generalFunctions.
Tests:
- test/basic: replace old level-armed-shift tests with two new ones
that exercise the hold-then-ramp arming, capture, hold, ramp-down,
disarm, and the bounce case (filling→draining→filling→draining
captures a fresh hold each time).
- test/integration/shifted-ramp-end-to-end.test.js: new file. Drives
Q_IN/Q_OUT through the full runtime tick with a controllable clock,
asserting the same hysteresis path the dashboard exercises.
- test/integration/basic-dashboard-flow.test.js: fixture keys updated
to the .default-suffixed form so they match the real flatten output.
56/56 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 11:46:46 +02:00
<!-- Horizontal arming - % line — y is set DYNAMICALLY by the JS to the
shiftArmPercent value (in plot-y space). Spans full plot width. -->
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< line id = "ps-mode-line-armPercent" x1 = "52" x2 = "392" stroke = "#D68910" stroke-dasharray = "4 3" stroke-width = "1" opacity = "0.7" style = "display:none;" / >
< text id = "ps-mode-label-armPercent" x = "394" text-anchor = "start" fill = "#D68910" font-size = "9" style = "display:none;" > arm%< / text >
<!-- Axis labels under the plot were removed — they crowded each other
when levels were close. Identification comes from the line colour
(matched to the side-panel input row) and hover-coupling. -->
<!-- Empty <text> stubs kept for the redraw loop's getElementById calls
(cheaper than guarding each one). They're hidden via display:none. -->
< text id = "ps-mode-label-dryRunLevel" style = "display:none;" > < / text >
< text id = "ps-mode-label-startLevel" style = "display:none;" > < / text >
2026-05-08 11:20:36 +02:00
< text id = "ps-mode-label-stopLevel" style = "display:none;" > < / text >
Editor: dynamic input bounds + full hierarchy validation, layout polish
Bounds (new src/editor/bounds.js):
- Sets HTML5 min/max on every level + percent input each redraw,
derived from the current values of related inputs so the spinner
stops at the basin hierarchy:
0 < outflowLevel < dryRunLevel < startLevel ≤ inflowLevel
≤ shiftLevel ≤ maxLevel ≤ overflowLevel ≤ basinHeight
- dryRunPercent capped so dryRunLevel ≤ startLevel given current outflow.
- shiftArmPercent ∈ [1, 100]; highVolumeSafety% ∈ [1, 100].
Validation:
- New visible ribbon above the basin diagram (#ps-basin-validation)
listing every hierarchy violation. The in-SVG warning text is now a
small reminder ("⚠ N ordering issues").
- basin-diagram.js owns hierarchy issues; mode-preview.js trimmed to
only own shift-specific issues (shift > start, shift ≤ max,
shiftArmPercent range, shiftLevel required-when-enabled).
- oneditsave blocks Deploy on the union of _psBasinValidationIssues
and _psModeValidationIssues with a RED.notify listing all problems.
Layout polish:
- Side panel widened to 220 px with minmax(0, 1fr) first column so long
labels can no longer push the rows past the panel edge.
- Basin SVG max-width 380 → 360, gap between side panel and SVG bumped
14 → 28 px. Tank shifted right (x=145 width=110) so the inlet
"bottom of pipe" sub-label is no longer clipped on the left edge.
- "0 m (datum)" moved below the tank (y=395, centred) so it can't
collide with "Outlet / top of pipe" when outflowLevel is near floor.
- Zone labels shortened (Spare / Sewage + buffer / Buffer / Dead vol)
and only show when the bracketing thresholds are ≥ 28 px apart, so
they never sit on a threshold label.
- Mode preview axis labels under the chart removed — line colour +
side-panel labels + hover-couple already identify each line. Stub
<text> elements left hidden to keep the redraw loop simple. Arm-%
line + label trimmed in 10 px on the right so they're not clipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:10:22 +02:00
< text id = "ps-mode-label-inflowLevel" style = "display:none;" > < / text >
< text id = "ps-mode-label-maxLevel" style = "display:none;" > < / text >
< text id = "ps-mode-label-overflowLevel" style = "display:none;" > < / text >
< text id = "ps-mode-label-shiftLevel" style = "display:none;" > < / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
<!-- Legend captions — placed BELOW the axis labels (y=200) on their own row,
so they never collide with the title (y=14). Up-caption left-aligned at
x=60; down-caption to its right at x=210. Both font-size 10. -->
< text id = "ps-mode-curve-up-label" x = "60" y = "205" fill = "#1E8449" font-size = "10" > — ramp inlet→max< / text >
Hold-then-ramp shift semantics + shiftArmPercent + e2e tests
Runtime (specificClass.js):
- Replace the "shift left both ramp ends" geometry with a true
hold-then-ramp hysteresis driven by output %, not level:
• Up-curve % crosses shiftArmPercent on the way up → ARM.
• Filling→draining transition while armed → capture the up-curve %
at that moment as _shiftHoldValue.
• Draining + level ≥ shiftLevel → output stays at _shiftHoldValue
(horizontal hold, matching the dashed segment in the SVG).
• Draining + level in [start, shift] → output ramps holdValue → 0 %
along the same curve shape (linear or log) as the up curve.
• Draining + level < startLevel → 0 % AND disarm.
• Returning to filling clears holdValue, stays armed; next drain
transition captures a fresh hold so bouncing fills rearm cleanly.
• Disarm only when level ≤ startLevel.
- New _curveShape(x) helper for shared linear/log shaping.
- Removed legacy _levelBasedRampStart / _levelBasedRampTop /
_updateShiftArmed in favour of the inline state machine.
Adapter (nodeClass.js):
- Pipe shiftArmPercent through to control.levelbased.
Editor (pumpingStation.html + src/editor/):
- Add shiftArmPercent input row (% with unit) to the mode side panel
(only shown when shifted ramp is enabled). Default 95 %.
- Add the horizontal arming-% line + label inside the mode SVG —
this is the "% Threshold triggering shifted ramp down" line from
the original drawing that had been missing.
- Redraw the shifted-down curve to match the SVG geometry literally:
100 % flat from maxLevel → shiftLevel, then ramp shiftLevel →
startLevel down to 0 %, OFF below startLevel. Preview shows the
worst-case envelope (hold = 100 %); runtime hold is captured live.
- Validation extended: 0 < shiftArmPercent ≤ 100; ordering rules
preserved (start < shift ≤ max etc.).
- Auto-default shiftArmPercent to 95 when shift is enabled and the
current value is missing or out of range.
Dashboard example (examples/basic-dashboard.flow.json):
- Parser now reads `level.predicted.atequipment.default` etc. The
MeasurementContainer flatten format includes the implicit 'default'
childId; consumers must include it. Comment in the parser points
at the documenting source in generalFunctions.
Tests:
- test/basic: replace old level-armed-shift tests with two new ones
that exercise the hold-then-ramp arming, capture, hold, ramp-down,
disarm, and the bounce case (filling→draining→filling→draining
captures a fresh hold each time).
- test/integration/shifted-ramp-end-to-end.test.js: new file. Drives
Q_IN/Q_OUT through the full runtime tick with a controllable clock,
asserting the same hysteresis path the dashboard exercises.
- test/integration/basic-dashboard-flow.test.js: fixture keys updated
to the .default-suffixed form so they match the real flatten output.
56/56 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 11:46:46 +02:00
< text id = "ps-mode-curve-down-label" x = "210" y = "205" fill = "#D68910" font-size = "10" style = "display:none;" > — shifted (held @100% then ramp shift→start)< / text >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< / svg >
2025-11-27 17:46:24 +01:00
< / div >
< / div >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< div id = "ps-mode-manual" class = "ps-mode-section" style = "display:none" >
< p style = "font-size:12px;color:#777;margin:0;" > Manual mode accepts external < code > Qd< / code > demand commands and does not compute demand from basin level.< / p >
< / div >
2025-11-27 17:46:24 +01:00
< hr >
< h4 > Reference< / h4 >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
<!-- Reference data — basinBottomRef moved into basin side - panel above. -->
2025-10-07 18:05:54 +02:00
< div class = "form-row" >
2025-10-14 16:32:44 +02:00
< label for = "node-input-refHeight" > < i class = "fa fa-map-marker" > < / i > Reference height< / label >
< select id = "node-input-refHeight" style = "width:60%;" >
< option value = "NAP" > NAP< / option >
2025-10-07 18:05:54 +02:00
< / select >
< / div >
2025-11-25 14:57:39 +01:00
< hr >
2025-11-27 17:46:24 +01:00
< h4 > Safety< / h4 >
2025-11-25 14:57:39 +01:00
<!-- Safety settings -->
< div class = "form-row" >
< label for = "node-input-enableDryRunProtection" >
< i class = "fa fa-shield" > < / i > Dry-run Protection
< / label >
< input type = "checkbox" id = "node-input-enableDryRunProtection" style = "width:20px;vertical-align:baseline;" / >
< span > Prevent pumps from running on low volume< / span >
< / div >
< div class = "form-row" >
< label for = "node-input-dryRunThresholdPercent" style = "padding-left:20px;" > Low Volume Threshold (%)< / label >
Editor: pipe-edge conventions + live derived safety levels
### P1 — match diagram naming (labels only, no schema change)
- "Inlet Elevation" → "Inlet (bottom of pipe, m)"
- "Outlet Elevation" → "Outlet (top of pipe, m)"
- "Overflow Level" → "Overflow (weir crest, m)"
- "Basin Bottom (m Refheight)" → "Basin floor above datum (m)"
- Added a one-line banner at the top of Basin Geometry:
"All heights measured from the basin floor (0 m)."
These map directly to the clarifications added to basin-model.drawio.svg
so editor and diagram speak the same vocabulary.
### P3 — live derived safety levels next to the % fields
Low/High Volume Threshold fields now show the resulting trip level
live as the operator types:
Low Volume Threshold (%) [ 2 ] → dryRunLevel ≈ 0.21 m
High Volume Threshold (%) [ 98 ] → overfillLevel ≈ 4.41 m
Recomputed on every input/change of outflowLevel, inflowLevel,
overflowLevel, minHeightBasedOn, or either %. Pure UI feedback —
no schema change, no save-side change, same formulas as
specificClass._validateThresholdOrdering().
Also includes the user's latest basin-model.drawio.svg update
(inlet=bottom/outlet=top labels + datum annotation).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 09:58:17 +02:00
< input type = "number" id = "node-input-dryRunThresholdPercent" min = "0" max = "100" step = "0.1" style = "width:80px;" / >
< span id = "derived-dryRunLevel" style = "margin-left:8px;color:#777;font-size:12px;" > → dryRunLevel ≈ — m< / span >
2025-11-25 14:57:39 +01:00
< / div >
< div class = "form-row" >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< label for = "node-input-enableHighVolumeSafety" >
< i class = "fa fa-exclamation-triangle" > < / i > High-volume Safety
2025-11-25 14:57:39 +01:00
< / label >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< input type = "checkbox" id = "node-input-enableHighVolumeSafety" style = "width:20px;vertical-align:baseline;" / >
< span > Act before physical overflow< / span >
2025-11-25 14:57:39 +01:00
< / div >
< div class = "form-row" >
Level-armed shift, derived dryRunLevel, side-panel editor + manual q_out
Runtime (specificClass.js):
- Replace direction-based hysteresis with level-armed _shiftArmed state.
Arms when level rises past shiftLevel; disarms when level drops below
startLevel. While armed, ramp foot moves to startLevel and ramp top
to shiftLevel — both ends shift left, then saturate at 100 % up to
maxLevel.
- _scaleLevelToFlowPercent now takes (rampStartLevel, rampTopLevel) so
the saturation point follows the shift state.
- New setManualOutflow mirroring setManualInflow.
Adapter (nodeClass.js):
- Pipe enableShiftedRamp / shiftLevel through to control.levelbased.
- New q_out topic handler.
Editor (pumpingStation.html + new src/editor/ modules):
- Split monolithic <script> into modules: index.js (helpers),
basin-diagram.js, mode-preview.js, hover-couple.js, oneditprepare.js,
oneditsave.js — served via /pumpingStation/editor/:file.
- Mode preview redrawn per the SVG diagrams: OFF tier below 0 %, 0 %
flat from start→inlet, ramp inlet→max, optional shifted-down curve
start→shift with 100 % saturation past shift.
- Mode preview gains zone bands (dryRun / safetyLow / safe / safetyHigh /
overflow), level markers (dryRun derived, start, inlet, max, shift,
overflow), validation ribbon that blocks save on bad ordering.
- Auto-default shiftLevel to 0.9 × maxLevel on enable so the marker is
always visible.
- All level inputs moved to a side panel left of each diagram, color-
coded to match line strokes; hover-couple highlights the paired SVG
line on input focus / mouseover.
- Removed UI for non-static parameters: minHeightBasedOn,
pipelineLength, maxDischargeHead, staticHead, defaultFluid,
maxInflowRate, temperatureReferenceDegC,
timeleftToFullOrEmptyThresholdSeconds, inletPipeDiameter,
outletPipeDiameter, minLevel (now derived = dryRunLevel).
- foreignObject inputs in basin SVG removed (single source of truth in
side panel).
Dashboard example (examples/basic-dashboard.flow.json):
- Add manual Q_OUT slider + q_out builder mirroring the existing q_in
trio so the basin can be exercised end-to-end without a connected
rotating-machine downstream.
Tests (test/basic/specificClass.test.js):
- Replace direction-shift test with two new cases covering shift-disabled
hold-zone behaviour and shift-armed/disarmed transitions through
shiftLevel and startLevel boundaries. 53/53 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:29:34 +02:00
< label for = "node-input-highVolumeSafetyThresholdPercent" style = "padding-left:20px;" > High-volume Safety (%)< / label >
< input type = "number" id = "node-input-highVolumeSafetyThresholdPercent" min = "0" max = "100" step = "0.1" style = "width:80px;" / >
< span id = "derived-highVolumeSafetyLevel" style = "margin-left:8px;color:#777;font-size:12px;" > → highVolumeSafetyLevel ≈ — m< / span >
2025-11-25 14:57:39 +01:00
< / div >
2026-03-31 18:20:09 +02:00
< hr >
2026-03-12 16:39:25 +01:00
< h3 > Output Formats< / h3 >
< div class = "form-row" >
< label for = "node-input-processOutputFormat" > < i class = "fa fa-random" > < / i > Process Output< / label >
< select id = "node-input-processOutputFormat" style = "width:60%;" >
< option value = "process" > process< / option >
< option value = "json" > json< / option >
< option value = "csv" > csv< / option >
< / select >
< / div >
< div class = "form-row" >
< label for = "node-input-dbaseOutputFormat" > < i class = "fa fa-database" > < / i > Database Output< / label >
< select id = "node-input-dbaseOutputFormat" style = "width:60%;" >
< option value = "influxdb" > influxdb< / option >
< option value = "json" > json< / option >
< option value = "csv" > csv< / option >
< / select >
< / div >
2025-10-14 16:32:44 +02:00
<!-- Shared asset/logger/position menus -->
2025-10-07 18:05:54 +02:00
< div id = "asset-fields-placeholder" > < / div >
< div id = "logger-fields-placeholder" > < / div >
< div id = "position-fields-placeholder" > < / div >
2025-10-14 16:32:44 +02:00
2025-10-07 18:05:54 +02:00
< / script >
2025-10-14 13:51:32 +02:00
< script type = "text/html" data-help-name = "pumpingStation" >
2025-10-07 18:05:54 +02:00
< / script >