changed the folder and added index.js

This commit is contained in:
znetsixe
2025-06-10 12:36:39 +02:00
parent fda8cb33db
commit bc9e3cda90
24 changed files with 3848 additions and 2 deletions

132
src/helper/outputUtils.js Normal file
View File

@@ -0,0 +1,132 @@
//this class will handle the output events for the node red node
class OutputUtils {
constructor() {
this.output ={};
this.output['influxdb'] = {};
this.output['process'] = {};
}
checkForChanges(output, format) {
const changedFields = {};
for (const key in output) {
if (output.hasOwnProperty(key) && output[key] !== this.output[format][key]) {
let value = output[key];
// For fields: if the value is an object (and not a Date), stringify it.
if (value !== null && typeof value === 'object' && !(value instanceof Date)) {
changedFields[key] = JSON.stringify(value);
} else {
changedFields[key] = value;
}
}
}
// Update the saved output state.
this.output[format] = { ...this.output[format], ...changedFields };
return changedFields;
}
formatMsg(output, config, format) {
//define emtpy message
let msg = {};
// Compare output with last output and only include changed values
const changedFields = this.checkForChanges(output,format);
if (Object.keys(changedFields).length > 0) {
switch (format) {
case 'influxdb':
// Extract the relevant config properties.
const relevantConfig = this.extractRelevantConfig(config);
// Flatten the tags so that no nested objects are passed on.
const flatTags = this.flattenTags(relevantConfig);
msg = this.influxDBFormat(changedFields, config, flatTags);
break;
case 'process':
// Compare output with last output and only include changed values
msg = this.processFormat(changedFields,config);
//console.log(msg);
break;
default:
console.log('Unknown format in output utils');
break;
}
return msg;
}
}
influxDBFormat(changedFields, config , flatTags) {
// Create the measurement and topic using softwareType and name config.functionality.softwareType + .
const measurement = config.general.name;
const payload = {
measurement: measurement,
fields: changedFields,
tags: flatTags,
timestamp: new Date(),
};
const topic = measurement;
const msg = { topic: topic, payload: payload };
return msg;
}
flattenTags(obj) {
const result = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
if (value !== null && typeof value === 'object' && !(value instanceof Date)) {
// Recursively flatten the nested object.
const flatChild = this.flattenTags(value);
for (const childKey in flatChild) {
if (flatChild.hasOwnProperty(childKey)) {
result[`${key}_${childKey}`] = String(flatChild[childKey]);
}
}
} else {
// InfluxDB tags must be strings.
result[key] = String(value);
}
}
}
return result;
}
extractRelevantConfig(config) {
return {
// general properties
id: config.general?.id,
name: config.general?.name,
unit: config.general?.unit,
// functionality properties
softwareType: config.functionality?.softwareType,
role: config.functionality?.role,
// asset properties (exclude machineCurve)
uuid: config.asset?.uuid,
geoLocation: config.asset?.geoLocation,
supplier: config.asset?.supplier,
type: config.asset?.type,
subType: config.asset?.subType,
model: config.asset?.model,
};
}
processFormat(changedFields,config) {
// Create the measurement and topic using softwareType and name config.functionality.softwareType + .
const measurement = config.general.name;
const payload = changedFields;
const topic = measurement;
const msg = { topic: topic, payload: payload };
return msg;
}
}
module.exports = OutputUtils;