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:
@@ -861,179 +861,4 @@ class PumpingStation {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PumpingStation;
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Example usage */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
if (require.main === module) {
|
||||
const Measurement = require('../../measurement/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 createLevelMeasurementConfig(name) {
|
||||
return {
|
||||
general: {
|
||||
logging: { enabled: true, logLevel: 'debug' },
|
||||
name,
|
||||
id: `${name}-${Date.now()}`,
|
||||
unit: 'm'
|
||||
},
|
||||
functionality: {
|
||||
softwareType: 'measurement',
|
||||
role: 'sensor',
|
||||
positionVsParent: 'atequipment'
|
||||
},
|
||||
asset: {
|
||||
category: 'sensor',
|
||||
type: 'level',
|
||||
model: 'demo-level',
|
||||
supplier: 'demoCo',
|
||||
unit: 'm'
|
||||
},
|
||||
scaling: { enabled: false },
|
||||
smoothing: { smoothWindow: 5, smoothMethod: 'none' }
|
||||
};
|
||||
}
|
||||
|
||||
function createFlowMeasurementConfig(name, position) {
|
||||
return {
|
||||
general: {
|
||||
logging: { enabled: true, logLevel: 'debug' },
|
||||
name,
|
||||
id: `${name}-${Date.now()}`,
|
||||
unit: 'm3/s'
|
||||
},
|
||||
functionality: {
|
||||
softwareType: 'measurement',
|
||||
role: 'sensor',
|
||||
positionVsParent: position
|
||||
},
|
||||
asset: {
|
||||
category: 'sensor',
|
||||
type: 'flow',
|
||||
model: 'demo-flow',
|
||||
supplier: 'demoCo',
|
||||
unit: 'm3/s'
|
||||
},
|
||||
scaling: { enabled: false },
|
||||
smoothing: { smoothWindow: 5, smoothMethod: 'none' }
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function seedSample(measurement, type, value, unit) {
|
||||
const pos = measurement.config.functionality.positionVsParent;
|
||||
measurement.measurements.type(type).variant('measured').position(pos).value(value, Date.now(), unit);
|
||||
}
|
||||
|
||||
(async function demo() {
|
||||
const station = new PumpingStation(createPumpingStationConfig('PumpingStationDemo'));
|
||||
const pump1 = new RotatingMachine(createMachineConfig('Pump1','downstream'), createMachineStateConfig());
|
||||
//const pump2 = new RotatingMachine(createMachineConfig('Pump2','upstream'), createMachineStateConfig());
|
||||
|
||||
//const levelSensor = new Measurement(createLevelMeasurementConfig('WetWellLevel'));
|
||||
//const inflowSensor = new Measurement(createFlowMeasurementConfig('InfluentFlow', 'in'));
|
||||
//const outflowSensor = new Measurement(createFlowMeasurementConfig('PumpDischargeFlow', 'out'));
|
||||
|
||||
//station.childRegistrationUtils.registerChild(levelSensor, levelSensor.config.functionality.softwareType);
|
||||
//station.childRegistrationUtils.registerChild(inflowSensor, inflowSensor.config.functionality.softwareType);
|
||||
//station.childRegistrationUtils.registerChild(outflowSensor, outflowSensor.config.functionality.softwareType);
|
||||
|
||||
station.childRegistrationUtils.registerChild(pump1, 'machine');
|
||||
//station.childRegistrationUtils.registerChild(pump2, 'machine');
|
||||
|
||||
// Seed initial measurements
|
||||
|
||||
//seedSample(levelSensor, 'level', 1.8, 'm');
|
||||
//seedSample(inflowSensor, 'flow', 0.35, 'm3/s');
|
||||
//seedSample(outflowSensor, 'flow', 0.20, 'm3/s');
|
||||
|
||||
|
||||
|
||||
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);
|
||||
//await pump1.handleInput('parent', 'execSequence', 'startup');
|
||||
//await pump1.handleInput('parent', 'execMovement', 10);
|
||||
//
|
||||
//await pump2.handleInput('parent', 'execSequence', 'startup');
|
||||
//await pump2.handleInput('parent', 'execMovement', 10);
|
||||
|
||||
console.log('Station state:', station.state);
|
||||
console.log('Station output:', station.getOutput());
|
||||
})().catch((err) => {
|
||||
console.error('Demo failed:', err);
|
||||
});
|
||||
}
|
||||
//*/
|
||||
module.exports = PumpingStation;
|
||||
Reference in New Issue
Block a user