Commit Graph

4 Commits

Author SHA1 Message Date
Rene De Ren
8a6ca1baeb 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
znetsixe
016433abe6 Add threshold guardrails, fix calibratePredictedLevel bug, rewrite tests
### Guardrails (specificClass.js)

New _validateThresholdOrdering() runs in the constructor. Checks every
ordered pair of basin + control + derived-safety levels and logs a
warning for each violation; returns the list as this.thresholdIssues
so tests and the eval harness can inspect. Non-fatal — we prefer a
running-but-warned station to a refusal-to-start (availability-first).

Strict invariants (bottom → top):
  0 < outflowLevel < inflowLevel < overflowLevel ≤ basinHeight
  dryRunLevel ≤ minLevel ≤ startLevel < maxLevel ≤ overfillLevel

Uses a list-of-checks pattern rather than a switch — easier to add new
invariants without reflowing cases, and the list itself is readable
documentation.

### Bug fix (specificClass.js)

calibratePredictedLevel was writing the volume value into the LEVEL
slot. Root cause: MeasurementContainer is stateful — its type()/
variant()/position() calls mutate the container's own cursor, so
caching chain references (const levelChain = ...; const volumeChain
= ...) doesn't isolate them. The second cached chain ended up sharing
the state of the last type() call. Rebuilt chains fresh each time,
matching the calibratePredictedVolume pattern that already worked.

### Tests (test/basic/specificClass.test.js)

Ported from Jest to node:test + node:assert — the project's standard
per .claude/rules/testing.md. Deleted the stale test/specificClass.test.js
(tests referenced methods that no longer exist post-rename).

New coverage, 42 passing subtests:
- Basin geometry derivations + minHeightBasedOn
- Level/volume roundtrip
- Threshold guardrails (5 violation cases)
- Direction derivation
- Mode change accept/reject
- Calibration (volume and level paths — catches the bug above)
- Levelbased control zones (STOP / DEAD ZONE / RAMP / saturate)
- getOutput flattening
- setManualInflow

Run with: node --test test/basic/*.test.js

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 16:38:41 +02:00
znetsixe
a2189457f6 Rename basin/control thresholds to wiki naming; trim stale comments
Aligns the code with the 5-threshold convention used throughout the
wiki (basin model + per-mode transfer-function diagrams):

  heightInlet       → inflowLevel
  heightOutlet      → outflowLevel
  heightOverflow    → overflowLevel
  stopLevel         → minLevel
  maxFlowLevel      → maxLevel
  minFlowLevel      → removed (collapsed into startLevel; they were
                      always supposed to hold the same value)
  minVolIn          → minVolAtInflow
  minVolOut         → minVolAtOutflow
  maxVolOverflow    → maxVolAtOverflow
  startLevel        → unchanged

Config schema (generalFunctions/src/configs/pumpingStation.json) is
updated in a parallel commit in that submodule.

Also:
- Stripped the ~150-line ASCII basin diagram from initBasinProperties
  JSDoc; it now points at wiki/functional-description.md#basin-model.
- Trimmed the top-of-class JSDoc — the config-sections breakdown was
  drifting from the schema anyway; wiki is now the source of truth.
- Tidied inline comments in _controlLevelBased, _scaleLevelToFlowPercent.
- Editor order reshuffled to match the bottom→top basin order:
  minLevel, startLevel, maxLevel.

Breaking change for saved flows: existing pumpingStation nodes in
production flows reference the old field names and will need to be
re-entered in the editor. No compat shim — node is RnD/trial.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 16:13:59 +02:00
Rene De Ren
f01b0bcb19 fix: rename _calcTimeRemaining to _calcRemainingTime + add tests
Fix method name mismatch in tick() that called non-existent _calcTimeRemaining
instead of _calcRemainingTime. Add 27 unit tests for specificClass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:31:47 +01:00