node-red-contrib-power-saver 3.0.6 → 3.0.10
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/docs/.vuepress/config.js +5 -1
- package/docs/.vuepress/dist/404.html +3 -3
- package/docs/.vuepress/dist/assets/img/best-save-config.93fa3c21.png +0 -0
- package/docs/.vuepress/dist/assets/img/lowest-price-config.6d66a8c2.png +0 -0
- package/docs/.vuepress/dist/assets/js/app.3cfedce6.js +1 -0
- package/docs/.vuepress/dist/assets/js/{runtime~app.0d53f24f.js → runtime~app.f1d7fab8.js} +1 -1
- package/docs/.vuepress/dist/assets/js/v-0b5e3c8c.163b80fb.js +1 -0
- package/docs/.vuepress/dist/assets/js/v-4637f9e4.60300b77.js +1 -0
- package/docs/.vuepress/dist/assets/js/v-510ed0d4.b76b84de.js +1 -0
- package/docs/.vuepress/dist/assets/js/v-5954bcb2.9e6d2df1.js +1 -0
- package/docs/.vuepress/dist/assets/js/v-61f728ca.64fa763c.js +1 -0
- package/docs/.vuepress/dist/assets/js/v-677dfaed.b84f09f5.js +1 -0
- package/docs/.vuepress/dist/assets/js/{v-7c87f26e.457a1a60.js → v-7c87f26e.91c245da.js} +1 -1
- package/docs/.vuepress/dist/assets/js/v-8daa1a0e.66c9dbce.js +1 -0
- package/docs/.vuepress/dist/assets/js/v-b4a42144.d1856a24.js +1 -0
- package/docs/.vuepress/dist/assets/js/v-fffb8e28.9e0579a1.js +1 -0
- package/docs/.vuepress/dist/changelog/index.html +4 -4
- package/docs/.vuepress/dist/contribute/index.html +4 -4
- package/docs/.vuepress/dist/examples/example-nordpool-current-state.html +176 -156
- package/docs/.vuepress/dist/examples/example-nordpool-events-state.html +3 -3
- package/docs/.vuepress/dist/examples/example-tibber-mqtt.html +3 -3
- package/docs/.vuepress/dist/examples/index.html +3 -3
- package/docs/.vuepress/dist/guide/index.html +5 -5
- package/docs/.vuepress/dist/index.html +4 -4
- package/docs/.vuepress/dist/logo.png +0 -0
- package/docs/.vuepress/dist/nodes/index.html +3 -3
- package/docs/.vuepress/dist/nodes/old-power-saver-doc.html +6 -6
- package/docs/.vuepress/dist/nodes/power-saver.html +3 -3
- package/docs/.vuepress/dist/nodes/ps-elvia-add-tariff.html +3 -3
- package/docs/.vuepress/dist/nodes/ps-receive-price.html +6 -6
- package/docs/.vuepress/dist/nodes/ps-strategy-best-save.html +5 -5
- package/docs/.vuepress/dist/nodes/ps-strategy-lowest-price.html +5 -5
- package/docs/.vuepress/dist/nodes/strategy-input.html +5 -5
- package/docs/.vuepress/public/logo.png +0 -0
- package/docs/README.md +5 -3
- package/docs/changelog/README.md +22 -5
- package/docs/contribute/README.md +1 -1
- package/docs/examples/example-nordpool-current-state.md +172 -152
- package/docs/guide/README.md +12 -10
- package/docs/images/logo copy.png +0 -0
- package/docs/images/logo.png +0 -0
- package/docs/images/logo.psd +0 -0
- package/docs/images/node-red-icon-2.svg +30 -0
- package/docs/nodes/old-power-saver-doc.md +6 -6
- package/docs/nodes/ps-receive-price.md +9 -5
- package/docs/nodes/ps-strategy-best-save.md +5 -1
- package/docs/nodes/ps-strategy-lowest-price.md +3 -3
- package/docs/nodes/strategy-input.md +1 -1
- package/package.json +1 -1
- package/src/elvia/elvia-add-tariff.js +7 -6
- package/src/handle-input.js +1 -7
- package/src/power-saver.js +1 -5
- package/src/receive-price-functions.js +9 -17
- package/src/strategy-lowest-price.js +2 -1
- package/src/utils.js +6 -0
- package/test/data/lowest-price-input-missing-end.json +197 -0
- package/test/data/lowest-price-result-missing-end.json +319 -0
- package/test/data/nordpool-events-state-2.json +288 -0
- package/test/data/nordpool-prices-in-payload.json +287 -0
- package/test/elvia.test.js +16 -2
- package/test/receive-price.test.js +27 -4
- package/test/strategy-lowest-price.test.js +33 -0
- package/docs/.vuepress/dist/assets/js/app.342dc054.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-0b5e3c8c.d008d8bc.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-4637f9e4.22ab9413.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-510ed0d4.129ef915.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-5954bcb2.be07962c.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-61f728ca.802ab15e.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-677dfaed.9bbbd037.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-8daa1a0e.db8b59c6.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-b4a42144.6e0c5aa0.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-fffb8e28.e815e852.js +0 -1
|
@@ -12,7 +12,7 @@ The picture at the bottom of the page, under [Integration with MagicMirror](#int
|
|
|
12
12
|
|
|
13
13
|
## Configuration
|
|
14
14
|
|
|
15
|
-

|
|
15
|
+

|
|
16
16
|
|
|
17
17
|
| Value | Description |
|
|
18
18
|
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -27,6 +27,10 @@ The picture at the bottom of the page, under [Integration with MagicMirror](#int
|
|
|
27
27
|
NB! The `Min recover` only has effect if the previous save-period is of length `Max per sequence`. If the save-period is shorter, the following on-period may be as short as one hour.
|
|
28
28
|
:::
|
|
29
29
|
|
|
30
|
+
::: tip Legionella
|
|
31
|
+
Many people ask if there is a danger that legionella bacteria will grow and become dangerous when the temperature of the water heater is lowered. As long as the water is heated to at least 65 °C every day, or at least every week, the risk of infection is not considered significant, according to the norwegian [FHI](https://www.fhi.no/nettpub/legionellaveilederen/).
|
|
32
|
+
:::
|
|
33
|
+
|
|
30
34
|
### Dynamic config
|
|
31
35
|
|
|
32
36
|
It is possible to change config dynamically by sending a config message to the node. The config messages has a payload with a config object like this example:
|
|
@@ -10,11 +10,11 @@ Strategy node to turn on power the hours when the price is lowest during a given
|
|
|
10
10
|
|
|
11
11
|
## Description
|
|
12
12
|
|
|
13
|
-
The node can work on a specific period from 1 to 24 hours during a 24 hour period. Inside this period, you can decide how many hours that shall be on. The rest of the period will be off. Outside the
|
|
13
|
+
The node can work on a specific period from 1 to 24 hours during a 24 hour period. Inside this period, you can decide how many hours that shall be on. The rest of the period will be off. Outside the period, you can select that the output shall be either on or off. You can also decide that the hours on shall be consecutive (one continuous period) or spread around in multiple on-periods.
|
|
14
14
|
|
|
15
15
|
## Configuration
|
|
16
16
|
|
|
17
|
-

|
|
17
|
+

|
|
18
18
|
|
|
19
19
|
| Value | Description |
|
|
20
20
|
| ---------------------- | -------------------------------------------------------------------------------- |
|
|
@@ -26,7 +26,7 @@ The node can work on a specific period from 1 to 24 hours during a 24 hour perio
|
|
|
26
26
|
| If No Schedule, Send | What to do if there is no valid schedule any more (turn on or off). |
|
|
27
27
|
| Outside Period, Send | Select the value to send outside the selected period. |
|
|
28
28
|
|
|
29
|
-
If you want to use a period of 24 hours, set the From Time and To Time to the same value. The time you select is
|
|
29
|
+
If you want to use a period of 24 hours, set the From Time and To Time to the same value. The time you select is significant in the way that it decides which 24 hours that are considered when finding the hours with lowest price.
|
|
30
30
|
|
|
31
31
|
::: tip Example with Consecutive On-Period
|
|
32
32
|
One example to need a consecutive on-period can be if you want to control the washing machine. Let's say it needs 3 hours, and you want it to run between 22:00 and 06:00. Set `From Time = 22:00`, `To Time = 06:00` and check the `Consecutive On-Period` flag. This will turn on the cheapest 3-hour period from 22:00 to 06:00.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Strategy input format
|
|
2
2
|
|
|
3
|
-
The common input for strategy nodes is a payload with a `priceData` array containing an object for each hour. Each object has a `value`
|
|
3
|
+
The common input for strategy nodes is a payload with a `priceData` array containing an object for each hour. Each object has a `value` which is the price, and a `start` which is the start time for the hour.
|
|
4
4
|
|
|
5
5
|
Example:
|
|
6
6
|
|
package/package.json
CHANGED
|
@@ -6,25 +6,26 @@ module.exports = function (RED) {
|
|
|
6
6
|
function PsElviaAddTariffNode(config) {
|
|
7
7
|
RED.nodes.createNode(this, config);
|
|
8
8
|
this.elviaConfig = RED.nodes.getNode(config.elviaConfig);
|
|
9
|
+
const key = this.elviaConfig.credentials.elviaSubscriptionKey;
|
|
9
10
|
this.tariffKey = config.tariffKey;
|
|
10
11
|
this.range = config.range;
|
|
11
12
|
const node = this;
|
|
12
|
-
|
|
13
|
-
const configList = node.context().global.get("elviaConfigList") || [];
|
|
14
|
-
const key = configList.find((c) => c.id == node.elviaConfig.id)?.elviaSubscriptionKey;
|
|
15
13
|
ping(node, key);
|
|
16
14
|
|
|
17
15
|
node.on("input", function (msg) {
|
|
18
16
|
const prices = msg.payload.priceData;
|
|
17
|
+
if (!prices) {
|
|
18
|
+
node.warn(
|
|
19
|
+
"No price data received on input. Did you use the ps-receive-price node or convert to correct format otherwise?"
|
|
20
|
+
);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
19
23
|
const fromTime = prices[0].start.substr(0, 19);
|
|
20
24
|
const toTime = DateTime.fromISO(prices[prices.length - 1].start)
|
|
21
25
|
.plus({ hours: 1 })
|
|
22
26
|
.toISO()
|
|
23
27
|
.substr(0, 19);
|
|
24
28
|
|
|
25
|
-
const configList = node.context().global.get("elviaConfigList") || [];
|
|
26
|
-
const key = configList.find((c) => c.id == node.elviaConfig.id)?.elviaSubscriptionKey;
|
|
27
|
-
|
|
28
29
|
getTariffForPeriod(node, key, node.tariffKey, fromTime, toTime).then((json) => {
|
|
29
30
|
const tariff = json;
|
|
30
31
|
const priceInfo = tariff.gridTariff.tariffPrice.priceInfo;
|
package/src/handle-input.js
CHANGED
|
@@ -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
|
};
|
package/src/power-saver.js
CHANGED
|
@@ -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,7 +64,15 @@ function convertMsg(msg) {
|
|
|
80
64
|
value: v.value,
|
|
81
65
|
start: v.start,
|
|
82
66
|
}));
|
|
83
|
-
} else if (msg.
|
|
67
|
+
} else if (msg.data?.attributes && msg.data?.attributes["raw_" + day]) {
|
|
68
|
+
result.source = "Nordpool";
|
|
69
|
+
result[day] = msg.data.attributes["raw_" + day]
|
|
70
|
+
.filter((v) => v.value)
|
|
71
|
+
.map((v) => ({
|
|
72
|
+
value: v.value,
|
|
73
|
+
start: v.start,
|
|
74
|
+
}));
|
|
75
|
+
} else if (msg.payload?.attributes && msg.payload.attributes["raw_" + day]) {
|
|
84
76
|
result.source = "Nordpool";
|
|
85
77
|
result[day] = msg.payload.attributes["raw_" + day]
|
|
86
78
|
.filter((v) => v.value)
|
|
@@ -48,7 +48,7 @@ function doPlanning(node, _, priceData, _, dateDayBefore, _) {
|
|
|
48
48
|
if (hour === to && to === from && currentStatus === "Inside") {
|
|
49
49
|
endIndexes.push(i - 1);
|
|
50
50
|
}
|
|
51
|
-
if (hour === to && to !== from && i > 0) {
|
|
51
|
+
if (hour === to && to !== from && i > 0 && currentStatus !== "StartMissing") {
|
|
52
52
|
currentStatus = "Outside";
|
|
53
53
|
endIndexes.push(i - 1);
|
|
54
54
|
}
|
|
@@ -66,6 +66,7 @@ function doPlanning(node, _, priceData, _, dateDayBefore, _) {
|
|
|
66
66
|
hour = DateTime.fromISO(priceData[i].start).hour;
|
|
67
67
|
i--;
|
|
68
68
|
} while (periodStatus[i] === "Inside" && hour !== from);
|
|
69
|
+
startIndexes.splice(startIndexes.length - 1, 1);
|
|
69
70
|
}
|
|
70
71
|
if (hour === (to === 0 ? 23 : to - 1)) {
|
|
71
72
|
endIndexes.push(priceData.length - 1);
|
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,197 @@
|
|
|
1
|
+
{
|
|
2
|
+
"priceData": [
|
|
3
|
+
{
|
|
4
|
+
"value": 1.588,
|
|
5
|
+
"start": "2021-12-15T00:00:00+01:00"
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"value": 1.521,
|
|
9
|
+
"start": "2021-12-15T01:00:00+01:00"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"value": 1.492,
|
|
13
|
+
"start": "2021-12-15T02:00:00+01:00"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"value": 1.487,
|
|
17
|
+
"start": "2021-12-15T03:00:00+01:00"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"value": 1.497,
|
|
21
|
+
"start": "2021-12-15T04:00:00+01:00"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"value": 1.514,
|
|
25
|
+
"start": "2021-12-15T05:00:00+01:00"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"value": 1.583,
|
|
29
|
+
"start": "2021-12-15T06:00:00+01:00"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"value": 1.667,
|
|
33
|
+
"start": "2021-12-15T07:00:00+01:00"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"value": 1.729,
|
|
37
|
+
"start": "2021-12-15T08:00:00+01:00"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"value": 1.724,
|
|
41
|
+
"start": "2021-12-15T09:00:00+01:00"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"value": 1.707,
|
|
45
|
+
"start": "2021-12-15T10:00:00+01:00"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"value": 1.703,
|
|
49
|
+
"start": "2021-12-15T11:00:00+01:00"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"value": 1.692,
|
|
53
|
+
"start": "2021-12-15T12:00:00+01:00"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"value": 1.692,
|
|
57
|
+
"start": "2021-12-15T13:00:00+01:00"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"value": 1.692,
|
|
61
|
+
"start": "2021-12-15T14:00:00+01:00"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"value": 1.717,
|
|
65
|
+
"start": "2021-12-15T15:00:00+01:00"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"value": 1.72,
|
|
69
|
+
"start": "2021-12-15T16:00:00+01:00"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"value": 1.718,
|
|
73
|
+
"start": "2021-12-15T17:00:00+01:00"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"value": 1.679,
|
|
77
|
+
"start": "2021-12-15T18:00:00+01:00"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"value": 1.661,
|
|
81
|
+
"start": "2021-12-15T19:00:00+01:00"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"value": 1.629,
|
|
85
|
+
"start": "2021-12-15T20:00:00+01:00"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"value": 1.652,
|
|
89
|
+
"start": "2021-12-15T21:00:00+01:00"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"value": 1.612,
|
|
93
|
+
"start": "2021-12-15T22:00:00+01:00"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"value": 1.587,
|
|
97
|
+
"start": "2021-12-15T23:00:00+01:00"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"value": 1.682,
|
|
101
|
+
"start": "2021-12-16T00:00:00+01:00"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"value": 1.676,
|
|
105
|
+
"start": "2021-12-16T01:00:00+01:00"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"value": 1.669,
|
|
109
|
+
"start": "2021-12-16T02:00:00+01:00"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"value": 1.673,
|
|
113
|
+
"start": "2021-12-16T03:00:00+01:00"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"value": 1.692,
|
|
117
|
+
"start": "2021-12-16T04:00:00+01:00"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"value": 1.768,
|
|
121
|
+
"start": "2021-12-16T05:00:00+01:00"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"value": 1.888,
|
|
125
|
+
"start": "2021-12-16T06:00:00+01:00"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"value": 1.971,
|
|
129
|
+
"start": "2021-12-16T07:00:00+01:00"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"value": 2.098,
|
|
133
|
+
"start": "2021-12-16T08:00:00+01:00"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"value": 2.076,
|
|
137
|
+
"start": "2021-12-16T09:00:00+01:00"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"value": 2.073,
|
|
141
|
+
"start": "2021-12-16T10:00:00+01:00"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"value": 2.039,
|
|
145
|
+
"start": "2021-12-16T11:00:00+01:00"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"value": 2.003,
|
|
149
|
+
"start": "2021-12-16T12:00:00+01:00"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"value": 1.968,
|
|
153
|
+
"start": "2021-12-16T13:00:00+01:00"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"value": 1.971,
|
|
157
|
+
"start": "2021-12-16T14:00:00+01:00"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"value": 2.029,
|
|
161
|
+
"start": "2021-12-16T15:00:00+01:00"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"value": 2.138,
|
|
165
|
+
"start": "2021-12-16T16:00:00+01:00"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"value": 2.258,
|
|
169
|
+
"start": "2021-12-16T17:00:00+01:00"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"value": 2.248,
|
|
173
|
+
"start": "2021-12-16T18:00:00+01:00"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"value": 2.076,
|
|
177
|
+
"start": "2021-12-16T19:00:00+01:00"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"value": 2.009,
|
|
181
|
+
"start": "2021-12-16T20:00:00+01:00"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"value": 2.051,
|
|
185
|
+
"start": "2021-12-16T21:00:00+01:00"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"value": 1.926,
|
|
189
|
+
"start": "2021-12-16T22:00:00+01:00"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"value": 1.863,
|
|
193
|
+
"start": "2021-12-16T23:00:00+01:00"
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
"source": "Nordpool"
|
|
197
|
+
}
|