node-red-contrib-power-saver 4.1.4 → 4.1.5

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.
@@ -7,6 +7,10 @@ sidebarDepth: 1
7
7
 
8
8
  List the most significant changes.
9
9
 
10
+ ## 4.1.5
11
+
12
+ - Fixed bug based on [this issue](https://github.com/ottopaulsen/node-red-contrib-power-saver/issues/184). Now correctly uses the value for `outputOutsidePeriod` when the planning period spans midnight, and there is no data available before midnight. In this case, the period from midnight to end time cannot be planned, so `outputIfNoSchedule` will be used until end time, and `outputOutsidePeriod` will be used from then. See the issue for more details.
13
+
10
14
  ## 4.1.4
11
15
 
12
16
  - Update dependencies.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-power-saver",
3
- "version": "4.1.4",
3
+ "version": "4.1.5",
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": {
@@ -56,9 +56,11 @@ function doPlanning(node, priceData) {
56
56
  if (hour === to && to === from && currentStatus === "Inside") {
57
57
  endIndexes.push(i - 1);
58
58
  }
59
- if (hour === to && to !== from && i > 0 && currentStatus !== "StartMissing") {
59
+ if (hour === to && to !== from && i > 0 ) {
60
+ if(currentStatus !== "StartMissing") {
61
+ endIndexes.push(i - 1);
62
+ }
60
63
  currentStatus = "Outside";
61
- endIndexes.push(i - 1);
62
64
  }
63
65
  if (hour === from) {
64
66
  currentStatus = "Inside";
@@ -0,0 +1,197 @@
1
+ {
2
+ "priceData": [
3
+ {
4
+ "value": 0.485,
5
+ "start": "2023-11-09T00:00:00+01:00"
6
+ },
7
+ {
8
+ "value": 0.429,
9
+ "start": "2023-11-09T01:00:00+01:00"
10
+ },
11
+ {
12
+ "value": 0.397,
13
+ "start": "2023-11-09T02:00:00+01:00"
14
+ },
15
+ {
16
+ "value": 0.373,
17
+ "start": "2023-11-09T03:00:00+01:00"
18
+ },
19
+ {
20
+ "value": 0.374,
21
+ "start": "2023-11-09T04:00:00+01:00"
22
+ },
23
+ {
24
+ "value": 0.389,
25
+ "start": "2023-11-09T05:00:00+01:00"
26
+ },
27
+ {
28
+ "value": 0.461,
29
+ "start": "2023-11-09T06:00:00+01:00"
30
+ },
31
+ {
32
+ "value": 0.528,
33
+ "start": "2023-11-09T07:00:00+01:00"
34
+ },
35
+ {
36
+ "value": 0.538,
37
+ "start": "2023-11-09T08:00:00+01:00"
38
+ },
39
+ {
40
+ "value": 0.558,
41
+ "start": "2023-11-09T09:00:00+01:00"
42
+ },
43
+ {
44
+ "value": 0.558,
45
+ "start": "2023-11-09T10:00:00+01:00"
46
+ },
47
+ {
48
+ "value": 0.598,
49
+ "start": "2023-11-09T11:00:00+01:00"
50
+ },
51
+ {
52
+ "value": 0.61,
53
+ "start": "2023-11-09T12:00:00+01:00"
54
+ },
55
+ {
56
+ "value": 0.688,
57
+ "start": "2023-11-09T13:00:00+01:00"
58
+ },
59
+ {
60
+ "value": 0.743,
61
+ "start": "2023-11-09T14:00:00+01:00"
62
+ },
63
+ {
64
+ "value": 0.763,
65
+ "start": "2023-11-09T15:00:00+01:00"
66
+ },
67
+ {
68
+ "value": 1.342,
69
+ "start": "2023-11-09T16:00:00+01:00"
70
+ },
71
+ {
72
+ "value": 1.377,
73
+ "start": "2023-11-09T17:00:00+01:00"
74
+ },
75
+ {
76
+ "value": 1.363,
77
+ "start": "2023-11-09T18:00:00+01:00"
78
+ },
79
+ {
80
+ "value": 1.237,
81
+ "start": "2023-11-09T19:00:00+01:00"
82
+ },
83
+ {
84
+ "value": 0.568,
85
+ "start": "2023-11-09T20:00:00+01:00"
86
+ },
87
+ {
88
+ "value": 0.542,
89
+ "start": "2023-11-09T21:00:00+01:00"
90
+ },
91
+ {
92
+ "value": 0.484,
93
+ "start": "2023-11-09T22:00:00+01:00"
94
+ },
95
+ {
96
+ "value": 0.415,
97
+ "start": "2023-11-09T23:00:00+01:00"
98
+ },
99
+ {
100
+ "value": 0.404,
101
+ "start": "2023-11-10T00:00:00+01:00"
102
+ },
103
+ {
104
+ "value": 0.363,
105
+ "start": "2023-11-10T01:00:00+01:00"
106
+ },
107
+ {
108
+ "value": 0.344,
109
+ "start": "2023-11-10T02:00:00+01:00"
110
+ },
111
+ {
112
+ "value": 0.331,
113
+ "start": "2023-11-10T03:00:00+01:00"
114
+ },
115
+ {
116
+ "value": 0.327,
117
+ "start": "2023-11-10T04:00:00+01:00"
118
+ },
119
+ {
120
+ "value": 0.363,
121
+ "start": "2023-11-10T05:00:00+01:00"
122
+ },
123
+ {
124
+ "value": 0.436,
125
+ "start": "2023-11-10T06:00:00+01:00"
126
+ },
127
+ {
128
+ "value": 0.912,
129
+ "start": "2023-11-10T07:00:00+01:00"
130
+ },
131
+ {
132
+ "value": 1.186,
133
+ "start": "2023-11-10T08:00:00+01:00"
134
+ },
135
+ {
136
+ "value": 1.165,
137
+ "start": "2023-11-10T09:00:00+01:00"
138
+ },
139
+ {
140
+ "value": 1.149,
141
+ "start": "2023-11-10T10:00:00+01:00"
142
+ },
143
+ {
144
+ "value": 1.133,
145
+ "start": "2023-11-10T11:00:00+01:00"
146
+ },
147
+ {
148
+ "value": 1.017,
149
+ "start": "2023-11-10T12:00:00+01:00"
150
+ },
151
+ {
152
+ "value": 0.757,
153
+ "start": "2023-11-10T13:00:00+01:00"
154
+ },
155
+ {
156
+ "value": 0.654,
157
+ "start": "2023-11-10T14:00:00+01:00"
158
+ },
159
+ {
160
+ "value": 1.279,
161
+ "start": "2023-11-10T15:00:00+01:00"
162
+ },
163
+ {
164
+ "value": 0.688,
165
+ "start": "2023-11-10T16:00:00+01:00"
166
+ },
167
+ {
168
+ "value": 1.597,
169
+ "start": "2023-11-10T17:00:00+01:00"
170
+ },
171
+ {
172
+ "value": 0.487,
173
+ "start": "2023-11-10T18:00:00+01:00"
174
+ },
175
+ {
176
+ "value": 0.405,
177
+ "start": "2023-11-10T19:00:00+01:00"
178
+ },
179
+ {
180
+ "value": 0.36,
181
+ "start": "2023-11-10T20:00:00+01:00"
182
+ },
183
+ {
184
+ "value": 0.33,
185
+ "start": "2023-11-10T21:00:00+01:00"
186
+ },
187
+ {
188
+ "value": 0.32,
189
+ "start": "2023-11-10T22:00:00+01:00"
190
+ },
191
+ {
192
+ "value": 0.283,
193
+ "start": "2023-11-10T23:00:00+01:00"
194
+ }
195
+ ],
196
+ "source": "Nordpool"
197
+ }
@@ -0,0 +1,341 @@
1
+ {
2
+ "schedule": [
3
+ {
4
+ "time": "2023-11-09T00:00:00+01:00",
5
+ "value": true,
6
+ "countHours": 5
7
+ },
8
+ {
9
+ "time": "2023-11-09T05:00:00+01:00",
10
+ "value": false,
11
+ "countHours": 20
12
+ },
13
+ {
14
+ "time": "2023-11-10T01:00:00+01:00",
15
+ "value": true,
16
+ "countHours": 4
17
+ },
18
+ {
19
+ "time": "2023-11-10T05:00:00+01:00",
20
+ "value": false,
21
+ "countHours": 15
22
+ },
23
+ {
24
+ "time": "2023-11-10T20:00:00+01:00",
25
+ "value": true,
26
+ "countHours": 4
27
+ }
28
+ ],
29
+ "hours": [
30
+ {
31
+ "start": "2023-11-09T00:00:00+01:00",
32
+ "price": 0.485,
33
+ "onOff": true,
34
+ "saving": null
35
+ },
36
+ {
37
+ "start": "2023-11-09T01:00:00+01:00",
38
+ "price": 0.429,
39
+ "onOff": true,
40
+ "saving": null
41
+ },
42
+ {
43
+ "start": "2023-11-09T02:00:00+01:00",
44
+ "price": 0.397,
45
+ "onOff": true,
46
+ "saving": null
47
+ },
48
+ {
49
+ "start": "2023-11-09T03:00:00+01:00",
50
+ "price": 0.373,
51
+ "onOff": true,
52
+ "saving": null
53
+ },
54
+ {
55
+ "start": "2023-11-09T04:00:00+01:00",
56
+ "price": 0.374,
57
+ "onOff": true,
58
+ "saving": null
59
+ },
60
+ {
61
+ "start": "2023-11-09T05:00:00+01:00",
62
+ "price": 0.389,
63
+ "onOff": false,
64
+ "saving": null
65
+ },
66
+ {
67
+ "start": "2023-11-09T06:00:00+01:00",
68
+ "price": 0.461,
69
+ "onOff": false,
70
+ "saving": null
71
+ },
72
+ {
73
+ "start": "2023-11-09T07:00:00+01:00",
74
+ "price": 0.528,
75
+ "onOff": false,
76
+ "saving": null
77
+ },
78
+ {
79
+ "start": "2023-11-09T08:00:00+01:00",
80
+ "price": 0.538,
81
+ "onOff": false,
82
+ "saving": null
83
+ },
84
+ {
85
+ "start": "2023-11-09T09:00:00+01:00",
86
+ "price": 0.558,
87
+ "onOff": false,
88
+ "saving": null
89
+ },
90
+ {
91
+ "start": "2023-11-09T10:00:00+01:00",
92
+ "price": 0.558,
93
+ "onOff": false,
94
+ "saving": null
95
+ },
96
+ {
97
+ "start": "2023-11-09T11:00:00+01:00",
98
+ "price": 0.598,
99
+ "onOff": false,
100
+ "saving": null
101
+ },
102
+ {
103
+ "start": "2023-11-09T12:00:00+01:00",
104
+ "price": 0.61,
105
+ "onOff": false,
106
+ "saving": null
107
+ },
108
+ {
109
+ "start": "2023-11-09T13:00:00+01:00",
110
+ "price": 0.688,
111
+ "onOff": false,
112
+ "saving": null
113
+ },
114
+ {
115
+ "start": "2023-11-09T14:00:00+01:00",
116
+ "price": 0.743,
117
+ "onOff": false,
118
+ "saving": null
119
+ },
120
+ {
121
+ "start": "2023-11-09T15:00:00+01:00",
122
+ "price": 0.763,
123
+ "onOff": false,
124
+ "saving": null
125
+ },
126
+ {
127
+ "start": "2023-11-09T16:00:00+01:00",
128
+ "price": 1.342,
129
+ "onOff": false,
130
+ "saving": null
131
+ },
132
+ {
133
+ "start": "2023-11-09T17:00:00+01:00",
134
+ "price": 1.377,
135
+ "onOff": false,
136
+ "saving": null
137
+ },
138
+ {
139
+ "start": "2023-11-09T18:00:00+01:00",
140
+ "price": 1.363,
141
+ "onOff": false,
142
+ "saving": null
143
+ },
144
+ {
145
+ "start": "2023-11-09T19:00:00+01:00",
146
+ "price": 1.237,
147
+ "onOff": false,
148
+ "saving": null
149
+ },
150
+ {
151
+ "start": "2023-11-09T20:00:00+01:00",
152
+ "price": 0.568,
153
+ "onOff": false,
154
+ "saving": null
155
+ },
156
+ {
157
+ "start": "2023-11-09T21:00:00+01:00",
158
+ "price": 0.542,
159
+ "onOff": false,
160
+ "saving": null
161
+ },
162
+ {
163
+ "start": "2023-11-09T22:00:00+01:00",
164
+ "price": 0.484,
165
+ "onOff": false,
166
+ "saving": null
167
+ },
168
+ {
169
+ "start": "2023-11-09T23:00:00+01:00",
170
+ "price": 0.415,
171
+ "onOff": false,
172
+ "saving": null
173
+ },
174
+ {
175
+ "start": "2023-11-10T00:00:00+01:00",
176
+ "price": 0.404,
177
+ "onOff": false,
178
+ "saving": null
179
+ },
180
+ {
181
+ "start": "2023-11-10T01:00:00+01:00",
182
+ "price": 0.363,
183
+ "onOff": true,
184
+ "saving": null
185
+ },
186
+ {
187
+ "start": "2023-11-10T02:00:00+01:00",
188
+ "price": 0.344,
189
+ "onOff": true,
190
+ "saving": null
191
+ },
192
+ {
193
+ "start": "2023-11-10T03:00:00+01:00",
194
+ "price": 0.331,
195
+ "onOff": true,
196
+ "saving": null
197
+ },
198
+ {
199
+ "start": "2023-11-10T04:00:00+01:00",
200
+ "price": 0.327,
201
+ "onOff": true,
202
+ "saving": null
203
+ },
204
+ {
205
+ "start": "2023-11-10T05:00:00+01:00",
206
+ "price": 0.363,
207
+ "onOff": false,
208
+ "saving": null
209
+ },
210
+ {
211
+ "start": "2023-11-10T06:00:00+01:00",
212
+ "price": 0.436,
213
+ "onOff": false,
214
+ "saving": null
215
+ },
216
+ {
217
+ "start": "2023-11-10T07:00:00+01:00",
218
+ "price": 0.912,
219
+ "onOff": false,
220
+ "saving": null
221
+ },
222
+ {
223
+ "start": "2023-11-10T08:00:00+01:00",
224
+ "price": 1.186,
225
+ "onOff": false,
226
+ "saving": null
227
+ },
228
+ {
229
+ "start": "2023-11-10T09:00:00+01:00",
230
+ "price": 1.165,
231
+ "onOff": false,
232
+ "saving": null
233
+ },
234
+ {
235
+ "start": "2023-11-10T10:00:00+01:00",
236
+ "price": 1.149,
237
+ "onOff": false,
238
+ "saving": null
239
+ },
240
+ {
241
+ "start": "2023-11-10T11:00:00+01:00",
242
+ "price": 1.133,
243
+ "onOff": false,
244
+ "saving": null
245
+ },
246
+ {
247
+ "start": "2023-11-10T12:00:00+01:00",
248
+ "price": 1.017,
249
+ "onOff": false,
250
+ "saving": null
251
+ },
252
+ {
253
+ "start": "2023-11-10T13:00:00+01:00",
254
+ "price": 0.757,
255
+ "onOff": false,
256
+ "saving": null
257
+ },
258
+ {
259
+ "start": "2023-11-10T14:00:00+01:00",
260
+ "price": 0.654,
261
+ "onOff": false,
262
+ "saving": null
263
+ },
264
+ {
265
+ "start": "2023-11-10T15:00:00+01:00",
266
+ "price": 1.279,
267
+ "onOff": false,
268
+ "saving": null
269
+ },
270
+ {
271
+ "start": "2023-11-10T16:00:00+01:00",
272
+ "price": 0.688,
273
+ "onOff": false,
274
+ "saving": null
275
+ },
276
+ {
277
+ "start": "2023-11-10T17:00:00+01:00",
278
+ "price": 1.597,
279
+ "onOff": false,
280
+ "saving": null
281
+ },
282
+ {
283
+ "start": "2023-11-10T18:00:00+01:00",
284
+ "price": 0.487,
285
+ "onOff": false,
286
+ "saving": null
287
+ },
288
+ {
289
+ "start": "2023-11-10T19:00:00+01:00",
290
+ "price": 0.405,
291
+ "onOff": false,
292
+ "saving": null
293
+ },
294
+ {
295
+ "start": "2023-11-10T20:00:00+01:00",
296
+ "price": 0.36,
297
+ "onOff": true,
298
+ "saving": null
299
+ },
300
+ {
301
+ "start": "2023-11-10T21:00:00+01:00",
302
+ "price": 0.33,
303
+ "onOff": true,
304
+ "saving": null
305
+ },
306
+ {
307
+ "start": "2023-11-10T22:00:00+01:00",
308
+ "price": 0.32,
309
+ "onOff": true,
310
+ "saving": null
311
+ },
312
+ {
313
+ "start": "2023-11-10T23:00:00+01:00",
314
+ "price": 0.283,
315
+ "onOff": true,
316
+ "saving": null
317
+ }
318
+ ],
319
+ "source": "Nordpool",
320
+ "config": {
321
+ "fromTime": "20",
322
+ "toTime": "05",
323
+ "hoursOn": 4,
324
+ "maxPrice": null,
325
+ "doNotSplit": false,
326
+ "sendCurrentValueWhenRescheduling": true,
327
+ "outputIfNoSchedule": true,
328
+ "outputOutsidePeriod": false,
329
+ "outputValueForOn": true,
330
+ "outputValueForOff": false,
331
+ "outputValueForOntype": "bool",
332
+ "outputValueForOfftype": "bool",
333
+ "override": "auto",
334
+ "contextStorage": "default",
335
+ "hasChanged": false
336
+ },
337
+ "time": "2023-11-09T16:08:07.158+01:00",
338
+ "version": "4.1.4",
339
+ "strategyNodeId": "n1",
340
+ "current": true
341
+ }
@@ -0,0 +1,60 @@
1
+ const { DateTime } = require("luxon");
2
+ const expect = require("chai").expect;
3
+ const helper = require("node-red-node-test-helper");
4
+ const lowestPrice = require("../src/strategy-lowest-price.js");
5
+ const { version } = require("../package.json");
6
+ const { makePayload } = require("./strategy-lowest-price-test-utils.js");
7
+
8
+ helper.init(require.resolve("node-red"));
9
+
10
+ describe("ps-strategy-lowest-price-bug", function () {
11
+ beforeEach(function (done) {
12
+ helper.startServer(done);
13
+ });
14
+
15
+ afterEach(function (done) {
16
+ helper.unload().then(function () {
17
+ helper.stopServer(done);
18
+ });
19
+ });
20
+
21
+ it("use outputOutsidePeriod correct when period spans midnight", function (done) {
22
+ const input = require("./data/lowest-price-bug184-input.json");
23
+ const result = require("./data/lowest-price-bug184.json");
24
+ result.version = version;
25
+ result.strategyNodeId = "n1";
26
+ result.current = false;
27
+ const flow = [
28
+ {
29
+ id: "n1",
30
+ type: "ps-strategy-lowest-price",
31
+ name: "test name",
32
+ fromTime: "20",
33
+ toTime: "05",
34
+ hoursOn: 4,
35
+ maxPrice: null,
36
+ doNotSplit: false,
37
+ sendCurrentValueWhenRescheduling: true,
38
+ outputIfNoSchedule: true,
39
+ outputOutsidePeriod: false,
40
+ wires: [["n3"], ["n4"], ["n2"]],
41
+ },
42
+ { id: "n2", type: "helper" },
43
+ { id: "n3", type: "helper" },
44
+ { id: "n4", type: "helper" },
45
+ ];
46
+ helper.load(lowestPrice, flow, function () {
47
+ const n1 = helper.getNode("n1");
48
+ const n2 = helper.getNode("n2");
49
+ n2.on("input", function (msg) {
50
+ result.current = msg.payload.current;
51
+ expect(msg).to.have.deep.property("payload", result);
52
+ n1.warn.should.not.be.called;
53
+ done();
54
+ });
55
+ const time = DateTime.fromISO("2023-11-09T16:08:07.158+01:00");
56
+ result.time = time.toISO();
57
+ n1.receive({ payload: makePayload(input, time) });
58
+ });
59
+ });
60
+ });