P2 wave 1: extract concerns from pumpingStation specificClass
Splits pumpingStation/src/ into focused concern modules. specificClass.js
will be slimmed to an orchestrator in P2.9 (integration); for now both
the inlined logic AND the new modules coexist so tests stay green
throughout.
src/basin/ BasinGeometry + thresholdValidator (pure)
src/measurement/ flowAggregator + measurementRouter + calibration
src/control/ levelBased + flowBased(stub) + manual + index dispatcher
src/safety/ safetyController split into dryRun + overfill rules
src/commands/ registry array + handlers (canonical names from start)
src/editor.js 260 lines of SVG basin-diagram redraw, was inline in .html
examples/standalone-demo.js was if(require.main===module) at bottom of specificClass.js
CONTRACT.md canonical inputs + outputs + emitted events
Modified:
src/specificClass.js removed the 170-line standalone demo block
pumpingStation.html oneditprepare/oneditsave delegate to editor.{init,save}
pumpingStation.js added admin endpoint serving src/editor.js
102 basic tests pass (60 new + 42 existing).
specificClass.js itself is unchanged in behaviour — integration is P2.9.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
57
examples/standalone-demo.js
Normal file
57
examples/standalone-demo.js
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Standalone PumpingStation demo — run with `node examples/standalone-demo.js`.
|
||||
* Builds a station + one pump, calibrates predicted volume, ticks once.
|
||||
* Useful for sanity-checking the orchestrator without Node-RED.
|
||||
*/
|
||||
const PumpingStation = require('../src/specificClass');
|
||||
const RotatingMachine = require('../../rotatingMachine/src/specificClass');
|
||||
|
||||
function createPumpingStationConfig(name) {
|
||||
return {
|
||||
general: {
|
||||
logging: { enabled: true, logLevel: 'debug' },
|
||||
name,
|
||||
id: `${name}-${Date.now()}`,
|
||||
flowThreshold: 1e-4,
|
||||
},
|
||||
functionality: { softwareType: 'pumpingStation', role: 'stationcontroller' },
|
||||
basin: { volume: 43.75, height: 10, inflowLevel: 3, outflowLevel: 0.2, overflowLevel: 3.2 },
|
||||
hydraulics: { refHeight: 'NAP', basinBottomRef: 0 },
|
||||
safety: { enableDryRunProtection: false, enableOverfillProtection: false },
|
||||
};
|
||||
}
|
||||
|
||||
function createMachineConfig(name, position) {
|
||||
return {
|
||||
general: { name, logging: { enabled: false, logLevel: 'debug' } },
|
||||
functionality: { softwareType: 'machine', positionVsParent: position },
|
||||
asset: { supplier: 'Hydrostal', type: 'pump', category: 'centrifugal', model: 'hidrostal-H05K-S03R' },
|
||||
};
|
||||
}
|
||||
|
||||
function createMachineStateConfig() {
|
||||
return {
|
||||
general: { logging: { enabled: true, logLevel: 'debug' } },
|
||||
movement: { speed: 1 },
|
||||
time: { starting: 2, warmingup: 3, stopping: 2, coolingdown: 3 },
|
||||
};
|
||||
}
|
||||
|
||||
(async function demo() {
|
||||
const station = new PumpingStation(createPumpingStationConfig('PumpingStationDemo'));
|
||||
const pump1 = new RotatingMachine(createMachineConfig('Pump1', 'downstream'), createMachineStateConfig());
|
||||
|
||||
station.childRegistrationUtils.registerChild(pump1, 'machine');
|
||||
|
||||
setInterval(() => station.tick(), 1000);
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
|
||||
console.log('Initial state:', station.state);
|
||||
station.setManualInflow(300, Date.now(), 'l/s');
|
||||
station.calibratePredictedVolume(3.4);
|
||||
|
||||
console.log('Station state:', station.state);
|
||||
console.log('Station output:', station.getOutput());
|
||||
})().catch((err) => {
|
||||
console.error('Demo failed:', err);
|
||||
});
|
||||
Reference in New Issue
Block a user