node-red-contrib-power-saver 3.0.6 → 3.0.7

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.
@@ -6,9 +6,13 @@ sidebar: "auto"
6
6
 
7
7
  List the most significant changes, starting in version 1.0.9.
8
8
 
9
+ ## 3.0.7
10
+
11
+ - Fix Nord Pool current state node input.
12
+
9
13
  ## 3.0.6
10
14
 
11
- Remove non-existant node from package.json.
15
+ - Remove non-existant node from package.json.
12
16
 
13
17
  ## 3.0.5
14
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-power-saver",
3
- "version": "3.0.6",
3
+ "version": "3.0.7",
4
4
  "description": "A module for Node-RED that you can use to turn on and off a switch based on power prices",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,5 +1,4 @@
1
- const { getEffectiveConfig } = require("./utils");
2
- const { extractPlanForDate } = require("./utils");
1
+ const { extractPlanForDate, getEffectiveConfig, validationFailure } = require("./utils");
3
2
  const { DateTime } = require("luxon");
4
3
 
5
4
  function handleStrategyInput(node, msg, doPlanning) {
@@ -152,11 +151,6 @@ function validateInput(node, msg) {
152
151
  return true;
153
152
  }
154
153
 
155
- function validationFailure(node, message, status = null) {
156
- node.status({ fill: "red", shape: "ring", text: status ?? message });
157
- node.warn(message);
158
- }
159
-
160
154
  module.exports = {
161
155
  handleStrategyInput,
162
156
  };
@@ -8,6 +8,7 @@ const {
8
8
  getStartAtIndex,
9
9
  loadDayData,
10
10
  makeSchedule,
11
+ validationFailure,
11
12
  } = require("./utils");
12
13
  const { convertMsg } = require("./receive-price-functions");
13
14
  const { calculate } = require("./strategy-best-save-functions");
@@ -189,11 +190,6 @@ function makePlan(node, values, startTimes, onOffBefore, firstValueNextDay) {
189
190
  };
190
191
  }
191
192
 
