updated pumpingstation
This commit is contained in:
@@ -63,6 +63,7 @@ class nodeClass {
|
||||
},
|
||||
hydraulics:{
|
||||
refHeight: uiConfig.refHeight,
|
||||
minHeightBasedOn: uiConfig.minHeightBasedOn,
|
||||
basinBottomRef: uiConfig.basinBottomRef,
|
||||
}
|
||||
};
|
||||
@@ -191,13 +192,9 @@ class nodeClass {
|
||||
this.node.on('input', (msg, send, done) => {
|
||||
switch (msg.topic) {
|
||||
//example
|
||||
/*case 'simulator':
|
||||
this.source.toggleSimulation();
|
||||
case 'changemode':
|
||||
this.source.changeMode(msg.payload);
|
||||
break;
|
||||
default:
|
||||
this.source.handleInput(msg);
|
||||
break;
|
||||
*/
|
||||
case 'registerChild':
|
||||
// Register this node as a child of the parent node
|
||||
const childId = msg.payload;
|
||||
|
||||
@@ -106,7 +106,7 @@ class PumpingStation {
|
||||
//get threshholds from config
|
||||
const timeThreshhold = this.config.safety.timeleftToFullOrEmptyThresholdSeconds; //seconds
|
||||
const triggerHighVol = this.basin.maxVolOverflow * ( this.config.safety.overfillThresholdPercent/100 );
|
||||
const triggerLowVol = this.basin.minVolOut * ( this.config.safety.dryRunThresholdPercent/100 );
|
||||
const triggerLowVol = this.basin.minVol * ( this.config.safety.dryRunThresholdPercent/100 );
|
||||
|
||||
// trigger conditions for draining
|
||||
if(direction == "draining"){
|
||||
@@ -165,10 +165,10 @@ class PumpingStation {
|
||||
}
|
||||
|
||||
changeMode(newMode){
|
||||
|
||||
if ( this.config.control.allowedModes.has(newMode) ){
|
||||
const currentMode = this.mode;
|
||||
this.logger.info(`Control mode changing from ${currentMode} to ${newMode}`);
|
||||
this.mode = newMode;
|
||||
this.logger.info(`Control mode changed from ${currentMode} to ${newMode}`);
|
||||
}
|
||||
else{
|
||||
this.logger.warn(`Attempted to change to unsupported control mode: ${newMode}`);
|
||||
@@ -176,48 +176,6 @@ class PumpingStation {
|
||||
|
||||
}
|
||||
|
||||
/* old levelcontrol
|
||||
async _controlLevelBased(snapshot, remainingTime) {
|
||||
|
||||
|
||||
// current volume as a percentage of usable capacity
|
||||
const vol = this._resolveVolume(snapshot);
|
||||
if (vol == null) {
|
||||
this.logger.warn('No valid volume found for level-based control');
|
||||
return;
|
||||
}
|
||||
|
||||
const { thresholds, timeThresholdSeconds } = this.config.control.levelbased;
|
||||
const percentFull = (vol / this.basin.maxVolOverflow) * 100;
|
||||
|
||||
// pick thresholds that are now crossed but were not crossed before
|
||||
const newlyCrossed = thresholds.filter(t => percentFull >= t && !this._levelState.crossed.has(t));
|
||||
this.logger.debug(`Level-based control: vol=${vol.toFixed(2)} m³ (${percentFull.toFixed(1)}%), newly crossed thresholds: [${newlyCrossed.join(', ')}]`);
|
||||
if (!newlyCrossed.length) return;
|
||||
|
||||
const now = Date.now();
|
||||
if (!this._levelState.dwellUntil) {
|
||||
this._levelState.dwellUntil = now + timeThresholdSeconds * 1000;
|
||||
this.logger.debug(`Level-based control: waiting ${timeThresholdSeconds}s before acting`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.debug(`Level-based control: dwelling for another ${Math.round((this._levelState.dwellUntil - now) / 1000)} seconds`);
|
||||
if (now < this._levelState.dwellUntil) return; // still waiting
|
||||
|
||||
this._levelState.dwellUntil = null; // dwell satisfied, let pumps start
|
||||
|
||||
for (const threshold of newlyCrossed) {
|
||||
const nextMachine = this._nextIdleMachine();
|
||||
if (!nextMachine) break;
|
||||
this._levelState.crossed.add(threshold);
|
||||
this.logger.info(
|
||||
`level-based control: threshold ${threshold}% reached, starting "${nextMachine.config.general.name}" (vol=${vol.toFixed(2)} m³)`
|
||||
);
|
||||
await nextMachine.handleInput('parent', 'execSequence', 'startup');
|
||||
}
|
||||
}
|
||||
*/
|
||||
async _controlLevelBased(snapshot, remainingTime) {
|
||||
|
||||
|
||||
@@ -337,12 +295,19 @@ class PumpingStation {
|
||||
case "flowbased":
|
||||
this._controlFlowBased();
|
||||
break;
|
||||
case "manual":
|
||||
this._manualControl();
|
||||
break;
|
||||
default:
|
||||
this.logger.warn(`Unsupported control mode: ${mode}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_manualControl() {
|
||||
// Nothing to do - manual mode
|
||||
}
|
||||
|
||||
//calibrate the predicted volume to a known value
|
||||
calibratePredictedVolume(calibratedVol, timestamp = Date.now()){
|
||||
|
||||
@@ -835,17 +800,22 @@ class PumpingStation {
|
||||
|
||||
initBasinProperties() {
|
||||
|
||||
const volEmptyBasin = this.config.basin.volume;
|
||||
const heightBasin = this.config.basin.height;
|
||||
const heightInlet = this.config.basin.heightInlet;
|
||||
const heightOutlet = this.config.basin.heightOutlet;
|
||||
const heightOverflow = this.config.basin.heightOverflow;
|
||||
//is min height based on inlet or outlet elevation?
|
||||
const minHeightBasedOn = this.config.hydraulics.minHeightBasedOn;
|
||||
|
||||
const surfaceArea = volEmptyBasin / heightBasin;
|
||||
const maxVol = heightBasin * surfaceArea;
|
||||
const maxVolOverflow = heightOverflow * surfaceArea;
|
||||
const minVol = heightOutlet * surfaceArea;
|
||||
const minVolOut = heightInlet * surfaceArea;
|
||||
const volEmptyBasin = this.config.basin.volume; //volume when basin is empty
|
||||
const heightBasin = this.config.basin.height; //total height of basin
|
||||
const heightInlet = this.config.basin.heightInlet; //height at which inlet is located
|
||||
const heightOutlet = this.config.basin.heightOutlet; //height at which outlet is located
|
||||
const heightOverflow = this.config.basin.heightOverflow; //height at which overflow occurs
|
||||
|
||||
const surfaceArea = volEmptyBasin / heightBasin; //assume uniform cross section for now
|
||||
const maxVol = heightBasin * surfaceArea; //maximum volume when basin is full
|
||||
const maxVolOverflow = heightOverflow * surfaceArea; //maximum volume before overflow occurs
|
||||
const minVolOut = heightOutlet * surfaceArea; //minimum volume to have outlet just above basin bottom
|
||||
const minVolIn = heightInlet * surfaceArea; //minimum volume to have inlet just above waterline
|
||||
const minVol = (minHeightBasedOn === "inlet") ? minVolIn : minVolOut;
|
||||
this.logger.debug(`Basin min volume based on ${minHeightBasedOn} : ${minVol.toFixed(2)} m3`);
|
||||
|
||||
this.basin = {
|
||||
volEmptyBasin,
|
||||
@@ -856,11 +826,13 @@ class PumpingStation {
|
||||
surfaceArea,
|
||||
maxVol,
|
||||
maxVolOverflow,
|
||||
minVolIn,
|
||||
minVolOut,
|
||||
minVol,
|
||||
minVolOut
|
||||
minHeightBasedOn
|
||||
};
|
||||
|
||||
this.measurements.type('volume').variant('predicted').position('atEquipment').value(heightOutlet).unit('m3');
|
||||
this.measurements.type('volume').variant('predicted').position('atEquipment').value(minVol).unit('m3');
|
||||
|
||||
this.logger.debug(
|
||||
`Basin initialized | area=${surfaceArea.toFixed(2)} m2, max=${maxVol.toFixed(2)} m3, overflow=${maxVolOverflow.toFixed(2)} m3`
|
||||
@@ -899,6 +871,8 @@ class PumpingStation {
|
||||
output.minVol = this.basin.minVol;
|
||||
output.maxVolOverflow = this.basin.maxVolOverflow;
|
||||
output.minVolOut = this.basin.minVolOut;
|
||||
output.minVolIn = this.basin.minVolIn;
|
||||
output.minHeightBasedOn = this.basin.minHeightBasedOn;
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user