Files
pumpingStation/simulations/scenarios/levelbased-steady.js
Rene De Ren 6ab585bcc2 Docs + simulations refresh; align spill-flow keys with new position
- wiki/functional-description.md: rename Overfill Protection → High-volume
  Safety; tighten basin-ordering chain; relocate level-based mode
  diagrams under wiki/diagrams/modes/level-based/; document the new
  flow.predicted.overflow.default position (replaces the previous
  child='overflow' under position 'out'); add underflowVolume +
  predictedUnderflowVolume entries.
- wiki/modes/{levelbased,powerbased}.md: paragraph cleanups.
- wiki/diagrams: move level-linear basin diagram under modes/level-based/
  alongside a new level-log variant.
- simulations/run.js: add max_demand_gt expectation.
- simulations/scenarios/*: minor fixture updates.
- test/basic/nodeClass-config.test.js: new config-shape coverage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 17:23:20 +02:00

62 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Steady sewer inflow, level-based control, pumps should settle.
//
// Expectation: with a stable inflow of 0.008 m³/s and a pump bank with
// max capacity 0.012 m³/s, the level settles in the RAMP zone (between
// inflowLevel and maxLevel while filling) at roughly the point where demand matches
// inflow. No safety trips should fire.
module.exports = {
name: 'levelbased-steady',
description: 'Constant sewer inflow below pump capacity; level converges inside the RAMP zone with demand matching inflow.',
durationSec: 3600,
config: {
general: { name: 'EvalSteady', id: 'eval-steady', unit: 'm3/h',
logging: { enabled: false, logLevel: 'error' } },
functionality: { softwareType: 'pumpingStation', role: 'stationcontroller', positionVsParent: 'atEquipment' },
basin: { volume: 50, height: 5, inflowLevel: 3, outflowLevel: 0.2, overflowLevel: 4.5, inletPipeDiameter: 0.4, outletPipeDiameter: 0.3 },
hydraulics: { refHeight: 'NAP', basinBottomRef: 0, minHeightBasedOn: 'outlet' },
control: {
mode: 'levelbased',
allowedModes: new Set(['levelbased']),
levelbased: { minLevel: 1, startLevel: 2, maxLevel: 4, curveType: 'linear', logCurveFactor: 9 },
},
safety: {
enableDryRunProtection: true,
dryRunThresholdPercent: 2,
enableHighVolumeSafety: true,
highVolumeSafetyThresholdPercent: 98,
timeleftToFullOrEmptyThresholdSeconds: 0,
},
},
setup: async (ps) => {
// Stub MGC: its pumps collectively deliver (demand/100) × MAX_OUTFLOW.
const MAX_OUTFLOW = 0.012; // m³/s
ps.machineGroups['mgc1'] = {
config: { general: { name: 'mgc1' } },
turnOffAllMachines: () => {
ps.measurements.type('flow').variant('predicted').position('out').child('mgc1').value(0, Date.now(), 'm3/s');
},
handleInput: async (_source, demand) => {
const d = Math.max(0, Math.min(100, Number(demand) || 0));
const outflow = (d / 100) * MAX_OUTFLOW;
ps.measurements.type('flow').variant('predicted').position('out').child('mgc1').value(outflow, Date.now(), 'm3/s');
},
};
ps.calibratePredictedLevel(2.0); // start at the mode start level, below the rising ramp
},
inputs: (t, ps) => {
ps.setManualInflow(0.008, Date.now(), 'm3/s'); // ≈ 29 m³/h
},
expectations: [
{ name: 'no safety trips', type: 'safety_trips_eq', value: 0 },
{ name: 'level stays below overflow', type: 'max_level_bounded', value: 4.5 },
{ name: 'level stays above outflow', type: 'min_level_bounded', value: 0.2 },
{ name: 'rising ramp engages after inlet level', type: 'max_demand_gt', value: 0 },
{ name: 'no threshold issues on init', type: 'threshold_issues_eq', value: 0 },
],
};