Initial commit - testing version

This commit is contained in:
rasta5man 2025-08-08 16:53:33 +02:00
parent cf16481324
commit 06b289d7a3
11 changed files with 6636 additions and 3819 deletions

View file

@ -1,186 +1,186 @@
class DataToTbHandler {
constructor(index) {
this.index = index;
constructor(index) {
this.index = index;
// time, after new value for the given key will be resend to tb (e.g. {status: "OK"})
this.timeToHoldTbValue = 30 * 60; //30 minutes
this.previousValues = {};
this.debug = false;
this.messageCounter = 0;
this.itIsNodeReadout = false;
this.sender = "";
// time, after new value for the given key will be resend to tb (e.g. {status: "OK"})
this.timeToHoldTbValue = 30 * 60; //30 minutes
this.previousValues = {};
this.debug = false;
this.messageCounter = 0;
this.itIsNodeReadout = false;
this.sender = "";
// if attribute change difference is less than limit value, we do not send to tb.
this.attributeChangeLimit = {
temperature: 0.5,
Phase_1_voltage: 2,
Phase_2_voltage: 2,
Phase_3_voltage: 2,
Phase_1_current: 0.1,
Phase_2_current: 0.1,
Phase_3_current: 0.1,
Phase_1_power: 2,
Phase_2_power: 2,
Phase_3_power: 2,
total_power: 2,
total_energy: 1,
Phase_1_pow_factor: 0.1,
Phase_2_pow_factor: 0.1,
Phase_3_pow_factor: 0.1,
power_factor: 0.1,
lifetime: 2,
voltage: 2,
power: 2,
frequency: 3,
energy: 0.1,
current: 2,
inclination_x: 10,
inclination_y: 10,
inclination_z: 10
};
// if attribute change difference is less than limit value, we do not send to tb.
this.attributeChangeLimit = {
temperature: 0.5,
Phase_1_voltage: 2,
Phase_2_voltage: 2,
Phase_3_voltage: 2,
Phase_1_current: 0.1,
Phase_2_current: 0.1,
Phase_3_current: 0.1,
Phase_1_power: 2,
Phase_2_power: 2,
Phase_3_power: 2,
total_power: 2,
total_energy: 1,
Phase_1_pow_factor: 0.1,
Phase_2_pow_factor: 0.1,
Phase_3_pow_factor: 0.1,
power_factor: 0.1,
lifetime: 2,
voltage: 2,
power: 2,
frequency: 3,
energy: 0.1,
current: 2,
inclination_x: 10,
inclination_y: 10,
inclination_z: 10
};
}
}
dump() {
console.log("----------------------------");
console.log("previousValues", this.previousValues);
console.log("----------------------------");
}
dump() {
console.log("----------------------------");
console.log("previousValues", this.previousValues);
console.log("----------------------------");
}
setSender(sender) {
this.sender = sender;
}
setSender(sender) {
this.sender = sender;
}
isEmptyObject(obj) {
for (var _ in obj) {
return false;
}
return true;
}
isEmptyObject(obj) {
for (var _ in obj) {
return false;
}
return true;
}
sendToTb(data, instance) {
sendToTb(data, instance) {
//not to modify data object, we do deep copy:
let dataCopy = JSON.parse(JSON.stringify(data));
//not to modify data object, we do deep copy:
let dataCopy = JSON.parse(JSON.stringify(data));
let keys = Object.keys(dataCopy);
let keys = Object.keys(dataCopy);
if (keys.length == 0) {
if (this.debug) console.log("sendToTb received empty object", dataCopy);
return;
}
if (keys.length == 0) {
if (this.debug) console.log("sendToTb received empty object", dataCopy);
return;
}
let tbname = keys[0];
let ts;
let tbname = keys[0];
let ts;
let arrayOfValues = dataCopy[tbname];
let arrayOfValuesToSend = [];
let arrayOfValues = dataCopy[tbname];
let arrayOfValuesToSend = [];
for (let i = 0; i < arrayOfValues.length; i++) {
for (let i = 0; i < arrayOfValues.length; i++) {
ts = arrayOfValues[i].ts;
let values = this.prepareValuesForTb(tbname, ts, arrayOfValues[i].values);
ts = arrayOfValues[i].ts;
let values = this.prepareValuesForTb(tbname, ts, arrayOfValues[i].values);
if (!this.isEmptyObject(values)) {
arrayOfValuesToSend.push({ ts: ts, values: values });
}
if (!this.isEmptyObject(values)) {
arrayOfValuesToSend.push({ ts: ts, values: values });
}
}
}
if (arrayOfValuesToSend.length == 0) {
//if(this.debug) console.log("data not sent - empty array");
return;
}
if (arrayOfValuesToSend.length == 0) {
//if(this.debug) console.log("data not sent - empty array");
return;
}
this.messageCounter++;
this.messageCounter++;
let dataToTbModified = {
[tbname]: arrayOfValuesToSend
}
let dataToTbModified = {
[tbname]: arrayOfValuesToSend
}
//console.log(this.sender + " DATA SEND TO TB ", tbname, this.messageCounter, new Date(ts), dataToTbModified[tbname][0].values, this.instance);
//if(this.debug) console.log(this.sender + " DATA SEND TO TB ", this.index, tbname, arrayOfValuesToSend);
instance.send(this.index, dataToTbModified);
}
//console.log(this.sender + " DATA SEND TO TB ", tbname, this.messageCounter, new Date(ts), dataToTbModified[tbname][0].values, this.instance);
//if(this.debug) console.log(this.sender + " DATA SEND TO TB ", this.index, tbname, arrayOfValuesToSend);
instance.send(this.index, dataToTbModified);
}
getDiffTimestamp(key) {
//TODO set different value for given key!!!
//if(key == "status") this.timeToHoldTbValue = 2*60*60;//2h
return this.timeToHoldTbValue * 1000;
}
getDiffTimestamp(key) {
//TODO set different value for given key!!!
//if(key == "status") this.timeToHoldTbValue = 2*60*60;//2h
return this.timeToHoldTbValue * 1000;
}
prepareValuesForTb(tbname, timestamp, values) {
prepareValuesForTb(tbname, timestamp, values) {
let keys = Object.keys(values);
let keys = Object.keys(values);
if (keys.includes("lifetime")) this.itIsNodeReadout = true;
if (keys.includes("lifetime")) this.itIsNodeReadout = true;
if (!this.previousValues.hasOwnProperty(tbname)) {
this.previousValues[tbname] = {};
}
if (!this.previousValues.hasOwnProperty(tbname)) {
this.previousValues[tbname] = {};
}
//if(this.debug) console.log("prepareValuesForTb", tbname, timestamp, values);
//if(this.debug) console.log("prepareValuesForTb", tbname, timestamp, values);
for (let i = 0; i < keys.length; i++) {
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let value = values[key];
let key = keys[i];
let value = values[key];
if (!this.previousValues[tbname].hasOwnProperty(key)) {
this.previousValues[tbname][key] = { ts: timestamp, value: value };
continue;
}
if (!this.previousValues[tbname].hasOwnProperty(key)) {
this.previousValues[tbname][key] = { ts: timestamp, value: value };
continue;
}
// attributeData ==> {voltage: {ts:333333, value:5}}
let attributeData = this.previousValues[tbname][key];
let attributeToChange = false;
if (key in this.attributeChangeLimit) attributeToChange = true;
let limit = this.attributeChangeLimit[key];
let timestampDiffToRemoveKey;
// attributeData ==> {voltage: {ts:333333, value:5}}
let attributeData = this.previousValues[tbname][key];
let attributeToChange = false;
if (key in this.attributeChangeLimit) attributeToChange = true;
let limit = this.attributeChangeLimit[key];
let timestampDiffToRemoveKey;
//this will ensure "node statecode" will be sent just once an hour
if (this.itIsNodeReadout && key === "statecode") {
attributeData.value = value;
this.itIsNodeReadout = false;
timestampDiffToRemoveKey = 1 * 60 * 60 * 1000; // 1 hour
}
//this will ensure "node statecode" will be sent just once an hour
if (this.itIsNodeReadout && key === "statecode") {
attributeData.value = value;
this.itIsNodeReadout = false;
timestampDiffToRemoveKey = 1 * 60 * 60 * 1000; // 1 hour
}
if (key === "twilight_sensor" && value > 100) {
attributeData.value = value;
}
if (key === "twilight_sensor" && value > 100) {
attributeData.value = value;
}
//if edge, master or node version do not change, send just once a day:
if (["edge_fw_version", "master_node_version", "fw_version"].includes(key)) {
timestampDiffToRemoveKey = 24 * 60 * 60 * 1000;
}
//if edge, master or node version do not change, send just once a day:
if (["edge_fw_version", "master_node_version", "fw_version"].includes(key)) {
timestampDiffToRemoveKey = 24 * 60 * 60 * 1000;
}
if (attributeData.value === value || attributeToChange && Math.abs(attributeData.value - value) < limit) {
if (attributeData.value === value || attributeToChange && Math.abs(attributeData.value - value) < limit) {
let diff = timestamp - attributeData.ts;
if (!timestampDiffToRemoveKey) timestampDiffToRemoveKey = this.getDiffTimestamp(key);
let diff = timestamp - attributeData.ts;
if (!timestampDiffToRemoveKey) timestampDiffToRemoveKey = this.getDiffTimestamp(key);
if (diff > timestampDiffToRemoveKey) {
attributeData.ts = Date.now();
//if(this.debug) console.log(this.sender + ": update ts for key", key, "diff is", diff, "messageCounter", this.messageCounter);
}
else {
delete values[key];
//if(this.debug) console.log(this.sender + ": delete key", key, "diff is", diff, "messageCounter", this.messageCounter, timestampDiffToRemoveKey);
}
}
else {
attributeData.value = value;
attributeData.ts = timestamp;
}
if (diff > timestampDiffToRemoveKey) {
attributeData.ts = Date.now();
//if(this.debug) console.log(this.sender + ": update ts for key", key, "diff is", diff, "messageCounter", this.messageCounter);
}
else {
delete values[key];
//if(this.debug) console.log(this.sender + ": delete key", key, "diff is", diff, "messageCounter", this.messageCounter, timestampDiffToRemoveKey);
}
}
else {
attributeData.value = value;
attributeData.ts = timestamp;
}
}
}
return values;
}
return values;
}
}
module.exports = DataToTbHandler;

