node-red-contrib-energymeterplus 0.2.1 → 0.2.3

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- #### **EnergyMeterPlus Node Version 0.2.1**
1
+ #### **EnergyMeterPlus Node Version 0.2.3**
2
2
 
3
3
 
4
4
 
@@ -50,7 +50,7 @@ EnergyMeterPlus is a custom Node‑RED function node designed to convert instant
50
50
 
51
51
 
52
52
 
53
- ###### **Configuration:**
53
+ ##### **Configuration:**
54
54
 
55
55
 
56
56
 
@@ -164,3 +164,25 @@ After 24 hours → \~108.6 kWh added to daily total.
164
164
 
165
165
  Costs scale automatically with your configured unit cost.
166
166
 
167
+
168
+
169
+
170
+
171
+ ##### **Updates 2.3:**
172
+
173
+
174
+
175
+ Cleared bug where baseline values remain visible after applying the values
176
+
177
+
178
+
179
+ Cleared the rollover logic to eliminate double-counting.
180
+
181
+
182
+
183
+ Baselines now applied once and stored in context.
184
+
185
+
186
+
187
+ updated counters to continuous absorption, no transfer at rollover
188
+
@@ -18,6 +18,13 @@
18
18
  icon: "sun.png",
19
19
  label: function() {
20
20
  return this.name || "energyMeterPlus";
21
+ },
22
+ oneditsave: function() {
23
+ // Cosmetic blanking: clear baseline fields in the editor UI after deploy
24
+ $("#node-input-baselineDaily").val("");
25
+ $("#node-input-baselineWeekly").val("");
26
+ $("#node-input-baselineMonthly").val("");
27
+ $("#node-input-baselineYearly").val("");
21
28
  }
22
29
  });
23
30
  </script>
@@ -11,7 +11,7 @@ module.exports = function(RED) {
11
11
  let inputUnit = config.inputUnit || "W";
12
12
  let currencyCode = config.currency || "USD";
13
13
 
14
- // Baseline corrections
14
+ // Baseline corrections (numeric values from config)
15
15
  let baselineDaily = Number(config.baselineDaily) || 0;
16
16
  let baselineWeekly = Number(config.baselineWeekly) || 0;
17
17
  let baselineMonthly = Number(config.baselineMonthly) || 0;
@@ -25,6 +25,14 @@ module.exports = function(RED) {
25
25
  yearly: 0
26
26
  };
27
27
 
28
+ // Store numeric baselines separately so resets don’t pull from blanked config
29
+ let storedBaselines = node.context().get("storedBaselines") || {
30
+ daily: baselineDaily,
31
+ weekly: baselineWeekly,
32
+ monthly: baselineMonthly,
33
+ yearly: baselineYearly
34
+ };
35
+
28
36
  // Apply baselines if new values entered
29
37
  let baselineApplied = node.context().get("baselineApplied") || false;
30
38
  if (!baselineApplied || baselineDaily || baselineWeekly || baselineMonthly || baselineYearly) {
@@ -33,7 +41,15 @@ module.exports = function(RED) {
33
41
  baseline.monthly += baselineMonthly;
34
42
  baseline.yearly += baselineYearly;
35
43
 
44
+ storedBaselines = {
45
+ daily: baselineDaily,
46
+ weekly: baselineWeekly,
47
+ monthly: baselineMonthly,
48
+ yearly: baselineYearly
49
+ };
50
+
36
51
  node.context().set("baselineApplied", true);
52
+ node.context().set("storedBaselines", storedBaselines);
37
53
 
38
54
  // Cosmetic blanking: clear config fields so they show empty in UI
39
55
  config.baselineDaily = "";
@@ -55,46 +71,54 @@ module.exports = function(RED) {
55
71
  }
56
72
  }
57
73
 
74
+ // Safe rounding helper
75
+ function round2(val) {
76
+ if (val === null || val === undefined || isNaN(val)) return 0;
77
+ return Number(val.toFixed(2));
78
+ }
79
+
80
+ // Archive yearly totals
81
+ function archiveYearly(total, year) {
82
+ try {
83
+ const archivePath = path.join(path.dirname(filePath), "yearly_archive.json");
84
+ let archive = [];
85
+ if (fs.existsSync(archivePath)) {
86
+ archive = JSON.parse(fs.readFileSync(archivePath));
87
+ }
88
+ archive.push({
89
+ year: year,
90
+ total_kWh: total,
91
+ timestamp: new Date().toISOString()
92
+ });
93
+ fs.writeFileSync(archivePath, JSON.stringify(archive, null, 2));
94
+ } catch (err) {
95
+ node.error("Failed to archive yearly total: " + err);
96
+ }
97
+ }
98
+
58
99
  // Rollover logic
59
100
  function checkRollover() {
60
101
  let now = new Date();
61
102
 
62
103
  // Daily rollover (midnight)
63
104
  if (now.getDate() !== lastCheck.getDate()) {
64
- baseline.weekly += baseline.daily; // absorb yesterday
65
- baseline.daily = 0;
105
+ baseline.daily = storedBaselines.daily;
66
106
  }
67
107
 
68
108
  // Weekly rollover (Sunday → Monday)
69
109
  if (now.getDay() === 1 && lastCheck.getDay() !== 1) {
70
- baseline.monthly += baseline.weekly; // absorb last week
71
- baseline.weekly = 0;
110
+ baseline.weekly = storedBaselines.weekly;
72
111
  }
73
112
 
74
113
  // Monthly rollover (1st of month)
75
114
  if (now.getMonth() !== lastCheck.getMonth()) {
76
- baseline.yearly += baseline.monthly; // absorb last month
77
- baseline.monthly = 0;
115
+ baseline.monthly = storedBaselines.monthly;
78
116
  }
79
117
 
80
118
  // Yearly rollover (Jan 1)
81
119
  if (now.getFullYear() !== lastCheck.getFullYear()) {
82
- try {
83
- const archivePath = path.join(path.dirname(filePath), "yearly_archive.json");
84
- let archive = [];
85
- if (fs.existsSync(archivePath)) {
86
- archive = JSON.parse(fs.readFileSync(archivePath));
87
- }
88
- archive.push({
89
- year: lastCheck.getFullYear(),
90
- total_kWh: baseline.yearly,
91
- timestamp: new Date().toISOString()
92
- });
93
- fs.writeFileSync(archivePath, JSON.stringify(archive, null, 2));
94
- } catch (err) {
95
- node.error("Failed to archive yearly total: " + err);
96
- }
97
- baseline.yearly = 0;
120
+ archiveYearly(baseline.yearly, lastCheck.getFullYear());
121
+ baseline.yearly = storedBaselines.yearly;
98
122
  }
99
123
 
100
124
  lastCheck = now;
@@ -114,9 +138,13 @@ module.exports = function(RED) {
114
138
 
115
139
  let energyIncrement = power_kW * durationHours;
116
140
 
141
+ // Add increment to daily
117
142
  baseline.daily += energyIncrement;
118
143
 
119
- function round2(val) { return Number(val.toFixed(2)); }
144
+ // Continuous absorption
145
+ baseline.weekly += energyIncrement;
146
+ baseline.monthly += energyIncrement;
147
+ baseline.yearly += energyIncrement;
120
148
 
121
149
  msg.payload = {
122
150
  daily_kWh: round2(baseline.daily),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-energymeterplus",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
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",
@@ -13,4 +13,3 @@
13
13
  }
14
14
  }
15
15
  }
16
-