node-red-contrib-energymeterplus 0.3.3 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/energyMeterPlus.js +42 -14
- package/package.json +1 -1
package/energyMeterPlus.js
CHANGED
|
@@ -11,13 +11,41 @@ module.exports = function(RED) {
|
|
|
11
11
|
let inputUnit = config.inputUnit || "W";
|
|
12
12
|
let currencyCode = config.currency || "USD";
|
|
13
13
|
|
|
14
|
-
//
|
|
14
|
+
// --- Editor-config delta apply (run on every deploy)
|
|
15
|
+
function toNum(v) { const n = Number(v); return isNaN(n) ? 0 : n; }
|
|
16
|
+
|
|
17
|
+
// read stored "last applied editor values" (so we can compute deltas)
|
|
18
|
+
let lastApplied = node.context().get("lastAppliedEditor") || { daily:0, weekly:0, monthly:0, yearly:0 };
|
|
19
|
+
|
|
20
|
+
// current editor values (always read from config)
|
|
21
|
+
let editor = {
|
|
22
|
+
daily: toNum(config.baselineDaily),
|
|
23
|
+
weekly: toNum(config.baselineWeekly),
|
|
24
|
+
monthly: toNum(config.baselineMonthly),
|
|
25
|
+
yearly: toNum(config.baselineYearly)
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// compute delta = editor - lastApplied
|
|
29
|
+
let delta = {
|
|
30
|
+
daily: editor.daily - (toNum(lastApplied.daily) || 0),
|
|
31
|
+
weekly: editor.weekly - (toNum(lastApplied.weekly) || 0),
|
|
32
|
+
monthly: editor.monthly - (toNum(lastApplied.monthly) || 0),
|
|
33
|
+
yearly: editor.yearly - (toNum(lastApplied.yearly) || 0)
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// ensure baseline exists
|
|
15
37
|
let baseline = node.context().get("baseline") || { daily:0, weekly:0, monthly:0, yearly:0 };
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
baseline.
|
|
19
|
-
baseline.
|
|
38
|
+
|
|
39
|
+
// apply delta (this adds positive or negative changes)
|
|
40
|
+
baseline.daily += delta.daily;
|
|
41
|
+
baseline.weekly += delta.weekly;
|
|
42
|
+
baseline.monthly += delta.monthly;
|
|
43
|
+
baseline.yearly += delta.yearly;
|
|
44
|
+
|
|
45
|
+
// persist baseline and remember the editor values we just applied
|
|
20
46
|
node.context().set("baseline", baseline);
|
|
47
|
+
node.context().set("lastAppliedEditor", editor);
|
|
48
|
+
// -------------------------------------------------------------------------------
|
|
21
49
|
|
|
22
50
|
// Accumulated values
|
|
23
51
|
let accumulated = node.context().get("accumulated") || { daily:0, weekly:0, monthly:0, yearly:0 };
|
|
@@ -29,11 +57,11 @@ module.exports = function(RED) {
|
|
|
29
57
|
}
|
|
30
58
|
|
|
31
59
|
// 1. Input handler: baseline updates + power increments
|
|
32
|
-
|
|
60
|
+
node.on('input', function(msg) {
|
|
33
61
|
let now = new Date();
|
|
34
62
|
let durationHours = (now - lastCheck) / (1000 * 3600);
|
|
35
63
|
|
|
36
|
-
// Handle baseline updates via message
|
|
64
|
+
// Handle baseline updates via message (runtime applyBaseline)
|
|
37
65
|
if (msg.topic === "applyBaseline" && msg.payload) {
|
|
38
66
|
baseline.daily += Number(msg.payload.daily) || 0;
|
|
39
67
|
baseline.weekly += Number(msg.payload.weekly) || 0;
|
|
@@ -42,7 +70,7 @@ module.exports = function(RED) {
|
|
|
42
70
|
node.context().set("baseline", baseline);
|
|
43
71
|
}
|
|
44
72
|
|
|
45
|
-
|
|
73
|
+
// Handle power input
|
|
46
74
|
let power = Number(msg.payload);
|
|
47
75
|
if (!isNaN(power) && durationHours > 0) {
|
|
48
76
|
let power_kW = (inputUnit === "W") ? power / 1000 : power;
|
|
@@ -58,7 +86,7 @@ module.exports = function(RED) {
|
|
|
58
86
|
node.context().set("lastCheck", lastCheck);
|
|
59
87
|
node.context().set("accumulated", accumulated);
|
|
60
88
|
|
|
61
|
-
|
|
89
|
+
// 3. Output payload
|
|
62
90
|
msg.payload = {
|
|
63
91
|
energyDaily: round2(baseline.daily + accumulated.daily),
|
|
64
92
|
energyWeekly: round2(baseline.weekly + accumulated.weekly),
|
|
@@ -71,7 +99,7 @@ module.exports = function(RED) {
|
|
|
71
99
|
currency: currencySymbol(currencyCode)
|
|
72
100
|
};
|
|
73
101
|
|
|
74
|
-
|
|
102
|
+
// 4. Persist to file
|
|
75
103
|
const dir = path.dirname(filePath);
|
|
76
104
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
77
105
|
try { fs.writeFileSync(filePath, JSON.stringify(msg.payload, null, 2)); }
|
|
@@ -81,7 +109,7 @@ module.exports = function(RED) {
|
|
|
81
109
|
});
|
|
82
110
|
|
|
83
111
|
// 5. Rollover logic
|
|
84
|
-
|
|
112
|
+
function checkRollover() {
|
|
85
113
|
let now = new Date();
|
|
86
114
|
|
|
87
115
|
if (!(lastCheck instanceof Date)) {
|
|
@@ -106,11 +134,11 @@ module.exports = function(RED) {
|
|
|
106
134
|
node.context().set("lastCheck", lastCheck);
|
|
107
135
|
node.context().set("accumulated", accumulated);
|
|
108
136
|
node.context().set("baseline", baseline);
|
|
109
|
-
|
|
110
|
-
|
|
137
|
+
}
|
|
138
|
+
setInterval(checkRollover, 60000);
|
|
111
139
|
|
|
112
140
|
// 6. Helpers
|
|
113
|
-
|
|
141
|
+
function currencySymbol(code) {
|
|
114
142
|
switch (code) {
|
|
115
143
|
case "USD": return "$";
|
|
116
144
|
case "EUR": return "€";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-energymeterplus",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "A custom Node-RED node that integrates power readings into energy totals with persistence and cost calculation.",
|
|
5
5
|
"author": "Arcfrankye",
|
|
6
6
|
"license": "MIT",
|