Compare commits
11 Commits
bef39bc533
...
dev-Rene
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
339ae6bdde | ||
| 756cc4bd20 | |||
|
|
a12c083b3f | ||
| 496c5688bc | |||
|
|
5a0c46cb67 | ||
|
|
b1ba23212d | ||
|
|
f6da9a6fc5 | ||
|
|
94da1a36e4 | ||
| 9a7b5a93ed | |||
|
|
be7c929600 | ||
|
|
de76803f7e |
@@ -1,11 +1,20 @@
|
|||||||
|
<!--
|
||||||
|
| S88-niveau | Primair (blokkleur) | Tekstkleur |
|
||||||
|
| ---------------------- | ------------------- | ---------- |
|
||||||
|
| **Area** | `#0f52a5` | wit |
|
||||||
|
| **Process Cell** | `#0c99d9` | wit |
|
||||||
|
| **Unit** | `#50a8d9` | zwart |
|
||||||
|
| **Equipment (Module)** | `#86bbdd` | zwart |
|
||||||
|
| **Control Module** | `#a9daee` | zwart |
|
||||||
|
|
||||||
|
-->
|
||||||
<script src="/measurement/menu.js"></script> <!-- Load the menu script for dynamic dropdowns -->
|
<script src="/measurement/menu.js"></script> <!-- Load the menu script for dynamic dropdowns -->
|
||||||
<script src="/measurement/configData.js"></script> <!-- Load the config script for node information -->
|
<script src="/measurement/configData.js"></script> <!-- Load the config script for node information -->
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
RED.nodes.registerType("measurement", {
|
RED.nodes.registerType("measurement", {
|
||||||
category: "EVOLV",
|
category: "EVOLV",
|
||||||
color: "#e4a363", // color for the node based on the S88 schema
|
color: "#a9daee", // color for the node based on the S88 schema
|
||||||
defaults: {
|
defaults: {
|
||||||
|
|
||||||
// Define default properties
|
// Define default properties
|
||||||
@@ -37,6 +46,10 @@
|
|||||||
//physicalAspect
|
//physicalAspect
|
||||||
positionVsParent: { value: "" },
|
positionVsParent: { value: "" },
|
||||||
positionIcon: { value: "" },
|
positionIcon: { value: "" },
|
||||||
|
hasDistance: { value: false },
|
||||||
|
distance: { value: 0 },
|
||||||
|
distanceUnit: { value: "m" },
|
||||||
|
distanceDescription: { value: "" }
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -44,7 +57,7 @@
|
|||||||
outputs: 3,
|
outputs: 3,
|
||||||
inputLabels: ["Input"],
|
inputLabels: ["Input"],
|
||||||
outputLabels: ["process", "dbase", "parent"],
|
outputLabels: ["process", "dbase", "parent"],
|
||||||
icon: "font-awesome/fa-tachometer",
|
icon: "font-awesome/fa-sliders",
|
||||||
|
|
||||||
label: function () {
|
label: function () {
|
||||||
return this.positionIcon + " " + this.assetType || "Measurement";
|
return this.positionIcon + " " + this.assetType || "Measurement";
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class nodeClass {
|
|||||||
// Merge UI config over defaults
|
// Merge UI config over defaults
|
||||||
this.config = {
|
this.config = {
|
||||||
general: {
|
general: {
|
||||||
name: uiConfig.name,
|
name: this.name,
|
||||||
id: node.id, // node.id is for the child registration process
|
id: node.id, // node.id is for the child registration process
|
||||||
unit: uiConfig.unit, // add converter options later to convert to default units (need like a model that defines this which units we are going to use and then conver to those standards)
|
unit: uiConfig.unit, // add converter options later to convert to default units (need like a model that defines this which units we are going to use and then conver to those standards)
|
||||||
logging: {
|
logging: {
|
||||||
@@ -81,10 +81,13 @@ class nodeClass {
|
|||||||
enabled: uiConfig.simulator
|
enabled: uiConfig.simulator
|
||||||
},
|
},
|
||||||
functionality: {
|
functionality: {
|
||||||
positionVsParent: uiConfig.positionVsParent || 'atEquipment', // Default to 'atEquipment' if not specified
|
positionVsParent: uiConfig.positionVsParent,// Default to 'atEquipment' if not specified
|
||||||
|
distance: uiConfig.hasDistance ? uiConfig.distance : undefined
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log(`position vs child for ${this.name} is ${this.config.functionality.positionVsParent} the distance is ${this.config.functionality.distance}`);
|
||||||
|
|
||||||
// Utility for formatting outputs
|
// Utility for formatting outputs
|
||||||
this._output = new outputUtils();
|
this._output = new outputUtils();
|
||||||
}
|
}
|
||||||
@@ -101,9 +104,11 @@ class nodeClass {
|
|||||||
* Bind Measurement events to Node-RED status updates. Using internal emitter. --> REMOVE LATER WE NEED ONLY COMPLETE CHILDS AND THEN CHECK FOR UPDATES
|
* Bind Measurement 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.source.emitter.on('mAbs', (val) => {
|
||||||
this.node.status({ fill: 'green', shape: 'dot', text: `${val} ${this.config.general.unit}` });
|
this.node.status({ fill: 'green', shape: 'dot', text: `${val} ${this.config.general.unit}` });
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,7 +120,7 @@ class nodeClass {
|
|||||||
this.node.send([
|
this.node.send([
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
{ topic: 'registerChild', payload: this.node.id , positionVsParent: this.config?.functionality?.positionVsParent || 'atEquipment' },
|
{ topic: 'registerChild', payload: this.node.id , positionVsParent: this.config?.functionality?.positionVsParent || 'atEquipment' , distance: this.config?.functionality?.distance || null},
|
||||||
]);
|
]);
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,3 @@
|
|||||||
/**
|
|
||||||
* @file Measurement.js
|
|
||||||
*
|
|
||||||
* Permission is hereby granted to any person obtaining a copy of this software
|
|
||||||
* and associated documentation files (the "Software"), to use it for personal
|
|
||||||
* or non-commercial purposes, with the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. **No Copying or Redistribution**: The Software or any of its parts may not
|
|
||||||
* be copied, merged, distributed, sublicensed, or sold without explicit
|
|
||||||
* prior written permission from the author.
|
|
||||||
*
|
|
||||||
* 2. **Commercial Use**: Any use of the Software for commercial purposes requires
|
|
||||||
* a valid license, obtainable only with the explicit consent of the author.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM,
|
|
||||||
* 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
|
|
||||||
* use of this Software is strictly prohibited.
|
|
||||||
*
|
|
||||||
* Author:
|
|
||||||
* - Rene De Ren
|
|
||||||
* Email:
|
|
||||||
* - r.de.ren@brabantsedelta.nl
|
|
||||||
*
|
|
||||||
* Future Improvements:
|
|
||||||
* - Time-based stability checks
|
|
||||||
* - Warmup handling
|
|
||||||
* - Dynamic outlier detection thresholds
|
|
||||||
* - Dynamic smoothing window and methods
|
|
||||||
* - Alarm and threshold handling
|
|
||||||
* - Maintenance mode
|
|
||||||
* - Historical data and trend analysis
|
|
||||||
*/
|
|
||||||
|
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const {logger,configUtils,configManager,MeasurementContainer} = require('generalFunctions');
|
const {logger,configUtils,configManager,MeasurementContainer} = require('generalFunctions');
|
||||||
|
|
||||||
@@ -59,6 +19,9 @@ class Measurement {
|
|||||||
windowSize: this.config.smoothing.smoothWindow
|
windowSize: this.config.smoothing.smoothWindow
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.measurements.setChildId(this.config.general.id);
|
||||||
|
this.measurements.setChildName(this.config.general.name);
|
||||||
|
|
||||||
// Smoothing
|
// Smoothing
|
||||||
this.storedValues = [];
|
this.storedValues = [];
|
||||||
|
|
||||||
@@ -494,8 +457,18 @@ class Measurement {
|
|||||||
|
|
||||||
updateOutputAbs(val) {
|
updateOutputAbs(val) {
|
||||||
|
|
||||||
|
// Constrain first, then check for changes
|
||||||
|
let constrainedVal = val;
|
||||||
|
|
||||||
|
if (val < this.config.scaling.absMin || val > this.config.scaling.absMax) {
|
||||||
|
this.logger.warn(`Output value=${val} is outside of ABS range. Constraining.`);
|
||||||
|
constrainedVal = this.constrain(val, this.config.scaling.absMin, this.config.scaling.absMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
const roundedVal = Math.round(constrainedVal * 100) / 100;
|
||||||
|
|
||||||
//only update on change
|
//only update on change
|
||||||
if(val != this.outputAbs){
|
if (roundedVal != this.outputAbs) {
|
||||||
|
|
||||||
// Constrain value within process range
|
// Constrain value within process range
|
||||||
if (val < this.config.scaling.absMin || val > this.config.scaling.absMax) {
|
if (val < this.config.scaling.absMin || val > this.config.scaling.absMax) {
|
||||||
@@ -508,9 +481,8 @@ class Measurement {
|
|||||||
|
|
||||||
this.emitter.emit('mAbs', this.outputAbs);// DEPRECATED: Use measurements container instead
|
this.emitter.emit('mAbs', this.outputAbs);// DEPRECATED: Use measurements container instead
|
||||||
|
|
||||||
// In the new method just update the measurement container and let the parent subscribe to it
|
|
||||||
this.logger.debug(`Updating type: ${this.config.asset.type}, variant: ${"measured"}, postition : ${this.config.functionality.positionVsParent} container with new value: ${this.outputAbs}`);
|
this.logger.debug(`Updating type: ${this.config.asset.type}, variant: ${"measured"}, postition : ${this.config.functionality.positionVsParent} container with new value: ${this.outputAbs}`);
|
||||||
this.measurements.type(this.config.asset.type).variant("measured").position(this.config.functionality.positionVsParent).value(this.outputAbs, Date.now(),this.config.asset.unit ); // New method
|
this.measurements.type(this.config.asset.type).variant("measured").position(this.config.functionality.positionVsParent).distance(this.config.functionality.distance).value(this.outputAbs, Date.now(),this.config.asset.unit );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user