2025-05-14 10:08:34 +02:00
< script type = "module" >
import * as menuUtils from "/generalFunctions/helper/menuUtils.js";
RED.nodes.registerType('monster', {
category: 'wbd typical',
color: '#4f8582',
defaults: {
// Define default properties
name: { value: "", required: true },
enableLog: { value: false },
logLevel: { value: "error" },
// Define specific properties
samplingtime: { value: 0 },
minvolume: { value: 5 },
maxweight: { value: 22 },
emptyWeightBucket: { value: 3 },
aquon_sample_name: { value: "" },
//define asset properties
supplier: { value: "" },
subType: { value: "" },
model: { value: "" },
unit: { value: "" },
},
inputs: 1,
outputs: 4,
inputLabels: ["Measurement Input"],
outputLabels: ["process", "dbase", "upstreamParent", "downstreamParent"],
2025-10-14 14:08:12 +02:00
icon: "font-awesome/fa-exchange",
2025-05-14 10:08:34 +02:00
// Define label function
label: function() {
return this.name || "Monsternamekast";
},
oneditprepare: function() {
const node = this;
// Define UI html elements
const elements = {
// Basic fields
name: document.getElementById("node-input-name"),
// specific fields
samplingtime: document.getElementById("node-input-samplingtime"),
minvolume: document.getElementById("node-input-minvolume"),
maxweight: document.getElementById("node-input-maxweight"),
emptyWeightBucket: document.getElementById("node-input-emptyWeightBucket"),
aquon_sample_name: document.getElementById("node-input-aquon_sample_name"),
// Logging fields
logCheckbox: document.getElementById("node-input-enableLog"),
logLevelSelect: document.getElementById("node-input-logLevel"),
rowLogLevel: document.getElementById("row-logLevel"),
// Asset fields
supplier: document.getElementById("node-input-supplier"),
subType: document.getElementById("node-input-subType"),
model: document.getElementById("node-input-model"),
unit: document.getElementById("node-input-unit"),
};
//this needs to live somewhere and for now we add it to every node file for simplicity
const projecSettingstURL = "http://localhost:1880/generalFunctions/settings/projectSettings.json";
try{
// Fetch project settings
menuUtils.fetchProjectData(projecSettingstURL)
.then((projectSettings) => {
//assign to node vars
node.configUrls = projectSettings.configUrls;
const { cloudConfigURL, localConfigURL } = menuUtils.getSpecificConfigUrl("monster",node.configUrls.cloud.taggcodeAPI);
node.configUrls.cloud.config = cloudConfigURL; // first call
node.configUrls.local.config = localConfigURL; // backup call
node.locationId = projectSettings.locationId;
node.uuid = projectSettings.uuid;
// Gets the ID of the active workspace (Flow)
const activeFlowId = RED.workspaces.active(); //fetches active flow id
node.processId = activeFlowId;
// UI elements across all nodes
menuUtils.fetchAndPopulateDropdowns(node.configUrls, elements, node); // function for all assets
menuUtils.initBasicToggles(elements);
})
}catch(e){
console.log("Error fetching project settings", e);
}
},
oneditsave: function() {
const node = this;
console.log(`------------ Saving changes to node ------------`);
console.log(`${node.uuid}`);
// Save basic properties
[ "name", "supplier", "subType", "model" ,"unit" ].forEach(
(field) => (node[field] = document.getElementById(`node-input-${field}`).value || "")
);
// Save numeric and boolean properties
["enableLog"].forEach(
(field) => (node[field] = document.getElementById(`node-input-${field}`).checked)
);
["samplingtime","minvolume","maxweight","emptyWeightBucket","aquon_sample_name"].forEach(
(field) => (node[field] = parseFloat(document.getElementById(`node-input-${field}`).value) || 0)
);
node.logLevel = document.getElementById("node-input-logLevel").value || "info";
// Validation checks
if (node.scaling & & (isNaN(node.i_min) || isNaN(node.i_max))) {
RED.notify("Scaling enabled, but input range is incomplete!", "error");
}
if (!node.unit) {
RED.notify("Unit selection is required.", "error");
}
if (node.subType & & !node.unit) {
RED.notify("Unit must be set when specifying a subtype.", "error");
}
console.log("stored node modelData", node.modelMetadata);
console.log("------------ Changes saved to measurement node preparing to save to API ------------");
try{
// Fetch project settings
menuUtils.apiCall(node,node.configUrls)
.then((response) => {
//save response to node information
node.assetId = response.asset_id;
node.assetTagCode = response.asset_tag_number;
})
.catch((error) => {
console.log("Error during API call", error);
});
}catch(e){
console.log("Error saving assetID and tagnumber", e);
}
}
});
< / script >
<!-- Main UI -->
< script type = "text/html" data-template-name = "monster" >
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INPUT NAME / TYPE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Node Name -->
< div class = "form-row" >
< label for = "node-input-name" > < i class = "fa fa-tag" > < / i > Name< / label >
< input type = "text" id = "node-input-name" placeholder = "Measurement Name" >
< / div >
<!-- Sampling Time -->
< div class = "form-row" >
< label for = "node-input-samplingtime" > < i class = "fa fa-clock-o" > < / i > Sampling Time (hours)< / label >
< input type = "number" id = "node-input-samplingtime" placeholder = "Enter sampling time in hours" min = "0" required >
< / div >
<!-- Minimum Volume -->
< div class = "form-row" >
< label for = "node-input-minvolume" > < i class = "fa fa-tint" > < / i > Minimum Volume (liters)< / label >
< input type = "number" id = "node-input-minvolume" placeholder = "Enter minimum volume in liters" min = "0" required >
< / div >
<!-- Maximum Weight -->
< div class = "form-row" >
< label for = "node-input-maxweight" > < i class = "fa fa-balance-scale" > < / i > Maximum Weight (kg)< / label >
< input type = "number" id = "node-input-maxweight" placeholder = "Enter maximum weight in kg" min = "0" required >
< / div >
<!-- Empty Bucket Weight -->
< div class = "form-row" >
< label for = "node-input-emptyWeightBucket" > < i class = "fa fa-bucket" > < / i > Empty Bucket Weight (kg)< / label >
< input type = "number" id = "node-input-emptyWeightBucket" placeholder = "Enter empty bucket weight in kg" min = "0" required >
< / div >
<!-- Aquon Sample Name -->
< div class = "form-row" >
< label for = "node-input-aquon_sample_name" > < i class = "fa fa-flask" > < / i > Aquon Sample Name< / label >
< input type = "text" id = "node-input-aquon_sample_name" placeholder = "Enter Aquon sample name" >
< / div >
<!-- Optional Extended Fields: supplier, type, subType, model -->
< hr / >
< div class = "form-row" >
< label for = "node-input-supplier"
>< i class = "fa fa-industry" > < / i > Supplier< / label >
< select id = "node-input-supplier" style = "width:60%;" >
< option value = "" > (optional)< / option >
< / select >
< / div >
< div class = "form-row" >
< label for = "node-input-subType"
>< i class = "fa fa-puzzle-piece" > < / i > SubType< / label >
< select id = "node-input-subType" style = "width:60%;" >
< option value = "" > (optional)< / option >
< / select >
< / div >
< div class = "form-row" >
< label for = "node-input-model" > < i class = "fa fa-wrench" > < / i > Model< / label >
< select id = "node-input-model" style = "width:60%;" >
< option value = "" > (optional)< / option >
< / select >
< / div >
< div class = "form-row" >
< label for = "node-input-unit" > < i class = "fa fa-balance-scale" > < / i > Unit< / label >
< select id = "node-input-unit" style = "width:60%;" > < / select >
< / div >
< hr / >
<!-- loglevel checkbox -->
< div class = "form-row" >
< label for = "node-input-enableLog"
>< i class = "fa fa-cog" > < / i > Enable Log< / label >
< input
type="checkbox"
id="node-input-enableLog"
style="width:20px; vertical-align:baseline;"
/>
< span > Enable logging< / span >
< / div >
< div class = "form-row" id = "row-logLevel" >
< label for = "node-input-logLevel" > < i class = "fa fa-cog" > < / i > Log Level< / label >
< select id = "node-input-logLevel" style = "width:60%;" >
< option value = "info" > Info< / option >
< option value = "debug" > Debug< / option >
< option value = "warn" > Warn< / option >
< option value = "error" > Error< / option >
< / select >
< / div >
< / script >
< script type = "text/html" data-help-name = "monster" >
< p > < b > Monster Node< / b > : Configures and manages monster measurement data.< / p >
< p > Use this node to configure and manage monster measurement data. The node can be configured to handle various measurement parameters and asset properties.< / p >
< li > < b > Supplier:< / b > Select a supplier to populate machine options.< / li >
< li > < b > SubType:< / b > Select a subtype if applicable to further categorize the asset.< / li >
< li > < b > Model:< / b > Define the specific model for more granular asset configuration.< / li >
< li > < b > Unit:< / b > Assign a unit to standardize measurements or operations.< / li >
< li > < b > Sampling Time:< / b > Define the sampling time in hours for measurements.< / li >
< li > < b > Minimum Volume:< / b > Specify the minimum volume in liters.< / li >
< li > < b > Maximum Weight:< / b > Specify the maximum weight in kilograms.< / li >
< li > < b > Empty Bucket Weight:< / b > Define the weight of the empty bucket in kilograms.< / li >
< li > < b > Aquon Sample Name:< / b > Provide the name for the Aquon sample.< / li >
< li > < b > Enable Log:< / b > Enable or disable logging for this node.< / li >
< li > < b > Log Level:< / b > Select the log level (Info, Debug, Warn, Error) for logging messages.< / li >
< / script >