Compare commits
1 Commits
5ca7889af1
...
a2018509ef
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2018509ef |
@@ -24,11 +24,11 @@
|
|||||||
"models": [
|
"models": [
|
||||||
{
|
{
|
||||||
"name": "VegaPressure 10",
|
"name": "VegaPressure 10",
|
||||||
"units": ["bar", "m WC", "psi"]
|
"units": ["bar", "mbar", "psi"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VegaPressure 20",
|
"name": "VegaPressure 20",
|
||||||
"units": ["bar", "m WC", "psi"]
|
"units": ["bar", "mbar", "psi"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -60,10 +60,8 @@
|
|||||||
"models": [
|
"models": [
|
||||||
{
|
{
|
||||||
"id": "hidrostal-pump-001",
|
"id": "hidrostal-pump-001",
|
||||||
"name": "H05K-S03R+HGM1X-X280KO",
|
"name": "hidrostal-H05K-S03R",
|
||||||
"units": ["m³/h", "gpm", "l/min"],
|
"units": ["m³/h", "gpm", "l/min"]
|
||||||
"hasCurveData": true,
|
|
||||||
"curveDataFile": "/data/curves/hidrostal-H05K-S03R.json"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"curve": {
|
|
||||||
"np": {
|
"np": {
|
||||||
"700": {
|
"700": {
|
||||||
"x": [
|
"x": [
|
||||||
@@ -139,7 +138,7 @@
|
|||||||
],
|
],
|
||||||
"y": [
|
"y": [
|
||||||
11.498673648884504,
|
11.498673648884504,
|
||||||
20.996631954252725,
|
20.996631954252724,
|
||||||
31.954252725886462,
|
31.954252725886462,
|
||||||
45.54353714625641,
|
45.54353714625641,
|
||||||
63.22528016894755
|
63.22528016894755
|
||||||
@@ -1061,4 +1060,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
5
index.js
5
index.js
@@ -23,7 +23,7 @@ const MenuManager = require('./src/menu/index.js');
|
|||||||
const predict = require('./src/predict/predict_class.js');
|
const predict = require('./src/predict/predict_class.js');
|
||||||
const interpolation = require('./src/predict/interpolation.js');
|
const interpolation = require('./src/predict/interpolation.js');
|
||||||
const childRegistrationUtils = require('./src/helper/childRegistrationUtils.js');
|
const childRegistrationUtils = require('./src/helper/childRegistrationUtils.js');
|
||||||
|
const { loadCurve } = require('./datasets/assetData/curves/index.js');
|
||||||
|
|
||||||
// Export everything
|
// Export everything
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@@ -39,5 +39,6 @@ module.exports = {
|
|||||||
state,
|
state,
|
||||||
convert,
|
convert,
|
||||||
MenuManager,
|
MenuManager,
|
||||||
childRegistrationUtils
|
childRegistrationUtils,
|
||||||
|
loadCurve
|
||||||
};
|
};
|
||||||
216
src/configs/machineGroupControl.json
Normal file
216
src/configs/machineGroupControl.json
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
{
|
||||||
|
"general": {
|
||||||
|
"name": {
|
||||||
|
"default": "Machine Group Configuration",
|
||||||
|
"rules": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "A human-readable name or label for this machine group configuration."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"default": null,
|
||||||
|
"rules": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true,
|
||||||
|
"description": "A unique identifier for this configuration. If not provided, defaults to null."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"unit": {
|
||||||
|
"default": "m3/h",
|
||||||
|
"rules": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The default measurement unit for this configuration (e.g., 'meters', 'seconds', 'unitless')."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"logging": {
|
||||||
|
"logLevel": {
|
||||||
|
"default": "info",
|
||||||
|
"rules": {
|
||||||
|
"type": "enum",
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"value": "debug",
|
||||||
|
"description": "Log messages are printed for debugging purposes."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "info",
|
||||||
|
"description": "Informational messages are printed."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "warn",
|
||||||
|
"description": "Warning messages are printed."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "error",
|
||||||
|
"description": "Error messages are printed."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enabled": {
|
||||||
|
"default": true,
|
||||||
|
"rules": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Indicates whether logging is active. If true, log messages will be generated."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"functionality": {
|
||||||
|
"softwareType": {
|
||||||
|
"default": "machineGroup",
|
||||||
|
"rules": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Logical name identifying the software type."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"default": "GroupController",
|
||||||
|
"rules": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Controls a group of machines within the system."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"positionVsParent":{
|
||||||
|
"default":"atEquipment",
|
||||||
|
"rules": {
|
||||||
|
"type": "enum",
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"value": "atEquipment",
|
||||||
|
"description": "The node is connected at the equipment level and is responsible for controlling or monitoring the equipment as a whole."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "upstream",
|
||||||
|
"description": "The node is connected in a downstream position, indicating it is responsible for monitoring or controlling processes that occur after the equipment's operation, such as product flow or output."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "downstream",
|
||||||
|
"description": "The node is connected in an upstream position, indicating it is responsible for monitoring or controlling processes that occur before the equipment's operation, such as input flow or supply."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Defines the position of the measurement relative to its parent equipment or system."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"current": {
|
||||||
|
"default": "optimalControl",
|
||||||
|
"rules": {
|
||||||
|
"type": "enum",
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"value": "optimalControl",
|
||||||
|
"description": "The group controller selects the most optimal combination of machines based on their real-time performance curves."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "priorityControl",
|
||||||
|
"description": "Machines are controlled sequentially from minimum to maximum output until each is maxed out, then additional machines are added."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "prioritypercentagecontrol",
|
||||||
|
"description": "Machines are controlled sequentially from minimum to maximum output until each is maxed out, then additional machines are added based on a percentage of the total demand."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "maintenance",
|
||||||
|
"description": "The group is in maintenance mode with limited actions (monitoring only)."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "The operational mode of the machine group controller."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"allowedActions": {
|
||||||
|
"default": {},
|
||||||
|
"rules": {
|
||||||
|
"type": "object",
|
||||||
|
"schema": {
|
||||||
|
"optimalControl": {
|
||||||
|
"default": ["statusCheck", "execOptimalCombination", "balanceLoad", "emergencyStop"],
|
||||||
|
"rules": {
|
||||||
|
"type": "set",
|
||||||
|
"itemType": "string",
|
||||||
|
"description": "Actions allowed in optimalControl mode."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"priorityControl": {
|
||||||
|
"default": ["statusCheck", "execSequentialControl", "balanceLoad", "emergencyStop"],
|
||||||
|
"rules": {
|
||||||
|
"type": "set",
|
||||||
|
"itemType": "string",
|
||||||
|
"description": "Actions allowed in priorityControl mode."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prioritypercentagecontrol": {
|
||||||
|
"default": ["statusCheck", "execSequentialControl", "balanceLoad", "emergencyStop"],
|
||||||
|
"rules": {
|
||||||
|
"type": "set",
|
||||||
|
"itemType": "string",
|
||||||
|
"description": "Actions allowed in manualOverride mode."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"maintenance": {
|
||||||
|
"default": ["statusCheck"],
|
||||||
|
"rules": {
|
||||||
|
"type": "set",
|
||||||
|
"itemType": "string",
|
||||||
|
"description": "Actions allowed in maintenance mode."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Defines the actions available for each operational mode of the machine group controller."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"allowedSources": {
|
||||||
|
"default": {},
|
||||||
|
"rules": {
|
||||||
|
"type": "object",
|
||||||
|
"schema": {
|
||||||
|
"optimalcontrol": {
|
||||||
|
"default": ["parent", "GUI", "physical", "API"],
|
||||||
|
"rules": {
|
||||||
|
"type": "set",
|
||||||
|
"itemType": "string",
|
||||||
|
"description": "Command sources allowed in optimalControl mode."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prioritycontrol": {
|
||||||
|
"default": ["parent", "GUI", "physical", "API"],
|
||||||
|
"rules": {
|
||||||
|
"type": "set",
|
||||||
|
"itemType": "string",
|
||||||
|
"description": "Command sources allowed in priorityControl mode."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prioritypercentagecontrol": {
|
||||||
|
"default": ["parent", "GUI", "physical", "API"],
|
||||||
|
"rules": {
|
||||||
|
"type": "set",
|
||||||
|
"itemType": "string",
|
||||||
|
"description": "Command sources allowed "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Specifies the valid command sources recognized by the machine group controller for each mode."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scaling": {
|
||||||
|
"current": {
|
||||||
|
"default": "normalized",
|
||||||
|
"rules": {
|
||||||
|
"type": "enum",
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"value": "normalized",
|
||||||
|
"description": "Scales the demand between 0–100% of the total flow capacity, interpolating to calculate the effective demand."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "absolute",
|
||||||
|
"description": "Uses the absolute demand value directly, capped between the min and max machine flow capacities."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "The scaling mode for demand calculations."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -102,6 +102,14 @@
|
|||||||
"description": "A universally unique identifier for this asset. May be null if not assigned."
|
"description": "A universally unique identifier for this asset. May be null if not assigned."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tagCode":{
|
||||||
|
"default": null,
|
||||||
|
"rules": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true,
|
||||||
|
"description": "Asset tag code which is a unique identifier for this asset. May be null if not assigned."
|
||||||
|
}
|
||||||
|
},
|
||||||
"geoLocation": {
|
"geoLocation": {
|
||||||
"default": {},
|
"default": {},
|
||||||
"rules": {
|
"rules": {
|
||||||
@@ -139,14 +147,14 @@
|
|||||||
"description": "The supplier or manufacturer of the asset."
|
"description": "The supplier or manufacturer of the asset."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"type": {
|
"category": {
|
||||||
"default": "pump",
|
"default": "pump",
|
||||||
"rules": {
|
"rules": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "A general classification of the asset tied to the specific software. This is not chosen from the asset dropdown menu."
|
"description": "A general classification of the asset tied to the specific software. This is not chosen from the asset dropdown menu."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"subType": {
|
"type": {
|
||||||
"default": "Centrifugal",
|
"default": "Centrifugal",
|
||||||
"rules": {
|
"rules": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -160,6 +168,13 @@
|
|||||||
"description": "A user-defined or manufacturer-defined model identifier for the asset."
|
"description": "A user-defined or manufacturer-defined model identifier for the asset."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"unit": {
|
||||||
|
"default": "unitless",
|
||||||
|
"rules": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The unit of measurement for this asset (e.g., 'meters', 'seconds', 'unitless')."
|
||||||
|
}
|
||||||
|
},
|
||||||
"accuracy": {
|
"accuracy": {
|
||||||
"default": null,
|
"default": null,
|
||||||
"rules": {
|
"rules": {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ class ChildRegistrationUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async registerChild(child, positionVsParent) {
|
async registerChild(child, positionVsParent) {
|
||||||
|
|
||||||
const { softwareType } = child.config.functionality;
|
const { softwareType } = child.config.functionality;
|
||||||
const { name, id, unit } = child.config.general;
|
const { name, id, unit } = child.config.general;
|
||||||
const { type = "", subType = "" } = child.config.asset || {};
|
const { type = "", subType = "" } = child.config.asset || {};
|
||||||
@@ -28,24 +29,6 @@ class ChildRegistrationUtils {
|
|||||||
this.mainClass.child[softwareType][type][subType] = [];
|
this.mainClass.child[softwareType][type][subType] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the child in the cloud when available and supply the new child on base of tagcode OLIFANT WE NEED TO FIX THIS SO ITS DYNAMIC!
|
|
||||||
/*
|
|
||||||
try{
|
|
||||||
const url = "https://pimmoerman.nl/rdlab/tagcode.app/v2.1/api/asset/create_asset.php?";
|
|
||||||
const TagCode = child.config.asset.tagCode;
|
|
||||||
//console.log(`Register child => ${TagCode}`);
|
|
||||||
const completeURL = url + `asset_product_model_id=1&asset_product_model_uuid=123456789&asset_name=AssetNaam&asset_description=Beschrijving&asset_status=actief&asset_profile_id=1&asset_location_id=1&asset_process_id=11&asset_tag_number=${TagCode}&child_assets=[L6616]`;
|
|
||||||
|
|
||||||
await fetch(completeURL, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}catch(e){
|
|
||||||
console.log("Error saving assetID and tagnumber", e);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Push the new child to the array of the mainclass so we can track the childs
|
// Push the new child to the array of the mainclass so we can track the childs
|
||||||
this.mainClass.child[softwareType][type][subType].push({
|
this.mainClass.child[softwareType][type][subType].push({
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ class PhysicalPositionMenu {
|
|||||||
return {
|
return {
|
||||||
positionGroups: [
|
positionGroups: [
|
||||||
{ group: 'Positional', options: [
|
{ group: 'Positional', options: [
|
||||||
{ value: 'upstream', label: '⬅ Upstream' },
|
{ value: 'upstream', label: '← Upstream', icon: '←'},
|
||||||
{ value: 'atEquipment', label: '⚙️ At Equipment' },
|
{ value: 'atEquipment', label: '⊥ in place' , icon: '⊥' },
|
||||||
{ value: 'downstream', label: '➡ Downstream' }
|
{ value: 'downstream', label: '→ Downstream' , icon: '→' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -61,6 +61,7 @@ class PhysicalPositionMenu {
|
|||||||
const opt = document.createElement('option');
|
const opt = document.createElement('option');
|
||||||
opt.value = o.value;
|
opt.value = o.value;
|
||||||
opt.textContent = o.label;
|
opt.textContent = o.label;
|
||||||
|
opt.setAttribute('data-icon', o.icon);
|
||||||
optg.appendChild(opt);
|
optg.appendChild(opt);
|
||||||
});
|
});
|
||||||
sel.appendChild(optg);
|
sel.appendChild(optg);
|
||||||
@@ -88,6 +89,8 @@ class PhysicalPositionMenu {
|
|||||||
window.EVOLV.nodes.${nodeName}.positionMenu.saveEditor = function(node) {
|
window.EVOLV.nodes.${nodeName}.positionMenu.saveEditor = function(node) {
|
||||||
const sel = document.getElementById('node-input-positionVsParent');
|
const sel = document.getElementById('node-input-positionVsParent');
|
||||||
node.positionVsParent = sel? sel.value : 'atEquipment';
|
node.positionVsParent = sel? sel.value : 'atEquipment';
|
||||||
|
node.positionLabel = sel? sel.options[sel.selectedIndex].textContent : 'At Equipment';
|
||||||
|
node.positionIcon = sel? sel.options[sel.selectedIndex].getAttribute('data-icon') : 'fa fa-cog';
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
`;
|
`;
|
||||||
|
|||||||
Reference in New Issue
Block a user