node-red-contrib-power-saver 3.2.0 → 3.3.0
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 -0
- package/docs/.vuepress/dist/.nojekyll +0 -0
- package/docs/.vuepress/dist/404.html +2 -2
- package/docs/.vuepress/dist/assets/js/{app.eae70176.js → app.49ad6d54.js} +1 -1
- package/docs/.vuepress/dist/assets/js/runtime~app.547d0f4e.js +1 -0
- package/docs/.vuepress/dist/assets/js/v-0b5e3c8c.3b37457f.js +1 -0
- package/docs/.vuepress/dist/assets/js/{v-1e2b191e.50b8fa18.js → v-1e2b191e.98cc227b.js} +1 -1
- package/docs/.vuepress/dist/assets/js/v-4637f9e4.b320f5e8.js +1 -0
- package/docs/.vuepress/dist/assets/js/v-510ed0d4.3c7e0056.js +1 -0
- package/docs/.vuepress/dist/changelog/index.html +3 -3
- package/docs/.vuepress/dist/contribute/index.html +2 -2
- package/docs/.vuepress/dist/examples/example-next-schedule-entity.html +2 -2
- package/docs/.vuepress/dist/examples/example-nordpool-current-state.html +2 -2
- package/docs/.vuepress/dist/examples/example-nordpool-events-state.html +2 -2
- package/docs/.vuepress/dist/examples/example-tibber-mqtt.html +2 -2
- package/docs/.vuepress/dist/examples/index.html +2 -2
- package/docs/.vuepress/dist/faq/index.html +2 -2
- package/docs/.vuepress/dist/guide/index.html +2 -2
- package/docs/.vuepress/dist/index.html +2 -2
- package/docs/.vuepress/dist/nodes/index.html +2 -2
- package/docs/.vuepress/dist/nodes/old-power-saver-doc.html +2 -2
- package/docs/.vuepress/dist/nodes/power-saver.html +2 -2
- package/docs/.vuepress/dist/nodes/ps-elvia-add-tariff.html +2 -2
- package/docs/.vuepress/dist/nodes/ps-general-add-tariff.html +3 -3
- package/docs/.vuepress/dist/nodes/ps-receive-price.html +2 -2
- package/docs/.vuepress/dist/nodes/ps-strategy-best-save.html +4 -4
- package/docs/.vuepress/dist/nodes/ps-strategy-lowest-price.html +4 -4
- package/docs/.vuepress/dist/nodes/strategy-input.html +2 -2
- package/docs/changelog/README.md +22 -0
- package/docs/examples/example-nordpool-current-state.md +0 -1
- package/docs/examples/example-tibber-mqtt.md +0 -1
- package/docs/faq/README.md +5 -1
- package/docs/images/best-save-config.png +0 -0
- package/docs/nodes/ps-strategy-best-save.md +77 -8
- package/docs/nodes/ps-strategy-lowest-price.md +43 -0
- package/package.json +1 -1
- package/src/general-add-tariff-functions.js +0 -1
- package/src/general-add-tariff.js +2 -4
- package/src/handle-input.js +32 -13
- package/src/strategy-best-save.html +0 -21
- package/src/strategy-best-save.js +8 -11
- package/test/commands-input.test.js +47 -0
- package/test/data/best-save-result.json +1 -2
- package/test/data/current-undefined-prices.json +197 -0
- package/test/data/current-undefined-result.json +208 -0
- package/test/data/lowest-price-result-missing-end.json +2 -1
- package/test/data/reconfigResult.js +56 -294
- package/test/data/reconfigResult_old2.js +75 -0
- package/test/data/tibber-result-end-0-24h.json +1 -0
- package/test/data/tibber-result-end-0.json +1 -0
- package/test/send-config-input.test.js +3 -37
- package/test/strategy-best-save-test-utils.js +2 -1
- package/test/test-utils.js +1 -7
- package/test/utils.test.js +0 -33
- package/docs/.vuepress/dist/assets/js/runtime~app.3384c251.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-0b5e3c8c.d62b30f7.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-4637f9e4.b67738ed.js +0 -1
- package/docs/.vuepress/dist/assets/js/v-510ed0d4.528dd6f3.js +0 -1
- package/test/data/adjustedResult.js +0 -302
- package/test/data/adjustedResult_old.js +0 -154
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
const cloneDeep = require("lodash.clonedeep");
|
|
2
|
-
const {
|
|
3
|
-
const {
|
|
4
|
-
const { roundPrice } = require("./utils");
|
|
5
|
-
const { extractPlanForDate, getEffectiveConfig, validationFailure } = require("./utils");
|
|
2
|
+
const { addTariffToPrices } = require("./general-add-tariff-functions");
|
|
3
|
+
const { getEffectiveConfig } = require("./utils");
|
|
6
4
|
|
|
7
5
|
module.exports = function (RED) {
|
|
8
6
|
function PsGeneralAddTariffNode(config) {
|
package/src/handle-input.js
CHANGED
|
@@ -3,15 +3,22 @@ const { DateTime } = require("luxon");
|
|
|
3
3
|
const { version } = require("../package.json");
|
|
4
4
|
|
|
5
5
|
function handleStrategyInput(node, msg, doPlanning) {
|
|
6
|
-
node.schedulingTimeout = null;
|
|
7
|
-
|
|
8
6
|
const effectiveConfig = getEffectiveConfig(node, msg);
|
|
9
7
|
|
|
10
8
|
if (!validateInput(node, msg)) {
|
|
11
9
|
return;
|
|
12
10
|
}
|
|
13
|
-
|
|
11
|
+
if (msg.payload.commands && msg.payload.commands.reset) {
|
|
12
|
+
node.warn("Resetting node context by command");
|
|
13
|
+
// Reset all saved data
|
|
14
|
+
node.context().set(["lastPlan", "lastPriceData", "lastSource"], [undefined, undefined, undefined]);
|
|
15
|
+
deleteSavedScheduleBefore(node, DateTime.now().plus({ days: 1 }), 100);
|
|
16
|
+
}
|
|
17
|
+
const { priceData, source } = getPriceData(node, msg);
|
|
14
18
|
if (!priceData) {
|
|
19
|
+
const message = "No price data";
|
|
20
|
+
node.warn(message);
|
|
21
|
+
node.status({ fill: "yellow", shape: "dot", text: message });
|
|
15
22
|
return;
|
|
16
23
|
}
|
|
17
24
|
const planFromTime = msg.payload.time ? DateTime.fromISO(msg.payload.time) : DateTime.now();
|
|
@@ -34,6 +41,8 @@ function handleStrategyInput(node, msg, doPlanning) {
|
|
|
34
41
|
node.context().set("lastPlan", plan);
|
|
35
42
|
dates.forEach((d) => saveDayData(node, d, extractPlanForDate(plan, d)));
|
|
36
43
|
|
|
44
|
+
const sentOnCommand = !!msg.payload.commands?.sendSchedule;
|
|
45
|
+
|
|
37
46
|
// Prepare output
|
|
38
47
|
let output1 = null;
|
|
39
48
|
let output2 = null;
|
|
@@ -41,8 +50,9 @@ function handleStrategyInput(node, msg, doPlanning) {
|
|
|
41
50
|
payload: {
|
|
42
51
|
schedule: plan.schedule,
|
|
43
52
|
hours: plan.hours,
|
|
44
|
-
source
|
|
53
|
+
source,
|
|
45
54
|
config: effectiveConfig,
|
|
55
|
+
sentOnCommand,
|
|
46
56
|
time: planFromTime.toISO(),
|
|
47
57
|
version,
|
|
48
58
|
},
|
|
@@ -51,7 +61,7 @@ function handleStrategyInput(node, msg, doPlanning) {
|
|
|
51
61
|
// Find current output, and set output (if configured to do)
|
|
52
62
|
const pastSchedule = plan.schedule.filter((entry) => DateTime.fromISO(entry.time) <= planFromTime);
|
|
53
63
|
|
|
54
|
-
const sendNow = node.sendCurrentValueWhenRescheduling && pastSchedule.length > 0;
|
|
64
|
+
const sendNow = !!node.sendCurrentValueWhenRescheduling && pastSchedule.length > 0 && !sentOnCommand;
|
|
55
65
|
const currentValue = pastSchedule[pastSchedule.length - 1]?.value;
|
|
56
66
|
if (sendNow) {
|
|
57
67
|
output1 = currentValue ? { payload: true } : null;
|
|
@@ -71,24 +81,28 @@ function handleStrategyInput(node, msg, doPlanning) {
|
|
|
71
81
|
|
|
72
82
|
function getPriceData(node, msg) {
|
|
73
83
|
const isConfigMsg = !!msg?.payload?.config;
|
|
84
|
+
const isCommandMsg = !!msg?.payload?.commands;
|
|
74
85
|
const isPriceMsg = !!msg?.payload?.priceData;
|
|
75
|
-
if (isConfigMsg && !isPriceMsg) {
|
|
76
|
-
|
|
86
|
+
if ((isConfigMsg || isCommandMsg) && !isPriceMsg) {
|
|
87
|
+
const priceData = node.context().get("lastPriceData");
|
|
88
|
+
const source = node.context().get("lastSource");
|
|
89
|
+
return { priceData, source };
|
|
77
90
|
}
|
|
78
91
|
const priceData = msg.payload.priceData;
|
|
92
|
+
const source = msg.payload.source;
|
|
79
93
|
node.context().set("lastPriceData", priceData);
|
|
80
|
-
|
|
94
|
+
node.context().set("lastSource", source);
|
|
95
|
+
return { priceData, source };
|
|
81
96
|
}
|
|
82
97
|
|
|
83
98
|
function runSchedule(node, schedule, time, currentSent = false) {
|
|
84
|
-
let currentTime = time;
|
|
85
99
|
let remainingSchedule = schedule.filter((entry) => {
|
|
86
|
-
return DateTime.fromISO(entry.time) >
|
|
100
|
+
return DateTime.fromISO(entry.time) > time;
|
|
87
101
|
});
|
|
88
102
|
if (remainingSchedule.length > 0) {
|
|
89
103
|
const entry = remainingSchedule[0];
|
|
90
104
|
const nextTime = DateTime.fromISO(entry.time);
|
|
91
|
-
const wait = nextTime -
|
|
105
|
+
const wait = nextTime - time;
|
|
92
106
|
const onOff = entry.value ? "on" : "off";
|
|
93
107
|
node.log("Switching " + onOff + " in " + wait + " milliseconds");
|
|
94
108
|
const statusMessage = `${remainingSchedule.length} changes - ${
|
|
@@ -109,12 +123,14 @@ function runSchedule(node, schedule, time, currentSent = false) {
|
|
|
109
123
|
}
|
|
110
124
|
}
|
|
111
125
|
|
|
112
|
-
function deleteSavedScheduleBefore(node, day) {
|
|
126
|
+
function deleteSavedScheduleBefore(node, day, checkDays = 0) {
|
|
113
127
|
let date = day;
|
|
128
|
+
let count = 0;
|
|
114
129
|
do {
|
|
115
130
|
date = date.plus({ days: -1 });
|
|
116
131
|
data = node.context().set(date.toISO(), undefined);
|
|
117
|
-
|
|
132
|
+
count++;
|
|
133
|
+
} while (data || count <= checkDays);
|
|
118
134
|
}
|
|
119
135
|
|
|
120
136
|
function saveDayData(node, date, plan) {
|
|
@@ -139,6 +155,9 @@ function validateInput(node, msg) {
|
|
|
139
155
|
if (msg.payload.config !== undefined) {
|
|
140
156
|
return true; // Got config msg
|
|
141
157
|
}
|
|
158
|
+
if (msg.payload.commands !== undefined) {
|
|
159
|
+
return true; // Got command msg
|
|
160
|
+
}
|
|
142
161
|
if (msg.payload.priceData === undefined) {
|
|
143
162
|
validationFailure(node, "Payload is missing priceData");
|
|
144
163
|
return;
|
|
@@ -26,11 +26,6 @@
|
|
|
26
26
|
align: "left",
|
|
27
27
|
},
|
|
28
28
|
outputIfNoSchedule: { value: "true", required: true, align: "left" },
|
|
29
|
-
scheduleOnlyFromCurrentTime: {
|
|
30
|
-
value: "true",
|
|
31
|
-
required: true,
|
|
32
|
-
align: "left",
|
|
33
|
-
},
|
|
34
29
|
},
|
|
35
30
|
inputs: 1,
|
|
36
31
|
outputs: 3,
|
|
@@ -52,17 +47,6 @@
|
|
|
52
47
|
},
|
|
53
48
|
],
|
|
54
49
|
});
|
|
55
|
-
$("#node-input-scheduleOnlyFromCurrentTime").typedInput({
|
|
56
|
-
types: [
|
|
57
|
-
{
|
|
58
|
-
value: "nowOrStart",
|
|
59
|
-
options: [
|
|
60
|
-
{ value: "false", label: "Whole data set" },
|
|
61
|
-
{ value: "true", label: "From current hour" },
|
|
62
|
-
],
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
});
|
|
66
50
|
},
|
|
67
51
|
});
|
|
68
52
|
</script>
|
|
@@ -88,11 +72,6 @@
|
|
|
88
72
|
<label for="node-input-minSaving"><i class="fa fa-eur"></i> Min saving</label>
|
|
89
73
|
<input type="text" id="node-input-minSaving" placeholder="Minimum to save for turning off" style="width: 80px">
|
|
90
74
|
</div>
|
|
91
|
-
<div class="form-row">
|
|
92
|
-
<label for="node-input-scheduleOnlyFromCurrentTime">Schedule for</label>
|
|
93
|
-
<input type="text" id="node-input-scheduleOnlyFromCurrentTime" style="width: 160px">
|
|
94
|
-
</label>
|
|
95
|
-
</div>
|
|
96
75
|
<h3>Output</h3>
|
|
97
76
|
<div class="form-row">
|
|
98
77
|
<label for="node-input-sendCurrentValueWhenRescheduling" style="width:240px">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { countAtEnd, makeSchedule, getSavings,
|
|
1
|
+
const { countAtEnd, makeSchedule, getSavings, getDiff } = require("./utils");
|
|
2
2
|
const { handleStrategyInput } = require("./handle-input");
|
|
3
3
|
const { loadDayData } = require("./utils");
|
|
4
4
|
|
|
@@ -15,7 +15,6 @@ module.exports = function (RED) {
|
|
|
15
15
|
minSaving: parseFloat(config.minSaving),
|
|
16
16
|
sendCurrentValueWhenRescheduling: config.sendCurrentValueWhenRescheduling,
|
|
17
17
|
outputIfNoSchedule: config.outputIfNoSchedule === "true",
|
|
18
|
-
scheduleOnlyFromCurrentTime: config.scheduleOnlyFromCurrentTime === "true",
|
|
19
18
|
};
|
|
20
19
|
node.context().set("config", originalConfig);
|
|
21
20
|
|
|
@@ -43,20 +42,18 @@ function adjustSavingsPassedHours(plan, includeFromLastPlanHours) {
|
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
function loadDataJustBefore(node, dateDayBefore
|
|
45
|
+
function loadDataJustBefore(node, dateDayBefore) {
|
|
47
46
|
const dataDayBefore = loadDayData(node, dateDayBefore);
|
|
48
|
-
const dataToday = loadDayData(node, dateToday);
|
|
49
47
|
return {
|
|
50
|
-
schedule: [...dataDayBefore.schedule
|
|
51
|
-
hours: [...dataDayBefore.hours
|
|
48
|
+
schedule: [...dataDayBefore.schedule],
|
|
49
|
+
hours: [...dataDayBefore.hours],
|
|
52
50
|
};
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
function doPlanning(node,
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
const startTimes = priceData.map((d) => d.start).slice(startAtIndex);
|
|
53
|
+
function doPlanning(node, _, priceData, _, dateDayBefore, _) {
|
|
54
|
+
const dataJustBefore = loadDataJustBefore(node, dateDayBefore);
|
|
55
|
+
const values = priceData.map((d) => d.value);
|
|
56
|
+
const startTimes = priceData.map((d) => d.start);
|
|
60
57
|
const onOffBefore = dataJustBefore.hours.map((h) => h.onOff);
|
|
61
58
|
const lastPlanHours = node.context().get("lastPlan")?.hours ?? [];
|
|
62
59
|
const plan = makePlan(node, values, startTimes, onOffBefore);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const expect = require("expect");
|
|
2
|
+
const helper = require("node-red-node-test-helper");
|
|
3
|
+
const bestSave = require("../src/strategy-best-save.js");
|
|
4
|
+
const prices = require("./data/converted-prices.json");
|
|
5
|
+
const result = require("./data/best-save-result.json");
|
|
6
|
+
const { testPlan, equalPlan } = require("./test-utils");
|
|
7
|
+
const { makeFlow, makePayload } = require("./strategy-best-save-test-utils");
|
|
8
|
+
|
|
9
|
+
helper.init(require.resolve("node-red"));
|
|
10
|
+
|
|
11
|
+
describe("send command as input", () => {
|
|
12
|
+
beforeEach(function (done) {
|
|
13
|
+
helper.startServer(done);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
afterEach(function (done) {
|
|
17
|
+
helper.unload().then(function () {
|
|
18
|
+
helper.stopServer(done);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("should send output on command", function (done) {
|
|
23
|
+
const flow = makeFlow(3, 2, true);
|
|
24
|
+
let pass = 1;
|
|
25
|
+
helper.load(bestSave, flow, function () {
|
|
26
|
+
const n1 = helper.getNode("n1");
|
|
27
|
+
const n2 = helper.getNode("n2");
|
|
28
|
+
n1.sendCurrentValueWhenRescheduling = true;
|
|
29
|
+
n2.on("input", function (msg) {
|
|
30
|
+
switch (pass) {
|
|
31
|
+
case 1:
|
|
32
|
+
pass++;
|
|
33
|
+
expect(equalPlan(result, msg.payload)).toBeTruthy();
|
|
34
|
+
expect(msg.payload.sentOnCommand).toBeFalsy();
|
|
35
|
+
n1.receive({ payload: { commands: { sendSchedule: true } } });
|
|
36
|
+
break;
|
|
37
|
+
case 2:
|
|
38
|
+
expect(equalPlan(result, msg.payload)).toBeTruthy();
|
|
39
|
+
expect(msg.payload.sentOnCommand).toBeTruthy();
|
|
40
|
+
done();
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
n1.receive({ payload: makePayload(prices, testPlan.time) });
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
{
|
|
2
|
+
"priceData": [
|
|
3
|
+
{
|
|
4
|
+
"value": 1.792,
|
|
5
|
+
"start": "2022-01-12T00:00:00+01:00"
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"value": 1.761,
|
|
9
|
+
"start": "2022-01-12T01:00:00+01:00"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"value": 1.744,
|
|
13
|
+
"start": "2022-01-12T02:00:00+01:00"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"value": 1.741,
|
|
17
|
+
"start": "2022-01-12T03:00:00+01:00"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"value": 1.752,
|
|
21
|
+
"start": "2022-01-12T04:00:00+01:00"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"value": 1.773,
|
|
25
|
+
"start": "2022-01-12T05:00:00+01:00"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"value": 1.773,
|
|
29
|
+
"start": "2022-01-12T06:00:00+01:00"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"value": 1.832,
|
|
33
|
+
"start": "2022-01-12T07:00:00+01:00"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"value": 1.863,
|
|
37
|
+
"start": "2022-01-12T08:00:00+01:00"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"value": 1.826,
|
|
41
|
+
"start": "2022-01-12T09:00:00+01:00"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"value": 1.795,
|
|
45
|
+
"start": "2022-01-12T10:00:00+01:00"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"value": 1.753,
|
|
49
|
+
"start": "2022-01-12T11:00:00+01:00"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"value": 1.75,
|
|
53
|
+
"start": "2022-01-12T12:00:00+01:00"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"value": 1.738,
|
|
57
|
+
"start": "2022-01-12T13:00:00+01:00"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"value": 1.717,
|
|
61
|
+
"start": "2022-01-12T14:00:00+01:00"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"value": 1.707,
|
|
65
|
+
"start": "2022-01-12T15:00:00+01:00"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"value": 1.708,
|
|
69
|
+
"start": "2022-01-12T16:00:00+01:00"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"value": 1.707,
|
|
73
|
+
"start": "2022-01-12T17:00:00+01:00"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"value": 1.692,
|
|
77
|
+
"start": "2022-01-12T18:00:00+01:00"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"value": 1.661,
|
|
81
|
+
"start": "2022-01-12T19:00:00+01:00"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"value": 1.64,
|
|
85
|
+
"start": "2022-01-12T20:00:00+01:00"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"value": 1.634,
|
|
89
|
+
"start": "2022-01-12T21:00:00+01:00"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"value": 1.614,
|
|
93
|
+
"start": "2022-01-12T22:00:00+01:00"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"value": 1.598,
|
|
97
|
+
"start": "2022-01-12T23:00:00+01:00"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"value": 1.569,
|
|
101
|
+
"start": "2022-01-13T00:00:00+01:00"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"value": 1.548,
|
|
105
|
+
"start": "2022-01-13T01:00:00+01:00"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"value": 1.518,
|
|
109
|
+
"start": "2022-01-13T02:00:00+01:00"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"value": 1.507,
|
|
113
|
+
"start": "2022-01-13T03:00:00+01:00"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"value": 1.501,
|
|
117
|
+
"start": "2022-01-13T04:00:00+01:00"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"value": 1.508,
|
|
121
|
+
"start": "2022-01-13T05:00:00+01:00"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"value": 1.544,
|
|
125
|
+
"start": "2022-01-13T06:00:00+01:00"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"value": 1.612,
|
|
129
|
+
"start": "2022-01-13T07:00:00+01:00"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"value": 1.646,
|
|
133
|
+
"start": "2022-01-13T08:00:00+01:00"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"value": 1.654,
|
|
137
|
+
"start": "2022-01-13T09:00:00+01:00"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"value": 1.656,
|
|
141
|
+
"start": "2022-01-13T10:00:00+01:00"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"value": 1.648,
|
|
145
|
+
"start": "2022-01-13T11:00:00+01:00"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"value": 1.617,
|
|
149
|
+
"start": "2022-01-13T12:00:00+01:00"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"value": 1.613,
|
|
153
|
+
"start": "2022-01-13T13:00:00+01:00"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"value": 1.612,
|
|
157
|
+
"start": "2022-01-13T14:00:00+01:00"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"value": 1.611,
|
|
161
|
+
"start": "2022-01-13T15:00:00+01:00"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"value": 1.618,
|
|
165
|
+
"start": "2022-01-13T16:00:00+01:00"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"value": 1.616,
|
|
169
|
+
"start": "2022-01-13T17:00:00+01:00"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"value": 1.617,
|
|
173
|
+
"start": "2022-01-13T18:00:00+01:00"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"value": 1.601,
|
|
177
|
+
"start": "2022-01-13T19:00:00+01:00"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"value": 1.568,
|
|
181
|
+
"start": "2022-01-13T20:00:00+01:00"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"value": 1.565,
|
|
185
|
+
"start": "2022-01-13T21:00:00+01:00"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"value": 1.506,
|
|
189
|
+
"start": "2022-01-13T22:00:00+01:00"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"value": 1.468,
|
|
193
|
+
"start": "2022-01-13T23:00:00+01:00"
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
"source": "Nordpool"
|
|
197
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schedule": [
|
|
3
|
+
{
|
|
4
|
+
"time": "2022-01-12T18:00:00+01:00",
|
|
5
|
+
"value": true
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"time": "2022-01-13T17:00:00+01:00",
|
|
9
|
+
"value": false
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"time": "2022-01-13T23:00:00+01:00",
|
|
13
|
+
"value": true
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"hours": [
|
|
17
|
+
{
|
|
18
|
+
"price": 1.692,
|
|
19
|
+
"onOff": true,
|
|
20
|
+
"start": "2022-01-12T18:00:00+01:00",
|
|
21
|
+
"saving": null
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"price": 1.661,
|
|
25
|
+
"onOff": true,
|
|
26
|
+
"start": "2022-01-12T19:00:00+01:00",
|
|
27
|
+
"saving": null
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"price": 1.64,
|
|
31
|
+
"onOff": true,
|
|
32
|
+
"start": "2022-01-12T20:00:00+01:00",
|
|
33
|
+
"saving": null
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"price": 1.634,
|
|
37
|
+
"onOff": true,
|
|
38
|
+
"start": "2022-01-12T21:00:00+01:00",
|
|
39
|
+
"saving": null
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"price": 1.614,
|
|
43
|
+
"onOff": true,
|
|
44
|
+
"start": "2022-01-12T22:00:00+01:00",
|
|
45
|
+
"saving": null
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"price": 1.598,
|
|
49
|
+
"onOff": true,
|
|
50
|
+
"start": "2022-01-12T23:00:00+01:00",
|
|
51
|
+
"saving": null
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"price": 1.569,
|
|
55
|
+
"onOff": true,
|
|
56
|
+
"start": "2022-01-13T00:00:00+01:00",
|
|
57
|
+
"saving": null
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"price": 1.548,
|
|
61
|
+
"onOff": true,
|
|
62
|
+
"start": "2022-01-13T01:00:00+01:00",
|
|
63
|
+
"saving": null
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"price": 1.518,
|
|
67
|
+
"onOff": true,
|
|
68
|
+
"start": "2022-01-13T02:00:00+01:00",
|
|
69
|
+
"saving": null
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"price": 1.507,
|
|
73
|
+
"onOff": true,
|
|
74
|
+
"start": "2022-01-13T03:00:00+01:00",
|
|
75
|
+
"saving": null
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"price": 1.501,
|
|
79
|
+
"onOff": true,
|
|
80
|
+
"start": "2022-01-13T04:00:00+01:00",
|
|
81
|
+
"saving": null
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"price": 1.508,
|
|
85
|
+
"onOff": true,
|
|
86
|
+
"start": "2022-01-13T05:00:00+01:00",
|
|
87
|
+
"saving": null
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"price": 1.544,
|
|
91
|
+
"onOff": true,
|
|
92
|
+
"start": "2022-01-13T06:00:00+01:00",
|
|
93
|
+
"saving": null
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"price": 1.612,
|
|
97
|
+
"onOff": true,
|
|
98
|
+
"start": "2022-01-13T07:00:00+01:00",
|
|
99
|
+
"saving": null
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"price": 1.646,
|
|
103
|
+
"onOff": true,
|
|
104
|
+
"start": "2022-01-13T08:00:00+01:00",
|
|
105
|
+
"saving": null
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"price": 1.654,
|
|
109
|
+
"onOff": true,
|
|
110
|
+
"start": "2022-01-13T09:00:00+01:00",
|
|
111
|
+
"saving": null
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"price": 1.656,
|
|
115
|
+
"onOff": true,
|
|
116
|
+
"start": "2022-01-13T10:00:00+01:00",
|
|
117
|
+
"saving": null
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"price": 1.648,
|
|
121
|
+
"onOff": true,
|
|
122
|
+
"start": "2022-01-13T11:00:00+01:00",
|
|
123
|
+
"saving": null
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"price": 1.617,
|
|
127
|
+
"onOff": true,
|
|
128
|
+
"start": "2022-01-13T12:00:00+01:00",
|
|
129
|
+
"saving": null
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"price": 1.613,
|
|
133
|
+
"onOff": true,
|
|
134
|
+
"start": "2022-01-13T13:00:00+01:00",
|
|
135
|
+
"saving": null
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"price": 1.612,
|
|
139
|
+
"onOff": true,
|
|
140
|
+
"start": "2022-01-13T14:00:00+01:00",
|
|
141
|
+
"saving": null
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"price": 1.611,
|
|
145
|
+
"onOff": true,
|
|
146
|
+
"start": "2022-01-13T15:00:00+01:00",
|
|
147
|
+
"saving": null
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"price": 1.618,
|
|
151
|
+
"onOff": true,
|
|
152
|
+
"start": "2022-01-13T16:00:00+01:00",
|
|
153
|
+
"saving": null
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"price": 1.616,
|
|
157
|
+
"onOff": false,
|
|
158
|
+
"start": "2022-01-13T17:00:00+01:00",
|
|
159
|
+
"saving": 0.148
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"price": 1.617,
|
|
163
|
+
"onOff": false,
|
|
164
|
+
"start": "2022-01-13T18:00:00+01:00",
|
|
165
|
+
"saving": 0.149
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"price": 1.601,
|
|
169
|
+
"onOff": false,
|
|
170
|
+
"start": "2022-01-13T19:00:00+01:00",
|
|
171
|
+
"saving": 0.133
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"price": 1.568,
|
|
175
|
+
"onOff": false,
|
|
176
|
+
"start": "2022-01-13T20:00:00+01:00",
|
|
177
|
+
"saving": 0.1
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"price": 1.565,
|
|
181
|
+
"onOff": false,
|
|
182
|
+
"start": "2022-01-13T21:00:00+01:00",
|
|
183
|
+
"saving": 0.097
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"price": 1.506,
|
|
187
|
+
"onOff": false,
|
|
188
|
+
"start": "2022-01-13T22:00:00+01:00",
|
|
189
|
+
"saving": 0.038
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"price": 1.468,
|
|
193
|
+
"onOff": true,
|
|
194
|
+
"start": "2022-01-13T23:00:00+01:00",
|
|
195
|
+
"saving": null
|
|
196
|
+
}
|
|
197
|
+
],
|
|
198
|
+
"source": "Nordpool",
|
|
199
|
+
"config": {
|
|
200
|
+
"maxHoursToSaveInSequence": "6",
|
|
201
|
+
"minHoursOnAfterMaxSequenceSaved": "3",
|
|
202
|
+
"minSaving": 0.1,
|
|
203
|
+
"sendCurrentValueWhenRescheduling": true,
|
|
204
|
+
"outputIfNoSchedule": true
|
|
205
|
+
},
|
|
206
|
+
"time": "2022-01-12T17:29:33.411+01:00",
|
|
207
|
+
"version": "3.2.3"
|
|
208
|
+
}
|