node-red-contrib-energymeterplus 0.2.3 → 0.2.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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- #### **EnergyMeterPlus Node Version 0.2.3**
1
+ #### **EnergyMeterPlus Node Version 0.2.4**
2
2
 
3
3
 
4
4
 
@@ -168,7 +168,11 @@ Costs scale automatically with your configured unit cost.
168
168
 
169
169
 
170
170
 
171
- ##### **Updates 2.3:**
171
+ ##### **Updates:**
172
+
173
+
174
+
175
+ ###### **V2.3:**
172
176
 
173
177
 
174
178
 
@@ -186,3 +190,19 @@ Baselines now applied once and stored in context.
186
190
 
187
191
  updated counters to continuous absorption, no transfer at rollover
188
192
 
193
+
194
+
195
+ ###### v2.4
196
+
197
+
198
+
199
+ Fixed a bug where the internal counters were not updating incrementally.
200
+
201
+
202
+
203
+ Added payload validation
204
+
205
+
206
+
207
+ Fixed Baselines bug: Baselines captured once, stored in context, and survive after UI clears
208
+
@@ -11,12 +11,6 @@ module.exports = function(RED) {
11
11
  let inputUnit = config.inputUnit || "W";
12
12
  let currencyCode = config.currency || "USD";
13
13
 
14
- // Baseline corrections (numeric values from config)
15
- let baselineDaily = Number(config.baselineDaily) || 0;
16
- let baselineWeekly = Number(config.baselineWeekly) || 0;
17
- let baselineMonthly = Number(config.baselineMonthly) || 0;
18
- let baselineYearly = Number(config.baselineYearly) || 0;
19
-
20
14
  // Load persisted baseline or initialize
21
15
  let baseline = node.context().get("baseline") || {
22
16
  daily: 0,
@@ -25,37 +19,23 @@ module.exports = function(RED) {
25
19
  yearly: 0
26
20
  };
27
21
 
28
- // Store numeric baselines separately so resets don’t pull from blanked config
22
+ // Load stored numeric baselines (persisted separately)
29
23
  let storedBaselines = node.context().get("storedBaselines") || {
30
- daily: baselineDaily,
31
- weekly: baselineWeekly,
32
- monthly: baselineMonthly,
33
- yearly: baselineYearly
24
+ daily: Number(config.baselineDaily) || 0,
25
+ weekly: Number(config.baselineWeekly) || 0,
26
+ monthly: Number(config.baselineMonthly) || 0,
27
+ yearly: Number(config.baselineYearly) || 0
34
28
  };
35
29
 
36
- // Apply baselines if new values entered
37
- let baselineApplied = node.context().get("baselineApplied") || false;
38
- if (!baselineApplied || baselineDaily || baselineWeekly || baselineMonthly || baselineYearly) {
39
- baseline.daily += baselineDaily;
40
- baseline.weekly += baselineWeekly;
41
- baseline.monthly += baselineMonthly;
42
- baseline.yearly += baselineYearly;
43
-
44
- storedBaselines = {
45
- daily: baselineDaily,
46
- weekly: baselineWeekly,
47
- monthly: baselineMonthly,
48
- yearly: baselineYearly
49
- };
30
+ // Apply baselines once if new values entered
31
+ if (config.baselineDaily || config.baselineWeekly || config.baselineMonthly || config.baselineYearly) {
32
+ baseline.daily += storedBaselines.daily;
33
+ baseline.weekly += storedBaselines.weekly;
34
+ baseline.monthly += storedBaselines.monthly;
35
+ baseline.yearly += storedBaselines.yearly;
50
36
 
51
- node.context().set("baselineApplied", true);
37
+ node.context().set("baseline", baseline);
52
38
  node.context().set("storedBaselines", storedBaselines);
53
-
54
- // Cosmetic blanking: clear config fields so they show empty in UI
55
- config.baselineDaily = "";
56
- config.baselineWeekly = "";
57
- config.baselineMonthly = "";
58
- config.baselineYearly = "";
59
39
  }
60
40
 
61
41
  // Load last timestamp or initialize
@@ -100,22 +80,15 @@ module.exports = function(RED) {
100
80
  function checkRollover() {
101
81
  let now = new Date();
102
82
 
103
- // Daily rollover (midnight)
104
83
  if (now.getDate() !== lastCheck.getDate()) {
105
84
  baseline.daily = storedBaselines.daily;
106
85
  }
107
-
108
- // Weekly rollover (Sunday → Monday)
109
86
  if (now.getDay() === 1 && lastCheck.getDay() !== 1) {
110
87
  baseline.weekly = storedBaselines.weekly;
111
88
  }
112
-
113
- // Monthly rollover (1st of month)
114
89
  if (now.getMonth() !== lastCheck.getMonth()) {
115
90
  baseline.monthly = storedBaselines.monthly;
116
91
  }
117
-
118
- // Yearly rollover (Jan 1)
119
92
  if (now.getFullYear() !== lastCheck.getFullYear()) {
120
93
  archiveYearly(baseline.yearly, lastCheck.getFullYear());
121
94
  baseline.yearly = storedBaselines.yearly;
@@ -129,22 +102,25 @@ module.exports = function(RED) {
129
102
 
130
103
  node.on('input', function(msg) {
131
104
  let now = new Date();
132
- let durationHours = (now - lastCheck) / (1000 * 3600);
133
- lastCheck = now;
134
- node.context().set("lastCheck", lastCheck);
135
105
 
136
- let power = Number(msg.payload) || 0;
137
- let power_kW = (inputUnit === "W") ? power / 1000 : power;
106
+ // Calculate duration BEFORE updating lastCheck
107
+ let durationHours = (now - lastCheck) / (1000 * 3600);
138
108
 
139
- let energyIncrement = power_kW * durationHours;
109
+ let power = Number(msg.payload);
110
+ if (!isNaN(power)) {
111
+ let power_kW = (inputUnit === "W") ? power / 1000 : power;
112
+ let energyIncrement = power_kW * durationHours;
140
113
 
141
- // Add increment to daily
142
- baseline.daily += energyIncrement;
114
+ // Apply increment
115
+ baseline.daily += energyIncrement;
116
+ baseline.weekly += energyIncrement;
117
+ baseline.monthly += energyIncrement;
118
+ baseline.yearly += energyIncrement;
119
+ }
143
120
 
144
- // Continuous absorption
145
- baseline.weekly += energyIncrement;
146
- baseline.monthly += energyIncrement;
147
- baseline.yearly += energyIncrement;
121
+ // Update lastCheck AFTER increment
122
+ lastCheck = now;
123
+ node.context().set("lastCheck", lastCheck);
148
124
 
149
125
  msg.payload = {
150
126
  daily_kWh: round2(baseline.daily),
@@ -164,7 +140,6 @@ module.exports = function(RED) {
164
140
  fs.mkdirSync(dir, { recursive: true });
165
141
  }
166
142
 
167
- // Write snapshot safely
168
143
  try {
169
144
  fs.writeFileSync(filePath, JSON.stringify(msg.payload, null, 2));
170
145
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-energymeterplus",
3
- "version": "0.2.3",
3
+ "version": "0.2.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",