diff --git a/rotatingMachine.html b/rotatingMachine.html index 05a3f6c..97d3265 100644 --- a/rotatingMachine.html +++ b/rotatingMachine.html @@ -68,6 +68,7 @@ }, oneditsave: function() { const node = this; + // save asset fields if (window.EVOLV?.nodes?.rotatingMachine?.assetMenu?.saveEditor) { window.EVOLV.nodes.rotatingMachine.assetMenu.saveEditor(this); diff --git a/src/nodeClass.js b/src/nodeClass.js index 792bfe1..6d20326 100644 --- a/src/nodeClass.js +++ b/src/nodeClass.js @@ -62,7 +62,7 @@ class nodeClass { unit: uiConfig.unit }, functionality: { - positionVsParent: uiConfig.positionVsParent || 'atEquipment', // Default to 'atEquipment' if not specified + positionVsParent: uiConfig.positionVsParent } }; diff --git a/src/specificClass.js b/src/specificClass.js index 69e399c..823f60c 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -20,7 +20,7 @@ * OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * Ownership of this code remains solely with the original author. Unauthorized + * Ownership of this code remainregisterChilds solely with the original author. Unauthorized * use of this Software is strictly prohibited. * * @summary A class to interact and manipulate machines with a non-euclidian curve @@ -120,18 +120,23 @@ class Machine { /*------------------- Register child events -------------------*/ registerChild(child, softwareType) { - this.logger.debug('Setting up child event listeners'); + this.logger.debug('Setting up child event for softwaretype ' + softwareType); if(softwareType === "measurement"){ const position = child.config.functionality.positionVsParent; + const distance = child.config.functionality.distanceVsParent || 0; const measurementType = child.config.asset.type; const key = `${measurementType}_${position}`; + //rebuild to measurementype.variant no position and then switch based on values not strings or names. const eventName = `${measurementType}.measured.${position}`; + this.logger.debug(`Setting up listener for ${eventName} from child ${child.config.general.name}`); // Register event listener for measurement updates child.measurements.emitter.on(eventName, (eventData) => { this.logger.debug(`🔄 ${position} ${measurementType} from ${eventData.childName}: ${eventData.value} ${eventData.unit}`); + + console.log(` Emitting... ${eventName} with data:`); // Store directly in parent's measurement container this.measurements .type(measurementType) @@ -214,37 +219,37 @@ _callMeasurementHandler(measurementType, value, position, context) { } async handleInput(source, action, parameter) { + if (!this.isValidSourceForMode(source, this.currentMode)) { let warningTxt = `Source '${source}' is not valid for mode '${this.currentMode}'.`; this.logger.warn(warningTxt); return {status : false , feedback: warningTxt}; } - this.logger.info(`Handling input from source '${source}' with action '${action}' in mode '${this.currentMode}'.`); + try { switch (action) { case "execSequence": - await this.executeSequence(parameter); - //recalc flow and power - this.updatePosition(); - break; + return await this.executeSequence(parameter); + case "execMovement": - await this.setpoint(parameter); - break; + return await this.setpoint(parameter); + case "flowMovement": // Calculate the control value for a desired flow const pos = this.calcCtrl(parameter); // Move to the desired setpoint - await this.setpoint(pos); - break; + return await this.setpoint(pos); + case "emergencyStop": this.logger.warn(`Emergency stop activated by '${source}'.`); - await this.executeSequence("emergencyStop"); - break; + return await this.executeSequence("emergencyStop"); + case "statusCheck": this.logger.info(`Status Check: Mode = '${this.currentMode}', Source = '${source}'.`); break; + default: this.logger.warn(`Action '${action}' is not implemented.`); break; @@ -254,6 +259,13 @@ _callMeasurementHandler(measurementType, value, position, context) { } catch (error) { this.logger.error(`Error handling input: ${error}`); } + + } + + abortMovement(reason = "group override") { + if (this.state?.abortCurrentMovement) { + this.state.abortCurrentMovement(reason); + } } setMode(newMode) { @@ -294,6 +306,9 @@ _callMeasurementHandler(measurementType, value, position, context) { break; // Exit sequence execution on error } } + + //recalc flow and power + this.updatePosition(); } async setpoint(setpoint) { @@ -341,20 +356,20 @@ _callMeasurementHandler(measurementType, value, position, context) { calcPower(x) { if(this.hasCurve) { if (!this._isOperationalState()) { - this.measurements.type("power").variant("predicted").position('upstream').value(0); + this.measurements.type("power").variant("predicted").position('atEquipment').value(0); this.logger.debug(`Machine is not operational. Setting predicted power to 0.`); return 0; } //this.predictPower.currentX = x; Decrepated const cPower = this.predictPower.y(x); - this.measurements.type("power").variant("predicted").position('upstream').value(cPower); + this.measurements.type("power").variant("predicted").position('atEquipment').value(cPower); //this.logger.debug(`Calculated power: ${cPower} for pressure: ${this.getMeasuredPressure()} and position: ${x}`); return cPower; } // If no curve data is available, log a warning and return 0 this.logger.warn(`No curve data available for power calculation. Returning 0.`); - this.measurements.type("power").variant("predicted").position('upstream').value(0); + this.measurements.type("power").variant("predicted").position('atEquipment').value(0); return 0; } @@ -372,7 +387,7 @@ _callMeasurementHandler(measurementType, value, position, context) { // If no curve data is available, log a warning and return 0 this.logger.warn(`No curve data available for power calculation. Returning 0.`); - this.measurements.type("power").variant("predicted").position('upstream').value(0); + this.measurements.type("power").variant("predicted").position('atEquipment').value(0); return 0; } @@ -382,14 +397,14 @@ _callMeasurementHandler(measurementType, value, position, context) { if(this.hasCurve) { this.predictCtrl.currentX = x; const cCtrl = this.predictCtrl.y(x); - this.measurements.type("ctrl").variant("predicted").position('upstream').value(cCtrl); + this.measurements.type("ctrl").variant("predicted").position('atEquipment').value(cCtrl); //this.logger.debug(`Calculated ctrl: ${cCtrl} for pressure: ${this.getMeasuredPressure()} and position: ${x}`); return cCtrl; } // If no curve data is available, log a warning and return 0 this.logger.warn(`No curve data available for control calculation. Returning 0.`); - this.measurements.type("ctrl").variant("predicted").position('upstream').value(0); + this.measurements.type("ctrl").variant("predicted").position('atEquipment').value(0); return 0; } @@ -398,9 +413,9 @@ _callMeasurementHandler(measurementType, value, position, context) { // this will be either the differential pressure, downstream or upstream pressure getMeasuredPressure() { const pressureDiff = this.measurements.type('pressure').variant('measured').difference(); - + // Both upstream & downstream => differential - if (pressureDiff != null) { + if (pressureDiff) { this.logger.debug(`Pressure differential: ${pressureDiff.value}`); this.predictFlow.fDimension = pressureDiff.value; this.predictPower.fDimension = pressureDiff.value; @@ -420,7 +435,7 @@ _callMeasurementHandler(measurementType, value, position, context) { // Only downstream => use it, warn that it's partial if (downstreamPressure != null) { - this.logger.warn(`Using downstream pressure only for prediction: ${downstreamPressure} `); + this.logger.warn(`Using downstream pressure only for prediction: ${downstreamPressure} This is less acurate!!`); this.predictFlow.fDimension = downstreamPressure; this.predictPower.fDimension = downstreamPressure; this.predictCtrl.fDimension = downstreamPressure; @@ -504,11 +519,7 @@ _callMeasurementHandler(measurementType, value, position, context) { // rich context handler for pressure updates updateMeasuredPressure(value, position, context = {}) { - if (!this._isOperationalState()) { - this.logger.warn(`Machine not operational, skipping pressure update from ${context.childName || 'unknown'}`); - return; - } - + // Enhanced logging with child context this.logger.debug(`Pressure update: ${value} at ${position} from ${context.childName || 'child'} (${context.childId || 'unknown-id'})`); @@ -548,6 +559,7 @@ _callMeasurementHandler(measurementType, value, position, context) { //what is the internal functions that need updating when something changes that has influence on this. updatePosition() { + if (this._isOperationalState()) { const currentPosition = this.state.getCurrentPosition(); @@ -659,12 +671,12 @@ _callMeasurementHandler(measurementType, value, position, context) { if (power != 0 && flow != 0) { // Calculate efficiency after measurements update - this.measurements.type("efficiency").variant(variant).position('downstream').value((flow / power)); + this.measurements.type("efficiency").variant(variant).position('atEquipment').value((flow / power)); } else { - this.measurements.type("efficiency").variant(variant).position('downstream').value(null); + this.measurements.type("efficiency").variant(variant).position('atEquipment').value(null); } - return this.measurements.type("efficiency").variant(variant).position('downstream').getCurrentValue(); + return this.measurements.type("efficiency").variant(variant).position('atEquipment').getCurrentValue(); }