View file

@ -1,112 +1,170 @@
function bytesToInt(bytes, numberOfBytes) {
let buffer = [];
if (Array.isArray(bytes)) {
buffer = bytes.slice(0);
if (numberOfBytes != undefined) {
buffer = bytes.slice(bytes.length - numberOfBytes);
}
}
else buffer.push(bytes);
let result = 0;
for (let i = 0; i < buffer.length; i++) {
result = (result << 8) | buffer[i];
}
return result >>> 0; //ensure it's an unsigned 32-bit number
}
function resizeArray(arr, newSize, defaultValue) {
while (newSize > arr.length)
arr.push(defaultValue);
arr.length = newSize;
}
longToByteArray = function(/*long*/long) {
// we want to represent the input as a 8-bytes array
var byteArray = [0, 0, 0, 0, 0, 0, 0, 0];
for (var index = 0; index < byteArray.length; index++) {
var byte = long & 0xff;
byteArray[index] = byte;
long = (long - byte) / 256;
}
return byteArray;
};
function addDays(date, days) {
var result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
/*
sleep(2000).then(() => {
// Do something after the sleep!
});
*/
function sleep(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
function isEmptyObject(obj) {
for (var name in obj) {
return false;
}
return true;
}
function convertUTCDateToLocalDate(date) {
var newDate = new Date(date);
newDate.setMinutes(date.getMinutes() + date.getTimezoneOffset());
return newDate;
}
function addZeroBefore(n) {
return (n < 10 ? '0' : '') + n;
}
var convertBase = function() {
function convertBase(baseFrom, baseTo) {
return function(num) {
return parseInt(num, baseFrom).toString(baseTo);
};
}
// binary to decimal
convertBase.bin2dec = convertBase(2, 10);
// binary to hexadecimal
convertBase.bin2hex = convertBase(2, 16);
// decimal to binary
convertBase.dec2bin = convertBase(10, 2);
// decimal to hexadecimal
convertBase.dec2hex = convertBase(10, 16);
// hexadecimal to binary
convertBase.hex2bin = convertBase(16, 2);
// hexadecimal to decimal
convertBase.hex2dec = convertBase(16, 10);
return convertBase;
}();
module.exports = {
bytesToInt,
longToByteArray,
addDays,
addZeroBefore,
resizeArray,
isEmptyObject,
sleep,
convertUTCDateToLocalDate
}
function bytesToInt_orig(bytes, numberOfBytes) {
let buffer = [];
if (Array.isArray(bytes)) {
buffer = bytes.slice(0);
if (numberOfBytes != undefined) {
buffer = bytes.slice(bytes.length - numberOfBytes);
}
}
else buffer.push(bytes);
//var decimal = (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3];
let l = (buffer.length - 1) * 8;
let decimal = 0;
for (let i = 0; i < buffer.length; i++) {
var s = buffer[i] << l;
if (l < 8) s = buffer[i]
decimal = decimal + s;
l = l - 8;
}
// console.log("decimal utils.js: ", decimal);
let decimal1 = 0n;
for (let i = 0; i < buffer.length; i++) {
decimal1 += BigInt(buffer[i]) * (2n ** BigInt((buffer.length - 1 - i) * 8));
}
// console.log("decimal biging utils.js: ", decimal1);
return decimal;
}
//bytestouintBE
function bytesToInt(bytes, numberOfBytes) {
let buffer = [];
if (Array.isArray(bytes)) {
buffer = bytes.slice(0);
if (numberOfBytes != undefined) {
buffer = bytes.slice(bytes.length - numberOfBytes);
}
}
else buffer.push(bytes);
console.log(bytes, buffer);
let result = 0;
for (let i = 0; i < buffer.length; i++) {
result = (result << 8) | bytes[i];
}
// console.log("decimal biging utils.js: ", decimal1);
console.log("originall: ", bytesToInt_orig(buffer));
console.log("uint little endian: ", bytesToUintLE(buffer));
console.log('neww: ', result >>> 0);
return result >>> 0;
}
function bytesToUintLE(bytes, numberOfBytes) {
let buffer = [];
if (Array.isArray(bytes)) {
buffer = bytes.slice(0);
if (numberOfBytes != undefined) {
buffer = bytes.slice(bytes.length - numberOfBytes);
}
}
else buffer.push(bytes);
//var decimal = (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3];
let result = 0;
for (let i = buffer.length - 1; i <= 0; i--) {
result = (result << 8) | bytes[i];
}
return result >>> 0;
}
function resizeArray(arr, newSize, defaultValue) {
while (newSize > arr.length)
arr.push(defaultValue);
arr.length = newSize;
}
longToByteArray = function(/*long*/long) {
// we want to represent the input as a 8-bytes array
var byteArray = [0, 0, 0, 0, 0, 0, 0, 0];
for (var index = 0; index < byteArray.length; index++) {
var byte = long & 0xff;
byteArray[index] = byte;
long = (long - byte) / 256;
}
return byteArray;
};
function addDays(date, days) {
var result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
/*
sleep(2000).then(() => {
// Do something after the sleep!
});
*/
function sleep(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
function isEmptyObject(obj) {
for (var name in obj) {
return false;
}
return true;
}
function convertUTCDateToLocalDate(date) {
var newDate = new Date(date);
newDate.setMinutes(date.getMinutes() + date.getTimezoneOffset());
return newDate;
}
function addZeroBefore(n) {
return (n < 10 ? '0' : '') + n;
}
var convertBase = function() {
function convertBase(baseFrom, baseTo) {
return function(num) {
return parseInt(num, baseFrom).toString(baseTo);
};
}
// binary to decimal
convertBase.bin2dec = convertBase(2, 10);
// binary to hexadecimal
convertBase.bin2hex = convertBase(2, 16);
// decimal to binary
convertBase.dec2bin = convertBase(10, 2);
// decimal to hexadecimal
convertBase.dec2hex = convertBase(10, 16);
// hexadecimal to binary
convertBase.hex2bin = convertBase(16, 2);
// hexadecimal to decimal
convertBase.hex2dec = convertBase(16, 10);
return convertBase;
}();
module.exports = {
bytesToInt,
longToByteArray,
addDays,
addZeroBefore,
resizeArray,
isEmptyObject,
sleep,
convertUTCDateToLocalDate
}