Compare commits
3 Commits
8d2a3b80e7
...
fa7c59fcab
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa7c59fcab | ||
|
|
3fc8dbefe8 | ||
|
|
f24a5fb90b |
@@ -57,11 +57,11 @@
|
|||||||
waitForMenuData();
|
waitForMenuData();
|
||||||
|
|
||||||
// your existing project‐settings & asset dropdown logic can remain here
|
// your existing project‐settings & asset dropdown logic can remain here
|
||||||
document.getElementById("node-input-speed"),
|
document.getElementById("node-input-speed");
|
||||||
document.getElementById("node-input-startup"),
|
document.getElementById("node-input-startup");
|
||||||
document.getElementById("node-input-warmup"),
|
document.getElementById("node-input-warmup");
|
||||||
document.getElementById("node-input-shutdown"),
|
document.getElementById("node-input-shutdown");
|
||||||
document.getElementById("node-input-cooldown")
|
document.getElementById("node-input-cooldown");
|
||||||
|
|
||||||
},
|
},
|
||||||
oneditsave: function() {
|
oneditsave: function() {
|
||||||
|
|||||||
@@ -20,12 +20,13 @@ class nodeClass {
|
|||||||
this.RED = RED; // This is the Node-RED runtime API, we can use this to create endpoints if needed
|
this.RED = RED; // This is the Node-RED runtime API, we can use this to create endpoints if needed
|
||||||
this.name = nameOfNode; // This is the name of the node, it should match the file name and the node type in Node-RED
|
this.name = nameOfNode; // This is the name of the node, it should match the file name and the node type in Node-RED
|
||||||
this.source = null; // Will hold the specific class instance
|
this.source = null; // Will hold the specific class instance
|
||||||
|
this.config = null; // Will hold the merged configuration
|
||||||
|
|
||||||
// Load default & UI config
|
// Load default & UI config
|
||||||
this._loadConfig(uiConfig,this.node);
|
this._loadConfig(uiConfig,this.node);
|
||||||
|
|
||||||
// Instantiate core Measurement class
|
// Instantiate core class
|
||||||
this._setupSpecificClass();
|
this._setupSpecificClass(uiConfig);
|
||||||
|
|
||||||
// Wire up event and lifecycle handlers
|
// Wire up event and lifecycle handlers
|
||||||
this._bindEvents();
|
this._bindEvents();
|
||||||
@@ -40,8 +41,6 @@ class nodeClass {
|
|||||||
* @param {object} uiConfig - Raw config from Node-RED UI.
|
* @param {object} uiConfig - Raw config from Node-RED UI.
|
||||||
*/
|
*/
|
||||||
_loadConfig(uiConfig,node) {
|
_loadConfig(uiConfig,node) {
|
||||||
const cfgMgr = new configManager();
|
|
||||||
this.defaultConfig = cfgMgr.getConfig(this.name);
|
|
||||||
|
|
||||||
// Merge UI config over defaults
|
// Merge UI config over defaults
|
||||||
this.config = {
|
this.config = {
|
||||||
@@ -75,7 +74,7 @@ class nodeClass {
|
|||||||
/**
|
/**
|
||||||
* Instantiate the core Measurement logic and store as source.
|
* Instantiate the core Measurement logic and store as source.
|
||||||
*/
|
*/
|
||||||
_setupSpecificClass() {
|
_setupSpecificClass(uiConfig) {
|
||||||
const machineConfig = this.config;
|
const machineConfig = this.config;
|
||||||
|
|
||||||
// need extra state for this
|
// need extra state for this
|
||||||
@@ -87,13 +86,13 @@ class nodeClass {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
movement: {
|
movement: {
|
||||||
speed: Number(machineConfig.speed)
|
speed: Number(uiConfig.speed)
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
starting: Number(machineConfig.startup),
|
starting: Number(uiConfig.startup),
|
||||||
warmingup: Number(machineConfig.warmup),
|
warmingup: Number(uiConfig.warmup),
|
||||||
stopping: Number(machineConfig.shutdown),
|
stopping: Number(uiConfig.shutdown),
|
||||||
coolingdown: Number(machineConfig.cooldown)
|
coolingdown: Number(uiConfig.cooldown)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -108,9 +107,7 @@ class nodeClass {
|
|||||||
* Bind events to Node-RED status updates. Using internal emitter. --> REMOVE LATER WE NEED ONLY COMPLETE CHILDS AND THEN CHECK FOR UPDATES
|
* Bind events to Node-RED status updates. Using internal emitter. --> REMOVE LATER WE NEED ONLY COMPLETE CHILDS AND THEN CHECK FOR UPDATES
|
||||||
*/
|
*/
|
||||||
_bindEvents() {
|
_bindEvents() {
|
||||||
this.source.emitter.on('mAbs', (val) => {
|
|
||||||
this.node.status({ fill: 'green', shape: 'dot', text: `${val} ${this.config.general.unit}` });
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateNodeStatus() {
|
_updateNodeStatus() {
|
||||||
@@ -206,7 +203,7 @@ class nodeClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the periodic tick loop to drive the Measurement class.
|
* Start the periodic tick loop.
|
||||||
*/
|
*/
|
||||||
_startTickLoop() {
|
_startTickLoop() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -269,9 +266,9 @@ class nodeClass {
|
|||||||
const { source: esSource, action: esAction } = msg.payload;
|
const { source: esSource, action: esAction } = msg.payload;
|
||||||
m.handleInput(esSource, esAction);
|
m.handleInput(esSource, esAction);
|
||||||
break;
|
break;
|
||||||
case 'showCompleteCurve':
|
case 'showWorkingCurves':
|
||||||
m.showCompleteCurve();
|
m.showWorkingCurves();
|
||||||
send({ topic : "Showing curve" , payload: m.showCompleteCurve() });
|
send({ topic : "Showing curve" , payload: m.showWorkingCurves() });
|
||||||
break;
|
break;
|
||||||
case 'CoG':
|
case 'CoG':
|
||||||
m.showCoG();
|
m.showCoG();
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ class Machine {
|
|||||||
this.model = machineConfig.asset.model; // Get the model from the machineConfig
|
this.model = machineConfig.asset.model; // Get the model from the machineConfig
|
||||||
this.curve = this.model ? loadCurve(this.model) : null;
|
this.curve = this.model ? loadCurve(this.model) : null;
|
||||||
|
|
||||||
|
//Init config and check if it is valid
|
||||||
|
this.config = this.configUtils.initConfig(machineConfig);
|
||||||
|
|
||||||
if (!this.model || !this.curve) {
|
if (!this.model || !this.curve) {
|
||||||
this.logger.warning(`${!this.model ? 'Model not specified' : 'Curve not found for model ' + this.model} in machineConfig. Cannot make predictions.`);
|
this.logger.warning(`${!this.model ? 'Model not specified' : 'Curve not found for model ' + this.model} in machineConfig. Cannot make predictions.`);
|
||||||
// Set prediction objects to null to prevent method calls
|
// Set prediction objects to null to prevent method calls
|
||||||
@@ -73,8 +76,10 @@ class Machine {
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
this.hasCurve = true;
|
this.hasCurve = true;
|
||||||
|
this.config = this.configUtils.updateConfig(this.config, {
|
||||||
|
asset: { ...this.config.asset, machineCurve: this.curve }
|
||||||
|
});
|
||||||
machineConfig = { ...machineConfig, asset: { ...machineConfig.asset, machineCurve: this.curve } }; // Merge curve into machineConfig
|
machineConfig = { ...machineConfig, asset: { ...machineConfig.asset, machineCurve: this.curve } }; // Merge curve into machineConfig
|
||||||
this.config = this.configUtils.initConfig(machineConfig);
|
|
||||||
this.predictFlow = new predict({ curve: this.config.asset.machineCurve.nq }); // load nq (x : ctrl , y : flow relationship)
|
this.predictFlow = new predict({ curve: this.config.asset.machineCurve.nq }); // load nq (x : ctrl , y : flow relationship)
|
||||||
this.predictPower = new predict({ curve: this.config.asset.machineCurve.np }); // load np (x : ctrl , y : power relationship)
|
this.predictPower = new predict({ curve: this.config.asset.machineCurve.np }); // load np (x : ctrl , y : power relationship)
|
||||||
this.predictCtrl = new predict({ curve: this.reverseCurve(this.config.asset.machineCurve.nq) }); // load reversed nq (x: flow, y: ctrl relationship)
|
this.predictCtrl = new predict({ curve: this.reverseCurve(this.config.asset.machineCurve.nq) }); // load reversed nq (x: flow, y: ctrl relationship)
|
||||||
@@ -104,8 +109,6 @@ class Machine {
|
|||||||
this.updatePosition();
|
this.updatePosition();
|
||||||
});
|
});
|
||||||
|
|
||||||
//this.calcCog();
|
|
||||||
|
|
||||||
this.childRegistrationUtils = new childRegistrationUtils(this); // Child registration utility
|
this.childRegistrationUtils = new childRegistrationUtils(this); // Child registration utility
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -197,7 +200,7 @@ class Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setMode(newMode) {
|
setMode(newMode) {
|
||||||
const availableModes = defaultConfig.mode.current.rules.values.map(v => v.value);
|
const availableModes = this.defaultConfig.mode.current.rules.values.map(v => v.value);
|
||||||
if (!availableModes.includes(newMode)) {
|
if (!availableModes.includes(newMode)) {
|
||||||
this.logger.warn(`Invalid mode '${newMode}'. Allowed modes are: ${availableModes.join(', ')}`);
|
this.logger.warn(`Invalid mode '${newMode}'. Allowed modes are: ${availableModes.join(', ')}`);
|
||||||
return;
|
return;
|
||||||
@@ -244,6 +247,8 @@ class Machine {
|
|||||||
throw new Error("Invalid setpoint: Setpoint must be a non-negative number.");
|
throw new Error("Invalid setpoint: Setpoint must be a non-negative number.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.logger.info(`Setting setpoint to ${setpoint}. Current position: ${this.state.getCurrentPosition()}`);
|
||||||
|
|
||||||
// Move to the desired setpoint
|
// Move to the desired setpoint
|
||||||
await this.state.moveTo(setpoint);
|
await this.state.moveTo(setpoint);
|
||||||
|
|
||||||
@@ -254,7 +259,7 @@ class Machine {
|
|||||||
|
|
||||||
// Calculate flow based on current pressure and position
|
// Calculate flow based on current pressure and position
|
||||||
calcFlow(x) {
|
calcFlow(x) {
|
||||||
if(!this.hasCurve) {
|
if(this.hasCurve) {
|
||||||
const state = this.state.getCurrentState();
|
const state = this.state.getCurrentState();
|
||||||
|
|
||||||
if (!["operational", "accelerating", "decelerating"].includes(state)) {
|
if (!["operational", "accelerating", "decelerating"].includes(state)) {
|
||||||
@@ -279,7 +284,7 @@ class Machine {
|
|||||||
|
|
||||||
// Calculate power based on current pressure and position
|
// Calculate power based on current pressure and position
|
||||||
calcPower(x) {
|
calcPower(x) {
|
||||||
if(!this.hasCurve) {
|
if(this.hasCurve) {
|
||||||
const state = this.state.getCurrentState();
|
const state = this.state.getCurrentState();
|
||||||
if (!["operational", "accelerating", "decelerating"].includes(state)) {
|
if (!["operational", "accelerating", "decelerating"].includes(state)) {
|
||||||
this.measurements.type("power").variant("predicted").position('upstream').value(0);
|
this.measurements.type("power").variant("predicted").position('upstream').value(0);
|
||||||
@@ -302,7 +307,7 @@ class Machine {
|
|||||||
|
|
||||||
// calculate the power consumption using only flow and pressure
|
// calculate the power consumption using only flow and pressure
|
||||||
inputFlowCalcPower(flow) {
|
inputFlowCalcPower(flow) {
|
||||||
if(!this.hasCurve) {
|
if(this.hasCurve) {
|
||||||
|
|
||||||
this.predictCtrl.currentX = flow;
|
this.predictCtrl.currentX = flow;
|
||||||
const cCtrl = this.predictCtrl.y(flow);
|
const cCtrl = this.predictCtrl.y(flow);
|
||||||
@@ -320,7 +325,7 @@ class Machine {
|
|||||||
|
|
||||||
// Function to predict control value for a desired flow
|
// Function to predict control value for a desired flow
|
||||||
calcCtrl(x) {
|
calcCtrl(x) {
|
||||||
if(!this.hasCurve) {
|
if(this.hasCurve) {
|
||||||
this.predictCtrl.currentX = x;
|
this.predictCtrl.currentX = x;
|
||||||
const cCtrl = this.predictCtrl.y(x);
|
const cCtrl = this.predictCtrl.y(x);
|
||||||
this.measurements.type("ctrl").variant("predicted").position('upstream').value(cCtrl);
|
this.measurements.type("ctrl").variant("predicted").position('upstream').value(cCtrl);
|
||||||
@@ -407,7 +412,7 @@ class Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get
|
// get
|
||||||
const upstreamFlow = this.measurements.type('pressure').variant('measured').position('upstream').getCurrentValue();
|
const upstreamFlow = this.measurements.type('flow').variant('measured').position('upstream').getCurrentValue();
|
||||||
|
|
||||||
// Only upstream => might still accept it, but warn
|
// Only upstream => might still accept it, but warn
|
||||||
if (upstreamFlow != null) {
|
if (upstreamFlow != null) {
|
||||||
@@ -416,7 +421,7 @@ class Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get
|
// get
|
||||||
const downstreamFlow = this.measurements.type('pressure').variant('measured').position('downstream').getCurrentValue();
|
const downstreamFlow = this.measurements.type('flow').variant('measured').position('downstream').getCurrentValue();
|
||||||
|
|
||||||
// Only downstream => might still accept it, but warn
|
// Only downstream => might still accept it, but warn
|
||||||
if (downstreamFlow != null) {
|
if (downstreamFlow != null) {
|
||||||
@@ -450,6 +455,7 @@ class Machine {
|
|||||||
if (this.state.getCurrentState() == "operational" || this.state.getCurrentState() == "accelerating" || this.state.getCurrentState() == "decelerating") {
|
if (this.state.getCurrentState() == "operational" || this.state.getCurrentState() == "accelerating" || this.state.getCurrentState() == "decelerating") {
|
||||||
// put value in measurements
|
// put value in measurements
|
||||||
this.measurements.type("pressure").variant("measured").position(position).value(value);
|
this.measurements.type("pressure").variant("measured").position(position).value(value);
|
||||||
|
this.logger.debug(`Updated measured pressure: ${value} at position: ${position}`);
|
||||||
//when measured pressure gets updated we need some logic to fetch the relevant value which could be downstream or differential pressure
|
//when measured pressure gets updated we need some logic to fetch the relevant value which could be downstream or differential pressure
|
||||||
const pressure = this.getMeasuredPressure();
|
const pressure = this.getMeasuredPressure();
|
||||||
//update the flow power and cog
|
//update the flow power and cog
|
||||||
@@ -539,6 +545,23 @@ class Machine {
|
|||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showWorkingCurves() {
|
||||||
|
// Show the current curves for debugging
|
||||||
|
const { powerCurve, flowCurve } = this.getCurrentCurves();
|
||||||
|
return {
|
||||||
|
powerCurve: powerCurve,
|
||||||
|
flowCurve: flowCurve,
|
||||||
|
cog: this.cog,
|
||||||
|
cogIndex: this.cogIndex,
|
||||||
|
NCog: this.NCog,
|
||||||
|
minEfficiency: this.minEfficiency,
|
||||||
|
currentEfficiencyCurve: this.currentEfficiencyCurve,
|
||||||
|
absDistFromPeak: this.absDistFromPeak,
|
||||||
|
relDistFromPeak: this.relDistFromPeak
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Calculate the center of gravity for current pressure
|
// Calculate the center of gravity for current pressure
|
||||||
calcCog() {
|
calcCog() {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user