Compare commits

..

1 commit

Author SHA1 Message Date
rasta5man
aa93a2a5c3 Initial commit - ip75 2025-08-14 22:48:26 +02:00
2 changed files with 193 additions and 130 deletions

View file

@ -1,2 +1,2 @@
rvo_name:string|lang:string|mqtt_host:string|mqtt_clientid:string|mqtt_username:string|mqtt_port:number|maintanace_mode:boolean|projects_id:number|controller_type:string|backup_on_failure:boolean|restore_from_backup:number|restore_backup_wait:number
+|Grafia 10.0.0.74|en||10_0_0_74_grafia||1883|0|29|unipi|1|30|50|...........................................
+|Grafia 10.0.0.75|en||10_0_0_75_grafia||1883|0|30|unipi|1|10|50|...........................................

View file

@ -7,48 +7,14 @@ exports.output = ["red", "white", "yellow"];
exports.click = false;
exports.author = 'Rastislav Kovac';
exports.icon = 'bolt';
exports.readme = `Modbus requests to energomonitor socomec suitcase`;
const streamBuilder = require("./helper/energo_streambuilder");
const structure = {
"192.168.1.11": {
51: "i-35", // nový merák I-35, bez zóny
16: "i-35", // zmena adresy z 1 na 16 - 13.5.2022
"6A": "i-60A",
"6B": "i-60B",
"7A": "i-60A",
"7B": "i-60B",
"8A": "i-60A",
"8B": "i-60B",
9: "i-30",
"10A": "i-60A",
"10B": "i-60B",
"11A": "i-60A",
"11B": "i-60B",
"12A": "i-60A",
"12B": "i-60B",
"13A": "i-60A",
"13B": "i-60B",
"14A": "i-60A",
"14B": "i-60B",
"15A": "i-60A",
"15B": "i-60B",
5: "i-30",
"2A": "i-60A",
"2B": "i-60B",
"3A": "i-60A",
"3B": "i-60B",
"4A": "i-60A",
"4B": "i-60B",
//novo nainstalovane 28.10.2024
"21A": "i-60A",
"21B": "i-60B"
// "36B": "i-60B" // vymyslene kvoli chybe
},
"192.168.1.12": {
18: "i-35",
"192.168.1.21": {
16: "i-35",
"2A": "i-60A",
"2B": "i-60B",
"3A": "i-60A",
@ -75,18 +41,29 @@ const structure = {
"13B": "i-60B",
"14A": "i-60A",
"14B": "i-60B",
"15A": "i-60A",
"15B": "i-60B",
"16A": "i-60A",
"16B": "i-60B",
"17A": "i-60A",
"17B": "i-60B"
},
"192.168.1.22": {
10: "i-35",
"2A": "i-60A",
"2B": "i-60B",
"3A": "i-60A",
"3B": "i-60B",
"4A": "i-60A",
"4B": "i-60B",
"5A": "i-60A",
"5B": "i-60B",
"6A": "i-60A",
"6B": "i-60B",
"7A": "i-60A",
"7B": "i-60B",
"8A": "i-60A",
"8B": "i-60B",
"9A": "i-60A",
"9B": "i-60B"
}
};
exports.install = function(instance) {
const modbus = require('jsmodbus');
@ -94,8 +71,7 @@ exports.install = function(instance) {
require('events').EventEmitter.defaultMaxListeners = 20;
const allModulesEnergy = {unipi_74: ""}; // key to identify source data
const allModulesEnergy = {unipi_75: ""}; // key to identify source data
const date = new Date();
let hour = date.getHours();
@ -116,98 +92,78 @@ exports.install = function(instance) {
const conversionTable = streamBuilder.makeStreamsTable(structure);
// const conversionTable =
// {
// "192.168.1.11": {
// "192.168.1.21": {
// "streams": [
// {
// "unitId": 1,
// "section": "",
// "name": 18488,
// "tb_value":"phase_1_power",
// "tb_value":"total_energy",
// "bytes": 2,
// "multiplier":1,
// "previousEnergy": null,
// "month": 2
// },
// ]
// }
// }
const tbNames = {
"192.168.1.11": {
"51": "1JMYvnx2RzKEo4aWQ7D93vAL8yZV3m9NBePXbrdj", // nový merák I-35, bez zóny
"16": "6lQGaY9RDywdVzObj0PZer7Pg4NBn3exEK51LWZq", // zmena adresy z 1 na 16, 13.5.2022
"6A": "JzwxZXOvDj1bVrN4nkWeR8A8qdyBl3MRKLpGPgaQ",
"6B": "g9OxBZ5KRwNznlY6pApbGmkWXvjdEL4eGQobMDy2",
"7A": "OzNMgZ9n43qPbjXmy7zOgGA2DKdYvW5e6pxGRrVa",
"7B": "JX1ObgmqGZ54DMyYL7aJzJAEVdve38WKRzwjNrQ9",
"8A": "RvmwNz8QPblKp41GD7l4WK7JrLVYoBO92dMegn6W",
"8B": "RO8rjaBDy21qPQJzW7oKpD7pK3xmNleVZg9Ed4Gw",
"9": "3JjOWdylwgNLzxVab7NPjw0Z2vG64rq8PEB5QmDo",
"10A": "Z5KyJe9nEg1QNbWlX0wmnM7oDjBLdqzR83VGv624",
"10B": "1JMYvnx2RzKEo4aWQ7D9xzAL8yZV3m9NBePXbrdj",
"11A": "PjLblDgRBO6WQqnxmkJwga7Jv3ewZN4p5a89yKdY",
"11B": "dz4ojlpP85JMgDLZWkQ12jkaKYqQexEr62GXRV1y",
"12A": "d5xjWYMwEJon6rLlK7yl3wkqgV4DaOeNB9ZX3Gzb",
"12B": "gRoJEyXVx4qD9er287LwbOkwBzGldaPjLWQKm3Mv",
"13A": "K94XLav1glVRnyQ6r01V3Wkme3YJwBxM5oOzdP2j",
"13B": "d9x2V5LGYBzXp4mMRAOPr10PloaqJwnQj6DgrNe3",
"14A": "B5EoxeMVp4zwr8nqW0Gen57RjvD1PNamOGbLg63Z",
"14B": "aw4eELG2DlPMdn1JW0Bz4Z0qQXOZRN3xB5yp8VKr",
"15A": "ZmRwd93QL4gaezxEbAx1Xw01prn2XjlPvGyqJ6BO",
"15B": "eod9aRWLVl34Gx1Dn7VYmDk2rz6qjgmpEXwQJN5Z",
"5": "3a5oqJN1bgnx4Ol9dk8BdqAByE6jQ8mKDWMpGrLV",
"2A": "EjgWGnXaLy9opPOz20ngWQk86BlYM3w1deVQvbKr",
"2B": "wvKJdZML6mXP4DzWBAXOK87jxNloa5g23Ve9Y1ry",
"3A": "Nzp2OoJlqn6r1ZgvdA3RqE7abBwP5G4eE3RQmyxD",
"3B": "PLBJzmK1r3Gynd6OW0g2WzAe5wV4vx9bDEqNgYR8",
"4A": "52dD6ZlV1QaOpRBmbAqvWb0KnGzWMLj4eJq38Pgo",
"4B": "rDbQ84xzwgdqEoPm3kbPWWA9anOZY1RXyBv2LVM6",
"21A": "1558",
"21B": "1559"
// "36B": "vymyslene kvoli chybe"
},
"192.168.1.12": {
"18": "m6EYyZoJ4gWexdjVPARapL7RDOq9wv2N5XzKGplr",
"2A": "E6Kg9oDnLWyzPRMva7vW8yAJxp4VG58qO2w1lZYe",
"2B": "roKgWqY95V3mXMRzyAjrW6AbLjexpJPvaGDBw826",
"3A": "nJL5lPMwBx23YpqRe0rqa4AdamXvWVbOrD4gNzy8",
"3B": "XMBbew5z4ELrZa2mRAdZW9k8vPN6gy3DdVYlpKjq",
"4A": "gYbDLqlyZVoRerQpB72GgvAWJnwM5z24POKa8Exj",
"4B": "zdQO8GwxDqjRgP4137Y5eo7NyKlpem2nL65rvVJY",
"5A": "5dBNwRp9graYJxZn409R28klVov1b2QLPDqGm6XK",
"5B": "JzwxZXOvDj1bVrN4nkWeZ8A8qdyBl3MRKLpGPgaQ",
"6A": "zrR51V2ajQ9ZLygPKkEPVW0YDq38xOJolENBXGnv",
"6B": "g9OxBZ5KRwNznlY6pApbymkWXvjdEL4eGQobMDy2",
"7A": "OzNMgZ9n43qPbjXmy7zOyGA2DKdYvW5e6pxGRrVa",
"7B": "JX1ObgmqGZ54DMyYL7aJZJAEVdve38WKRzwjNrQ9",
"8A": "RvmwNz8QPblKp41GD7l4yK7JrLVYoBO92dMegn6W",
"8B": "RO8rjaBDy21qPQJzW7oKyD7pK3xmNleVZg9Ed4Gw",
"9A": "3JjOWdylwgNLzxVab7NPxw0Z2vG64rq8PEB5QmDo",
"9B": "Z5KyJe9nEg1QNbWlX0wmyM7oDjBLdqzR83VGv624",
"10A": "1JMYvnx2RzKEo4aWQ7D9MzAL8yZV3m9NBePXbrdj",
"10B": "PjLblDgRBO6WQqnxmkJwea7Jv3ewZN4p5a89yKdY",
"11A": "WlVJBygjDZMeKX3vnAMWvLk8NqdmG2x1Y69LQ4P5",
"11B": "dz4ojlpP85JMgDLZWkQ1njkaKYqQexEr62GXRV1y",
"12A": "BaY3Xpy1EbKGjLq2O7m9W27rx8owgQz9P4dDJRmN",
"12B": "DbQY6zyveZRwK5drV0Zl4j7joE4XJM83N9xl2nWq",
"13A": "apKVJBwOyrP35m2lv7KEqd0YXbeWNd64En9GxRqg",
"13B": "o9vbeQlLMVg8j5dq4kedWy0NxZpEmnXzwYKO1ar2",
"14A": "gP1eOZVj3Q9lv5aDEk4MbP7rdpqW8yLm2BbKzJxM",
"14B": "2O14VBzl8aDmWdNw3A53vOkGyZ5qLJoEMpj6R9ng",
"15A": "pE5X8NQPaow6vlOZxk6Yjw0q42ezGBMyWgDVjR3L",
"15B": "d5xjWYMwEJon6rLlK7ylywkqgV4DaOeNB9ZX3Gzb",
"16A": "6lQGaY9RDywdVzObj0PZdr7Pg4NBn3exEK51LWZq",
"16B": "m6EYyZoJ4gWexdjVPARaYL7RDOq9wv2N5XzKGplr",
"17A": "gRoJEyXVx4qD9er287LwBOkwBzGldaPjLWQKm3Mv",
"17B": "K94XLav1glVRnyQ6r01VpWkme3YJwBxM5oOzdP2j"
"192.168.1.21": {
"16": "aw4eELG2DlPMdn1JW0Bz2Z0qQXOZRN3xB5yp8VKr",
"2A": "d9x2V5LGYBzXp4mMRAOPV10PloaqJwnQj6DgrNe3",
"2B": "eod9aRWLVl34Gx1Dn7VYbDk2rz6qjgmpEXwQJN5Z",
"3A": "3a5oqJN1bgnx4Ol9dk8BnqAByE6jQ8mKDWMpGrLV",
"3B": "EjgWGnXaLy9opPOz20ngyQk86BlYM3w1deVQvbKr",
"4A": "rDbQ84xzwgdqEoPm3kbPKDA9anOZY1RXyBv2LVM6",
"4B": "wvKJdZML6mXP4DzWBAXOj87jxNloa5g23Ve9Y1ry",
"5A": "E6Kg9oDnLWyzPRMva7vWy9AJxp4VG58qO2w1lZYe",
"5B": "roKgWqY95V3mXMRzyAjrynAbLjexpJPvaGDBw826",
"6A": "Nzp2OoJlqn6r1ZgvdA3RoE7abBwP5G4eE3RQmyxD",
"6B": "rDbQ84xzwgdqEoPm3kbPKWA9anOZY1RXyBv2LVM6",
"7A": "E6Kg9oDnLWyzPRMva7vWyyAJxp4VG58qO2w1lZYe",
"7B": "roKgWqY95V3mXMRzyAjry6AbLjexpJPvaGDBw826",
"8A": "nJL5lPMwBx23YpqRe0rqy4AdamXvWVbOrD4gNzy8",
"8B": "ZmRwd93QL4gaezxEbAx1yb01prn2XjlPvGyqJ6BO",
"9A": "eod9aRWLVl34Gx1Dn7VYb9k2rz6qjgmpEXwQJN5Z",
"9B": "Nzp2OoJlqn6r1ZgvdA3Rov7abBwP5G4eE3RQmyxD",
"10A": "3a5oqJN1bgnx4Ol9dk8Bn1AByE6jQ8mKDWMpGrLV",
"10B": "EjgWGnXaLy9opPOz20ngydk86BlYM3w1deVQvbKr",
"11A": "PLBJzmK1r3Gynd6OW0g2yqAe5wV4vx9bDEqNgYR8",
"11B": "wvKJdZML6mXP4DzWBAXOjV7jxNloa5g23Ve9Y1ry",
"12A": "nJL5lPMwBx23YpqRe0rqybAdamXvWVbOrD4gNzy8",
"12B": "52dD6ZlV1QaOpRBmbAqvyN0KnGzWMLj4eJq38Pgo",
"13A": "XMBbew5z4ELrZa2mRAdZ4xk8vPN6gy3DdVYlpKjq",
"13B": "PLBJzmK1r3Gynd6OW0g2yzAe5wV4vx9bDEqNgYR8",
"14A": "52dD6ZlV1QaOpRBmbAqvyb0KnGzWMLj4eJq38Pgo",
"14B": "gYbDLqlyZVoRerQpB72Gp4AWJnwM5z24POKa8Exj",
},
"192.168.1.22": {
"10": "ZmRwd93QL4gaezxEbAx1yw01prn2XjlPvGyqJ6BO",
"2A": "B5EoxeMVp4zwr8nqW0GeGG7RjvD1PNamOGbLg63Z",
"2B": "WlVJBygjDZMeKX3vnAMW6Pk8NqdmG2x1Y69LQ4P5",
"3A": "zrR51V2ajQ9ZLygPKkEPz10YDq38xOJolENBXGnv",
"3B": "BaY3Xpy1EbKGjLq2O7m9N97rx8owgQz9P4dDJRmN",
"4A": "JzwxZXOvDj1bVrN4nkWe3zA8qdyBl3MRKLpGPgaQ",
"4B": "o9vbeQlLMVg8j5dq4kedZK0NxZpEmnXzwYKO1ar2",
"5A": "gP1eOZVj3Q9lv5aDEk4M4a7rdpqW8yLm2BbKzJxM",
"5B": "5dBNwRp9graYJxZn409RBvklVov1b2QLPDqGm6XK",
"6A": "g9OxBZ5KRwNznlY6pApbNOkWXvjdEL4eGQobMDy2",
"6B": "pE5X8NQPaow6vlOZxk6Y6z0q42ezGBMyWgDVjR3L",
"7A": "2O14VBzl8aDmWdNw3A535GkGyZ5qLJoEMpj6R9ng",
"7B": "DbQY6zyveZRwK5drV0ZlB87joE4XJM83N9xl2nWq",
"8A": "6lQGaY9RDywdVzObj0PZpb7Pg4NBn3exEK51LWZq",
"8B": "m6EYyZoJ4gWexdjVPARaxV7RDOq9wv2N5XzKGplr",
"9A": "apKVJBwOyrP35m2lv7KEpz0YXbeWNd64En9GxRqg",
"9B": "OzNMgZ9n43qPbjXmy7zONeA2DKdYvW5e6pxGRrVa"
}
};
const meter51 = ["total_energy","phase_1_power","phase_2_power","phase_3_power","phase_1_voltage","phase_2_voltage",
"phase_3_voltage","phase_1_react_power","phase_2_react_power","phase_3_react_power","phase_1_apparent_power",
"phase_2_apparent_power","phase_3_apparent_power","total_active_power","total_reactive_power","total_apparent_power"];
// static class attribute ???
const valuesToRecount = ['total_energy', 'phase_1_current', 'phase_2_current', 'phase_3_current', 'neutral_wire_current', 'total_active_power', 'total_reactive_power', 'total_apparent_power'];
class SocketWithClients {
@ -222,10 +178,23 @@ exports.install = function(instance) {
}
this.streams = data.streams; //pole
// distribute ==> we are sending attributes from 'valuesToRecount' with value divided by 2 to these 4 tbNames. To ensure, we send 'energy_last_month' and 'energy_update' attribute as well, we must store 'month' key and previousEnergy
// can be static class attribute ??
this.distribute = {
"6lQGaY9RDywdVzObj0PZpb7Pg4NBn3exEK51LWZq": {month: this.getCurrentMonth(), previousEnergy: null, tbNames: ["nJL5lPMwBx23YpqRe0rq4bAdamXvWVbOrD4gNzy8", "ZmRwd93QL4gaezxEbAx1oK01prn2XjlPvGyqJ6BO"]},
"PLBJzmK1r3Gynd6OW0g2yqAe5wV4vx9bDEqNgYR8": {month: this.getCurrentMonth(), previousEnergy: null, tbNames: ["E6Kg9oDnLWyzPRMva7vWR9AJxp4VG58qO2w1lZYe","roKgWqY95V3mXMRzyAjrYnAbLjexpJPvaGDBw826"]}
}
this.startSocket();
}
getCurrentMonth = () => {
const date = new Date();
return date.getMonth();
};
startSocket = () => {
let obj = this;
@ -398,16 +367,13 @@ exports.install = function(instance) {
if(tbName == undefined) return;
// we handle multimeter 51 values: - if voltage or power, we multiply with 55
if(tbName == '1JMYvnx2RzKEo4aWQ7D93vAL8yZV3m9NBePXbrdj' && meter51.includes(tb_value)) value = parseFloat((value * 55).toFixed(2));
const values = {
"status": "OK",
[tb_value]: value
};
// we send "energy_last_month" value, that is equal to "total_energy" value, on first day and first minute of new month ==> it means when month has changed
// we send "energy_last_month" value, that is equal to "total_energy" value, on first day of new month ==> it means when month changes
if(tb_value == "total_energy")
{
const previousEnergy = a.previousEnergy;
@ -417,7 +383,7 @@ exports.install = function(instance) {
{
values["energy_update"] = value - previousEnergy;
}
const d = new Date(date);
const currentMonth = d.getMonth();
const month = a.month;
@ -429,6 +395,12 @@ exports.install = function(instance) {
}
allModulesEnergy[this.ip + '@' + unitId + section] = value;
if(this.ip + '@' + unitId + section == "192.168.1.22@8A")
{
allModulesEnergy[this.ip + '@' + unitId + section + '_48'] = value / 2;
allModulesEnergy[this.ip + '@' + unitId + section + '_64'] = value / 2;
}
}
@ -442,14 +414,105 @@ exports.install = function(instance) {
};
instance.send(1, dataToTB);
// new code - ensures, we send values to another 4 devices, and "energy_last_month" value at the start of new month.
if(this.distribute.hasOwnProperty(tbName))
{
if(valuesToRecount.includes(tb_value))
{
value = value/2;
const values = {
"status": "OK",
[tb_value]: value
};
if(tb_value == "total_energy")
{
const previousEnergy = this.distribute[tbName].previousEnergy;
this.distribute[tbName].previousEnergy = value;
if(previousEnergy != null)
{
values["energy_update"] = value - previousEnergy;
}
let d = new Date(date);
let month = d.getMonth();
if(month != this.distribute[tbName].month)
{
values["energy_last_month"] = value;
this.distribute[tbName].month = month;
}
}
this.distribute[tbName].tbNames.map(sendTo => {
dataToTB = {
[sendTo]: [
{
"ts": date,
"values": values
}
]
};
instance.send(1, dataToTB);
})
}
}
break;
}
}
};
}
const newSocket = new SocketWithClients("192.168.1.11", conversionTable["192.168.1.11"]);
const newSocket2 = new SocketWithClients("192.168.1.12", conversionTable["192.168.1.12"]);
const newSocket = new SocketWithClients("192.168.1.21", conversionTable["192.168.1.21"]);
const newSocket2 = new SocketWithClients("192.168.1.22", conversionTable["192.168.1.22"]);
}
//! VYPOCTY "energy_last_month_delta" pre virtualne devices za februar 2022 - zmazat neskor
// "192.168.1.22@8A":{"value":76772,"zone":"lithoman_48_64","tbname":"6lQGaY9RDywdVzObj0PZpb7Pg4NBn3exEK51LWZq"}
// "192.168.1.22@8A":{"value":50857,"zone":"lithoman_48_64","tbname":"6lQGaY9RDywdVzObj0PZpb7Pg4NBn3exEK51LWZq"}
// "energy_last_month_delta" = 25915
// --------
// { "nJL5lPMwBx23YpqRe0rq4bAdamXvWVbOrD4gNzy8": [ { "ts": 1643673891157, "values": { "energy_last_month_delta": 12958 } } ] }
// "nJL5lPMwBx23YpqRe0rq4bAdamXvWVbOrD4gNzy8", "ZmRwd93QL4gaezxEbAx1oK01prn2XjlPvGyqJ6BO"
// "192.168.1.22@8A_48":{"value":38386,"zone":"lithoman_48"},"192.168.1.22@8A_64":{"value":38386,"zone":"lithoman_64"}
// "192.168.1.22@8A_48":{"value":25428,"zone":"lithoman_48"},"192.168.1.22@8A_64":{"value":25428,"zone":"lithoman_64"}
// --------
// "192.168.1.21@11A":{"value":11830,"zone":"sitma_cmc","tbname":"PLBJzmK1r3Gynd6OW0g2yqAe5wV4vx9bDEqNgYR8"}
// "192.168.1.21@11A":{"value":7530,"zone":"sitma_cmc","tbname":"PLBJzmK1r3Gynd6OW0g2yqAe5wV4vx9bDEqNgYR8"}
// "energy_last_month_delta" = 4300
// -------
// 5915
// 3765
// = 2150
// this.distribute = {
// "6lQGaY9RDywdVzObj0PZpb7Pg4NBn3exEK51LWZq": {month: this.getCurrentMonth(), previousEnergy: null, tbNames: ["nJL5lPMwBx23YpqRe0rq4bAdamXvWVbOrD4gNzy8", "ZmRwd93QL4gaezxEbAx1oK01prn2XjlPvGyqJ6BO"]},
// "PLBJzmK1r3Gynd6OW0g2yqAe5wV4vx9bDEqNgYR8": {month: this.getCurrentMonth(), previousEnergy: null, tbNames: ["E6Kg9oDnLWyzPRMva7vWR9AJxp4VG58qO2w1lZYe","roKgWqY95V3mXMRzyAjrYnAbLjexpJPvaGDBw826"]}
// }
// { "E6Kg9oDnLWyzPRMva7vWR9AJxp4VG58qO2w1lZYe": [ { "ts": 1643673891157, "values": { "energy_last_month_delta": 2150 } } ] }