node-red-contrib-power-saver 1.0.0 → 1.0.1
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
|
@@ -2,4 +2,156 @@
|
|
|
2
2
|
|
|
3
3
|
A Node-RED node to save money by turning off power when the power price is highest.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
You can use it to control for example a heater, a water heater or any other power consumer that is acceptable to turn off now and then.
|
|
8
|
+
|
|
9
|
+
The node takes power prices per hour as input, and sends output to turn a switch on or off based on the power price. It also outputs the schedule that is planned, as well as how much you save per kWh for each of the hours that are turned off, assuming that the same power is used as soon as the power is tuened on.
|
|
10
|
+
|
|
11
|
+
Power prices may be received from Tibber, Nordpool or any other source that gives price per hour for today and optionally tomorrow. It is primarily made to be used together with Home Assistant (HA), but there is no dependency to HA, so it can just as well be used by itself.
|
|
12
|
+
|
|
13
|
+
The node can also be used in combination with MagicMirror with the MMM-MQTT and MMM-Tibber modules, in order to get the savings displayed on the MM screen in the MMM-Tibber module:
|
|
14
|
+
|
|
15
|
+
NB! WIP
|
|
16
|
+
|
|
17
|
+
This node is currently very new, and has hardly been tried. Feel free to try it, and report back problems or ideas as Github issues.
|
|
18
|
+
|
|
19
|
+
## Input
|
|
20
|
+
|
|
21
|
+
3 different types of input are accepted:
|
|
22
|
+
|
|
23
|
+
* Tibber
|
|
24
|
+
* Nordpool
|
|
25
|
+
* Other sources in a specific JSON format
|
|
26
|
+
|
|
27
|
+
Choose the one that fits you best. Of course, all inputs are JSON, but the Tibber and Nordpool alternatives are designed to connect directly to those sources with a minimum effort.
|
|
28
|
+
|
|
29
|
+
### Tibber input
|
|
30
|
+
|
|
31
|
+
If you are a Tibber customer, you can use the `tibber-query` node from the [`node-red-contrib-tibber-api` node](https://flows.nodered.org/node/node-red-contrib-tibber-api). Set it up with the following query:
|
|
32
|
+
|
|
33
|
+
```gql
|
|
34
|
+
{
|
|
35
|
+
viewer {
|
|
36
|
+
homes {
|
|
37
|
+
currentSubscription{
|
|
38
|
+
priceInfo{
|
|
39
|
+
today {
|
|
40
|
+
total
|
|
41
|
+
startsAt
|
|
42
|
+
}
|
|
43
|
+
tomorrow {
|
|
44
|
+
total
|
|
45
|
+
startsAt
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Send the result from the `tibber-query` node with the query above directly to the `power-saver` node. Make sure it is refreshed when new prices are ready. Prices for the next day are normally ready at 13:00, but refreshing every hour can be a good idea.
|
|
55
|
+
|
|
56
|
+
### Nordpool input
|
|
57
|
+
|
|
58
|
+
This is especially designed to work for Home Assistant (HA), and the [Nordpool custom component](https://github.com/custom-components/nordpool). The Nordpool component provides a *sensor* that gives price per hour for today and tomorrow (after 13:00). Send the output from this sensor directly to the `power-saver` node. Make sure this is done whenever the node is updated, as well as when the system starts up.
|
|
59
|
+
|
|
60
|
+
NB! I myself have trouble with my Nordpool sensor in HA. It is not updating properly. Please give feedback how you experience this, preferably as Github issues.
|
|
61
|
+
|
|
62
|
+
### Other input
|
|
63
|
+
|
|
64
|
+
If you cannot use any of the two above (Tibber or Nordpool), create the input to the node with the payload containing JSON like this:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"today": [
|
|
69
|
+
{ "value": 1, "start": "2021-06-21T00:00:00+02:00" },
|
|
70
|
+
{ "value": 2, "start": "2021-06-21T01:00:00+02:00" },
|
|
71
|
+
...
|
|
72
|
+
],
|
|
73
|
+
"tomorrow": [
|
|
74
|
+
{ "value": 3, "start": "2021-06-22T00:00:00+02:00" },
|
|
75
|
+
{ "value": 4, "start": "2021-06-22T01:00:00+02:00" },
|
|
76
|
+
...
|
|
77
|
+
],
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Output
|
|
82
|
+
|
|
83
|
+
### Output 1
|
|
84
|
+
|
|
85
|
+
A payload with the word `true` is sent to output 1 whenever the power / switch shall be turned on.
|
|
86
|
+
|
|
87
|
+
### Output 2
|
|
88
|
+
|
|
89
|
+
A payload with the word `false` is sent to output 2 whenever the power / switch shall be turned off.
|
|
90
|
+
|
|
91
|
+
### Output 3
|
|
92
|
+
|
|
93
|
+
When a valid input is received, and the schedule is recalculated, the resulting schedule, as well as some other information, is sent to output 3. You can use this to see the plan and verify that it meets your expectations. You can also use it to display the schedule in any way you like.
|
|
94
|
+
|
|
95
|
+
Example of output:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"schedule": [
|
|
100
|
+
{
|
|
101
|
+
"time": "2021-09-30T00:00:00.000+02:00",
|
|
102
|
+
"value": false
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"time": "2021-09-30T01:00:00.000+02:00",
|
|
106
|
+
"value": true
|
|
107
|
+
},
|
|
108
|
+
...
|
|
109
|
+
],
|
|
110
|
+
"hours": [
|
|
111
|
+
{
|
|
112
|
+
"price": 1.2584,
|
|
113
|
+
"onOff": false,
|
|
114
|
+
"start": "2021-09-30T00:00:00.000+02:00",
|
|
115
|
+
"saving": 0.2034
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"price": 1.0550,
|
|
119
|
+
"onOff": true,
|
|
120
|
+
"start": "2021-09-30T01:00:00.000+02:00",
|
|
121
|
+
"saving": null
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"price": 1.2054,
|
|
125
|
+
"onOff": true,
|
|
126
|
+
"start": "2021-09-30T02:00:00.000+02:00",
|
|
127
|
+
"saving": null
|
|
128
|
+
},
|
|
129
|
+
...
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The `schedule` array shows every time the switch is turned on or off. The `hours` array shows values per hour containing the price (received as input), whether that hour is on or off, the start time of the hour and the amount per kWh that is saved on hours that are turned off, compared to the next hour that is on.
|
|
135
|
+
|
|
136
|
+
## Configuration
|
|
137
|
+
|
|
138
|
+
Currently there is only one strategy for saving. This is the *mostSaved* strategy. This strategy turns off the hours where the price difference is largest compared to the next hour that is on. The idea is that the power you are not using when the switch is turned off, will be used immediately when the switch is turned on. This would fit well for turning of a water heater or another thermostat controlled heater.
|
|
139
|
+
|
|
140
|
+
You can configure the following:
|
|
141
|
+
|
|
142
|
+
* Maximum number of hours to turn off during a day (24 hours).
|
|
143
|
+
* Maximum number of hours to turn off in a sequence.
|
|
144
|
+
* Minimum hours to turn on immediately after a period when turned off the maximum number of hours that is allowed to be turned off.
|
|
145
|
+
* Minimum amount to save per kWh in order to bother turning it off.
|
|
146
|
+
* What to do if there is no valid schedule any more (turn on or off).
|
|
147
|
+
|
|
148
|
+
## Integration with MagicMirror
|
|
149
|
+
|
|
150
|
+
Are you using [MagicMirror](https://magicmirror.builders/)? Are you also using [Tibber](https://tibber.com/)? If so, there is a module for MM called [MMM-Tibber](https://github.com/ottopaulsen/MMM-Tibber), that easily can be used to show savings from this node.
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+

|
|
154
|
+
|
|
155
|
+
The purple lines show savings.
|
|
156
|
+
|
|
157
|
+
Read more about this in the [MMM-Tibber documentation](https://github.com/ottopaulsen/MMM-Tibber#show-savings).
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-power-saver",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
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": {
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
},
|
|
9
9
|
"author": "Otto Paulsen <ottpau@gmail.com>",
|
|
10
10
|
"license": "MIT",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"node-red"
|
|
13
|
+
],
|
|
11
14
|
"node-red": {
|
|
12
15
|
"nodes": {
|
|
13
16
|
"power-saver": "power-saver.js"
|
package/power-saver.html
CHANGED
|
@@ -102,169 +102,170 @@
|
|
|
102
102
|
</script>
|
|
103
103
|
|
|
104
104
|
<script type="text/html" data-help-name="power-saver">
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
105
|
+
<p>A node you can use to save money by turning off and on a switch based on power prices.</p>
|
|
106
|
+
<p>You can use it to control for example a heater, a water heater or any other power consumer that is acceptable to turn off now and then.</p>
|
|
107
|
+
<p>It is designed to be used with Home Assistant, and to use the prices as produced by the <a href="https://github.com/custom-components/nordpool">nordpool</a> custom component, but can be used without as long as you can provide input in the correct format.</p>
|
|
108
|
+
<h3>Input</h3>
|
|
109
|
+
<dl class="message-properties">
|
|
110
|
+
<dt>payload
|
|
111
|
+
<span class="property-type">object</span>
|
|
112
|
+
</dt>
|
|
113
|
+
<dd>The payload should be an object with two arrays: <code>raw_today</code> and <code>raw_tomorrow</code>.
|
|
114
|
+
Each array shall contain one object per hour, with attributes start, end and value.
|
|
115
|
+
<br>
|
|
116
|
+
The <code>raw_today</code> and <code>raw_tomorrow</code> may alternatively be in the
|
|
117
|
+
<code>data.new_state.attributes</code> part of the message.
|
|
118
|
+
This is exactly what is delivered by the sensor given by the nordpool custom component,
|
|
119
|
+
so just put the output from that sensor to the input of this node.
|
|
120
|
+
</dd>
|
|
121
|
+
</dl>
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
123
|
+
<h3>Outputs</h3>
|
|
124
|
+
<ol class="node-ports">
|
|
125
|
+
<li>Output 1
|
|
126
|
+
<dl class="message-properties">
|
|
127
|
+
<dt>payload <span class="property-type">string</span></dt>
|
|
128
|
+
<dd>A payload containing <code>true</code> is sent to this output when the power shall be turned on.</dd>
|
|
129
|
+
</dl>
|
|
130
|
+
</li>
|
|
131
|
+
<li>Output 2
|
|
132
|
+
<dl class="message-properties">
|
|
133
|
+
<dt>payload <span class="property-type">string</span></dt>
|
|
134
|
+
<dd>A payload containing <code>false</code> is sent to this output when the power shall be turned off.</dd>
|
|
135
|
+
</dl>
|
|
136
|
+
</li>
|
|
137
|
+
<li>Output 3
|
|
138
|
+
<dl class="message-properties">
|
|
139
|
+
<dt>payload <span class="property-type">string</span></dt>
|
|
140
|
+
<dd>When the schedule is created or changed, a payload containing information about the schedule is sent to this output.</dd>
|
|
141
|
+
</dl>
|
|
142
|
+
</li>
|
|
143
|
+
</ol>
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
145
|
+
<h3>Details</h3>
|
|
146
|
+
<p>
|
|
147
|
+
Set up the Home Assistants <em>events: state</em> node to receive state changes on the nordpool sensor.
|
|
148
|
+
Example of entity id: <code>sensor.nordpool_kwh_trheim_nok_3_095_025</code>, but you must check what your sensor id is.
|
|
149
|
+
</p>
|
|
150
|
+
<p>
|
|
151
|
+
Connect the nordpool sensor output directly to the input on this node. Connect output 1 to a node that can turn the power switch on,
|
|
152
|
+
and output 2 to a node that can turn the power switch off. The values are true and false,
|
|
153
|
+
so they may be connected to the same node, and use the value to turn on or off.
|
|
154
|
+
</p>
|
|
155
|
+
<p>You may use output 3 to display the schedule.</p>
|
|
156
|
+
<p><strong>Input payload example</strong><br/>
|
|
157
|
+
<pre>
|
|
158
|
+
{
|
|
159
|
+
raw_today:[
|
|
160
|
+
{
|
|
161
|
+
start: "2021-06-20T00:00:00+02:00",
|
|
162
|
+
end: "2021-06-20T01:00:00+02:00",
|
|
163
|
+
value: 0.37,
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
start: "2021-06-20T01:00:00+02:00",
|
|
167
|
+
end: "2021-06-20T02:00:00+02:00",
|
|
168
|
+
value: 0.4,
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
start: "2021-06-20T02:00:00+02:00",
|
|
172
|
+
end: "2021-06-20T03:00:00+02:00",
|
|
173
|
+
value: 0.35,
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
start: "2021-06-20T03:00:00+02:00",
|
|
177
|
+
end: "2021-06-20T04:00:00+02:00",
|
|
178
|
+
value: 0.65,
|
|
179
|
+
},
|
|
180
|
+
// One entry per hour, 24 hours
|
|
181
|
+
],
|
|
182
|
+
raw_tomorrow: [
|
|
183
|
+
{
|
|
184
|
+
start: "2021-06-20T00:00:00+02:00",
|
|
185
|
+
end: "2021-06-21T01:00:00+02:00",
|
|
186
|
+
value: 1.5,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
start: "2021-06-21T01:00:00+02:00",
|
|
190
|
+
end: "2021-06-21T02:00:00+02:00",
|
|
191
|
+
value: 1.4,
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
start: "2021-06-21T02:00:00+02:00",
|
|
195
|
+
end: "2021-06-21T03:00:00+02:00",
|
|
196
|
+
value: 0.8,
|
|
197
|
+
},
|
|
198
|
+
// One entry per hour, 24 hours
|
|
199
|
+
],
|
|
200
|
+
};
|
|
201
|
+
</pre>
|
|
202
|
+
</p>
|
|
203
|
+
<p><strong>Output 3 payload example</strong><br/>
|
|
204
|
+
<pre>
|
|
205
205
|
{
|
|
206
206
|
"schedule": [
|
|
207
207
|
{
|
|
208
|
-
"time": "2021-09-
|
|
208
|
+
"time": "2021-09-30T00:00:00.000+02:00",
|
|
209
209
|
"value": false
|
|
210
210
|
},
|
|
211
211
|
{
|
|
212
|
-
"time": "2021-09-
|
|
212
|
+
"time": "2021-09-30T01:00:00.000+02:00",
|
|
213
213
|
"value": true
|
|
214
214
|
},
|
|
215
215
|
{
|
|
216
|
-
"time": "2021-09-
|
|
217
|
-
"value":
|
|
216
|
+
"time": "2021-09-30T02:00:00.000+02:00",
|
|
217
|
+
"value": true
|
|
218
218
|
},
|
|
219
|
-
|
|
219
|
+
...
|
|
220
220
|
],
|
|
221
221
|
"hours": [
|
|
222
222
|
{
|
|
223
|
-
"price":
|
|
224
|
-
"onOff":
|
|
223
|
+
"price": 1.2584,
|
|
224
|
+
"onOff": false,
|
|
225
225
|
"start": "2021-09-30T00:00:00.000+02:00",
|
|
226
|
-
"saving":
|
|
226
|
+
"saving": 0.2034
|
|
227
227
|
},
|
|
228
228
|
{
|
|
229
|
-
"price":
|
|
229
|
+
"price": 1.0550,
|
|
230
230
|
"onOff": true,
|
|
231
231
|
"start": "2021-09-30T01:00:00.000+02:00",
|
|
232
232
|
"saving": null
|
|
233
233
|
},
|
|
234
234
|
{
|
|
235
|
-
"price":
|
|
235
|
+
"price": 1.2054,
|
|
236
236
|
"onOff": true,
|
|
237
237
|
"start": "2021-09-30T02:00:00.000+02:00",
|
|
238
238
|
"saving": null
|
|
239
239
|
},
|
|
240
|
-
|
|
240
|
+
...
|
|
241
241
|
]
|
|
242
242
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
243
|
+
|
|
244
|
+
</pre>
|
|
245
|
+
</p>
|
|
246
|
+
<p>
|
|
247
|
+
The <code>value</code> in <code>schedule</code> is <code>true</code> to turn on and <code>false</code> to turn off.
|
|
248
|
+
</p>
|
|
249
|
+
<p>
|
|
250
|
+
The <code>savings</code> array shows the price per kWh saved that hour, only for hours that are turned off.
|
|
251
|
+
Hours that are turned on has <code>null</code> as saving.
|
|
252
|
+
</p>
|
|
253
|
+
<h3>Algorithm</h3>
|
|
254
|
+
<p>
|
|
255
|
+
Currently there is only one algorithm / strategy for saving power. It is the <strong>most saved</strong> strategy.
|
|
256
|
+
In this strategy it is assumed that when the power has been off for some time, the consumer will catch up by consuming
|
|
257
|
+
power as soon as the power is turned on again. Based on this assumption, the algorithm will turn off those hours
|
|
258
|
+
that has the highest difference between the hour that is off and the next hour that is on, and by this, turn off
|
|
259
|
+
the hours where it is most to save. This would be a good fit for turning off a heater controlled by a thermostat.
|
|
260
|
+
</p>
|
|
261
|
+
<p>
|
|
262
|
+
Other strategies are planned, but not yet implemented.
|
|
263
|
+
</p>
|
|
264
|
+
<h3>References</h3>
|
|
265
|
+
<ul>
|
|
266
|
+
<li><a href="https://github.com/ottopaulsen/node-red-contrib-power-saver">
|
|
267
|
+
node-red-contrib-power-saver</a> on GitHub</li>
|
|
268
|
+
<li>The <a href="https://github.com/custom-components/nordpool">
|
|
269
|
+
nordpool</a> custom component for Home Assistant</li>
|
|
270
|
+
</ul>
|
|
270
271
|
</script>
|