192
- function validationFailure(node, message) {
193
- node.status({ fill: "red", shape: "ring", text: message });
194
- node.warn(message);
195
- }
196
-
197
193
  function validateMsg(node, msg) {
198
194
  if (!msg.payload && !msg.data?.new_state?.attributes) {
199
195
  validationFailure(node, "Payload missing");
@@ -6,9 +6,6 @@ function getPriceData(node, msg) {
6
6
  return node.context().get("lastPriceData");
7
7
  }
8
8
 
9
- if (!validateMsg(node, msg)) {
10
- return null;
11
- }
12
9
  const input = convertMsg(msg);
13
10
  if (!validateInput(node, input)) {
14
11
  return null;
@@ -20,19 +17,6 @@ function getPriceData(node, msg) {
20
17
  return { priceData, source };
21
18
  }
22
19
 
23
- function validateMsg(node, msg) {
24
- if (!msg.payload && !msg.data?.new_state?.attributes) {
25
- validationFailure(node, "Payload missing");
26
- return false;
27
- }
28
- const payload = msg.data?.new_state?.attributes ?? msg.data?.attributes ?? msg.payload;
29
- if (typeof payload !== "object") {
30
- validationFailure(node, "Payload must be an object");
31
- return false;
32
- }
33
- return true;
34
- }
35
-
36
20
  function validateInput(node, input) {
37
21
  ["today", "tomorrow"].forEach((arr) => {
38
22
  if (
@@ -80,9 +64,9 @@ function convertMsg(msg) {
80
64
  value: v.value,
81
65
  start: v.start,
82
66
  }));
83
- } else if (msg.payload?.attributes && msg.payload?.attributes["raw_" + day]) {
67
+ } else if (msg.data?.attributes && msg.data?.attributes["raw_" + day]) {
84
68
  result.source = "Nordpool";
85
- result[day] = msg.payload.attributes["raw_" + day]
69
+ result[day] = msg.data.attributes["raw_" + day]
86
70
  .filter((v) => v.value)
87
71
  .map((v) => ({
88
72
  value: v.value,
package/src/utils.js CHANGED
@@ -175,6 +175,11 @@ function getStartAtIndex(effectiveConfig, priceData, time) {
175
175
  }
176
176
  }
177
177
 
178
+ function validationFailure(node, message, status = null) {
179
+ node.status({ fill: "red", shape: "ring", text: status ?? message });
180
+ node.warn(message);
181
+ }
182
+
178
183
  module.exports = {
179
184
  booleanConfig,
180
185
  countAtEnd,
@@ -191,4 +196,5 @@ module.exports = {
191
196
  makeSchedule,
192
197
  roundPrice,
193
198
  sortedIndex,
199
+ validationFailure,
194
200
  };
@@ -0,0 +1,288 @@
1
+ {
2
+ "_msgid": "584656e8b6b08fc4",
3
+ "payload": "1.523",
4
+ "topic": "",
5
+ "data": {
6
+ "entity_id": "sensor.nordpool_kwh_krsand",
7
+ "state": "1.523",
8
+ "attributes": {
9
+ "current_price": 1.523,
10
+ "average": 2.602,
11
+ "off peak 1": 1.768,
12
+ "off peak 2": 1.633,
13
+ "peak": 3.977,
14
+ "min": 1.523,
15
+ "max": 4.582,
16
+ "unit": "kWh",
17
+ "currency": "NOK",
18
+ "country": "Norway",
19
+ "region": "Kr.sand",
20
+ "low price": true,
21
+ "tomorrow_valid": true,
22
+ "today": [
23
+ 1.633, 1.584, 1.581, 1.583, 1.596, 1.661, 1.746, 2.763, 3.803, 3.921, 3.551, 4.172, 3.683, 3.742, 3.847, 4.315,
24
+ 4.582, 2.202, 2.153, 1.803, 1.722, 1.716, 1.569, 1.523
25
+ ],
26
+ "tomorrow": [
27
+ 1.588, 1.521, 1.492, 1.487, 1.497, 1.514, 1.583, 1.667, 1.729, 1.724, 1.707, 1.703, 1.692, 1.692, 1.692, 1.717,
28
+ 1.72, 1.718, 1.679, 1.661, 1.629, 1.652, 1.612, 1.587
29
+ ],
30
+ "raw_today": [
31
+ {
32
+ "start": "2021-12-14T00:00:00+01:00",
33
+ "end": "2021-12-14T01:00:00+01:00",
34
+ "value": 1.633
35
+ },
36
+ {
37
+ "start": "2021-12-14T01:00:00+01:00",
38
+ "end": "2021-12-14T02:00:00+01:00",
39
+ "value": 1.584
40
+ },
41
+ {
42
+ "start": "2021-12-14T02:00:00+01:00",
43
+ "end": "2021-12-14T03:00:00+01:00",
44
+ "value": 1.581
45
+ },
46
+ {
47
+ "start": "2021-12-14T03:00:00+01:00",
48
+ "end": "2021-12-14T04:00:00+01:00",
49
+ "value": 1.583
50
+ },
51
+ {
52
+ "start": "2021-12-14T04:00:00+01:00",
53
+ "end": "2021-12-14T05:00:00+01:00",
54
+ "value": 1.596
55
+ },
56
+ {
57
+ "start": "2021-12-14T05:00:00+01:00",
58
+ "end": "2021-12-14T06:00:00+01:00",
59
+ "value": 1.661
60
+ },
61
+ {
62
+ "start": "2021-12-14T06:00:00+01:00",
63
+ "end": "2021-12-14T07:00:00+01:00",
64
+ "value": 1.746
65
+ },
66
+ {
67
+ "start": "2021-12-14T07:00:00+01:00",
68
+ "end": "2021-12-14T08:00:00+01:00",
69
+ "value": 2.763
70
+ },
71
+ {
72
+ "start": "2021-12-14T08:00:00+01:00",
73
+ "end": "2021-12-14T09:00:00+01:00",
74
+ "value": 3.803
75
+ },
76
+ {
77
+ "start": "2021-12-14T09:00:00+01:00",
78
+ "end": "2021-12-14T10:00:00+01:00",
79
+ "value": 3.921
80
+ },
81
+ {
82
+ "start": "2021-12-14T10:00:00+01:00",
83
+ "end": "2021-12-14T11:00:00+01:00",
84
+ "value": 3.551
85
+ },
86
+ {
87
+ "start": "2021-12-14T11:00:00+01:00",
88
+ "end": "2021-12-14T12:00:00+01:00",
89
+ "value": 4.172
90
+ },
91
+ {
92
+ "start": "2021-12-14T12:00:00+01:00",
93
+ "end": "2021-12-14T13:00:00+01:00",
94
+ "value": 3.683
95
+ },
96
+ {
97
+ "start": "2021-12-14T13:00:00+01:00",
98
+ "end": "2021-12-14T14:00:00+01:00",
99
+ "value": 3.742
100
+ },
101
+ {
102
+ "start": "2021-12-14T14:00:00+01:00",
103
+ "end": "2021-12-14T15:00:00+01:00",
104
+ "value": 3.847
105
+ },
106
+ {
107
+ "start": "2021-12-14T15:00:00+01:00",
108
+ "end": "2021-12-14T16:00:00+01:00",
109
+ "value": 4.315
110
+ },
111
+ {
112
+ "start": "2021-12-14T16:00:00+01:00",
113
+ "end": "2021-12-14T17:00:00+01:00",
114
+ "value": 4.582
115
+ },
116
+ {
117
+ "start": "2021-12-14T17:00:00+01:00",
118
+ "end": "2021-12-14T18:00:00+01:00",
119
+ "value": 2.202
120
+ },
121
+ {
122
+ "start": "2021-12-14T18:00:00+01:00",
123
+ "end": "2021-12-14T19:00:00+01:00",
124
+ "value": 2.153
125
+ },
126
+ {
127
+ "start": "2021-12-14T19:00:00+01:00",
128
+ "end": "2021-12-14T20:00:00+01:00",
129
+ "value": 1.803
130
+ },
131
+ {
132
+ "start": "2021-12-14T20:00:00+01:00",
133
+ "end": "2021-12-14T21:00:00+01:00",
134
+ "value": 1.722
135
+ },
136
+ {
137
+ "start": "2021-12-14T21:00:00+01:00",
138
+ "end": "2021-12-14T22:00:00+01:00",
139
+ "value": 1.716
140
+ },
141
+ {
142
+ "start": "2021-12-14T22:00:00+01:00",
143
+ "end": "2021-12-14T23:00:00+01:00",
144
+ "value": 1.569
145
+ },
146
+ {
147
+ "start": "2021-12-14T23:00:00+01:00",
148
+ "end": "2021-12-15T00:00:00+01:00",
149
+ "value": 1.523
150
+ }
151
+ ],
152
+ "raw_tomorrow": [
153
+ {
154
+ "start": "2021-12-15T00:00:00+01:00",
155
+ "end": "2021-12-15T01:00:00+01:00",
156
+ "value": 1.588
157
+ },
158
+ {
159
+ "start": "2021-12-15T01:00:00+01:00",
160
+ "end": "2021-12-15T02:00:00+01:00",
161
+ "value": 1.521
162
+ },
163
+ {
164
+ "start": "2021-12-15T02:00:00+01:00",
165
+ "end": "2021-12-15T03:00:00+01:00",
166
+ "value": 1.492
167
+ },
168
+ {
169
+ "start": "2021-12-15T03:00:00+01:00",
170
+ "end": "2021-12-15T04:00:00+01:00",
171
+ "value": 1.487
172
+ },
173
+ {
174
+ "start": "2021-12-15T04:00:00+01:00",
175
+ "end": "2021-12-15T05:00:00+01:00",
176
+ "value": 1.497
177
+ },
178
+ {
179
+ "start": "2021-12-15T05:00:00+01:00",
180
+ "end": "2021-12-15T06:00:00+01:00",
181
+ "value": 1.514
182
+ },
183
+ {
184
+ "start": "2021-12-15T06:00:00+01:00",
185
+ "end": "2021-12-15T07:00:00+01:00",
186
+ "value": 1.583
187
+ },
188
+ {
189
+ "start": "2021-12-15T07:00:00+01:00",
190
+ "end": "2021-12-15T08:00:00+01:00",
191
+ "value": 1.667
192
+ },
193
+ {
194
+ "start": "2021-12-15T08:00:00+01:00",
195
+ "end": "2021-12-15T09:00:00+01:00",
196
+ "value": 1.729
197
+ },
198
+ {
199
+ "start": "2021-12-15T09:00:00+01:00",
200
+ "end": "2021-12-15T10:00:00+01:00",
201
+ "value": 1.724
202
+ },
203
+ {
204
+ "start": "2021-12-15T10:00:00+01:00",
205
+ "end": "2021-12-15T11:00:00+01:00",
206
+ "value": 1.707
207
+ },
208
+ {
209
+ "start": "2021-12-15T11:00:00+01:00",
210
+ "end": "2021-12-15T12:00:00+01:00",
211
+ "value": 1.703
212
+ },
213
+ {
214
+ "start": "2021-12-15T12:00:00+01:00",
215
+ "end": "2021-12-15T13:00:00+01:00",
216
+ "value": 1.692
217
+ },
218
+ {
219
+ "start": "2021-12-15T13:00:00+01:00",
220
+ "end": "2021-12-15T14:00:00+01:00",
221
+ "value": 1.692
222
+ },
223
+ {
224
+ "start": "2021-12-15T14:00:00+01:00",
225
+ "end": "2021-12-15T15:00:00+01:00",
226
+ "value": 1.692
227
+ },
228
+ {
229
+ "start": "2021-12-15T15:00:00+01:00",
230
+ "end": "2021-12-15T16:00:00+01:00",
231
+ "value": 1.717
232
+ },
233
+ {
234
+ "start": "2021-12-15T16:00:00+01:00",
235
+ "end": "2021-12-15T17:00:00+01:00",
236
+ "value": 1.72
237
+ },
238
+ {
239
+ "start": "2021-12-15T17:00:00+01:00",
240
+ "end": "2021-12-15T18:00:00+01:00",
241
+ "value": 1.718
242
+ },
243
+ {
244
+ "start": "2021-12-15T18:00:00+01:00",
245
+ "end": "2021-12-15T19:00:00+01:00",
246
+ "value": 1.679
247
+ },
248
+ {
249
+ "start": "2021-12-15T19:00:00+01:00",
250
+ "end": "2021-12-15T20:00:00+01:00",
251
+ "value": 1.661
252
+ },
253
+ {
254
+ "start": "2021-12-15T20:00:00+01:00",
255
+ "end": "2021-12-15T21:00:00+01:00",
256
+ "value": 1.629
257
+ },
258
+ {
259
+ "start": "2021-12-15T21:00:00+01:00",
260
+ "end": "2021-12-15T22:00:00+01:00",
261
+ "value": 1.652
262
+ },
263
+ {
264
+ "start": "2021-12-15T22:00:00+01:00",
265
+ "end": "2021-12-15T23:00:00+01:00",
266
+ "value": 1.612
267
+ },
268
+ {
269
+ "start": "2021-12-15T23:00:00+01:00",
270
+ "end": "2021-12-16T00:00:00+01:00",
271
+ "value": 1.587
272
+ }
273
+ ],
274
+ "unit_of_measurement": "NOK/kWh",
275
+ "friendly_name": "nordpool_kwh_krsand_nok_3_10_025",
276
+ "icon": "mdi:flash"
277
+ },
278
+ "last_changed": "2021-12-14T22:00:00.034750+00:00",
279
+ "last_updated": "2021-12-14T22:00:00.034750+00:00",
280
+ "context": {
281
+ "id": "1c81d6655547e2889f0347188f45cf58",
282
+ "parent_id": null,
283
+ "user_id": null
284
+ },
285
+ "timeSinceChangedMs": 1286197,
286
+ "original_state": "1.523"
287
+ }
288
+ }
@@ -96,8 +96,8 @@ describe("receive-price node", function () {
96
96
  });
97
97
  });
98
98
 
99
- it("should convert nordpool current state prices", function (done) {
100
- const nordpoolPrices = require("./data/nordpool-current-state-prices.json");
99
+ it("should convert nordpool complete current state data set", function (done) {
100
+ const nordpoolPrices = require("./data/nordpool-events-state-2.json");
101
101
  const convertedPrices = require("./data/converted-prices.json");
102
102
  convertedPrices.source = "Nordpool";
103
103
  const flow = [
@@ -113,10 +113,11 @@ describe("receive-price node", function () {
113
113
  const n1 = helper.getNode("n1");
114
114
  const n2 = helper.getNode("n2");
115
115
  n2.on("input", function (msg) {
116
- expect(msg).toHaveProperty("payload", convertedPrices);
116
+ expect(msg.payload.priceData.length).toEqual(48);
117
+ expect(msg.payload.source).toEqual("Nordpool");
117
118
  done();
118
119
  });
119
- n1.receive({ payload: nordpoolPrices });
120
+ n1.receive({ payload: nordpoolPrices.payload, data: nordpoolPrices.data });
120
121
  });
121
122
  });
122
123
  });