iobroker.tibberlink 4.2.2 → 4.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/README.md +70 -137
- package/admin/i18n/de/translations.json +3 -5
- package/admin/i18n/en/translations.json +2 -4
- package/admin/i18n/es/translations.json +3 -5
- package/admin/i18n/fr/translations.json +3 -5
- package/admin/i18n/it/translations.json +3 -5
- package/admin/i18n/nl/translations.json +3 -5
- package/admin/i18n/pl/translations.json +3 -5
- package/admin/i18n/pt/translations.json +3 -5
- package/admin/i18n/ru/translations.json +11 -13
- package/admin/i18n/uk/translations.json +7 -9
- package/admin/i18n/zh-cn/translations.json +6 -8
- package/admin/jsonConfig.json +19 -61
- package/build/lib/projectUtils.js +24 -59
- package/build/lib/projectUtils.js.map +1 -1
- package/build/lib/tibberAPICaller.js +6 -45
- package/build/lib/tibberAPICaller.js.map +1 -1
- package/build/lib/tibberCalculator.js +301 -85
- package/build/lib/tibberCalculator.js.map +1 -1
- package/build/lib/tibberCharts.js +15 -9
- package/build/lib/tibberCharts.js.map +1 -1
- package/io-package.json +294 -266
- package/package.json +8 -7
|
@@ -118,26 +118,24 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
118
118
|
| Output state: "Output", "OutputJSON"
|
|
119
119
|
"best hours block" | Input state: "AmountHours"
|
|
120
120
|
| Output state: "Output", "OutputJSON", "AverageTotalCost", "BlockStartFullHour", "BlockEndFullHour", "BlockStart", "BlockEnd"
|
|
121
|
-
"best cost LTF" | Input state: "TriggerPrice", "StartTime", "StopTime", "RepeatDays"
|
|
121
|
+
"best cost LTF" | Input state: "TriggerPrice", ["StartTime", "StopTime", "RepeatDays"]
|
|
122
122
|
| Output state: "Output", "OutputJSON"
|
|
123
|
-
"best single hours LTF" | Input state: "AmountHours", "StartTime", "StopTime", "RepeatDays"
|
|
123
|
+
"best single hours LTF" | Input state: "AmountHours", ["StartTime", "StopTime", "RepeatDays"]
|
|
124
124
|
| Output state: "Output", "OutputJSON"
|
|
125
|
-
"best hours block LTF" | Input state: "AmountHours", "StartTime", "StopTime", "RepeatDays"
|
|
125
|
+
"best hours block LTF" | Input state: "AmountHours", ["StartTime", "StopTime", "RepeatDays"]
|
|
126
126
|
| Output state: "Output", "OutputJSON", "AverageTotalCost", "BlockStartFullHour", "BlockEndFullHour", "BlockStart", "BlockEnd"
|
|
127
127
|
"smart battery buffer" | Input state: "AmountHours", "EfficiencyLoss"
|
|
128
|
-
| Output state: "Output", "Output2"
|
|
128
|
+
| Output state: "Output", "Output2", "OutputJSON", "OutputJSON2"
|
|
129
129
|
"best percentage" | Input state: "Percentage"
|
|
130
130
|
| Output state: "Output", "OutputJSON"
|
|
131
|
-
"best percentage LTF" | Input state: "Percentage", "StartTime", "StopTime", "RepeatDays"
|
|
131
|
+
"best percentage LTF" | Input state: "Percentage", ["StartTime", "StopTime", "RepeatDays"]
|
|
132
132
|
| Output state: "Output", "OutputJSON"
|
|
133
133
|
*/
|
|
134
134
|
switch (channelConfig.chType) {
|
|
135
135
|
case projectUtils_1.enCalcType.BestCost:
|
|
136
|
-
await this.
|
|
137
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.
|
|
138
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StopTime`);
|
|
136
|
+
await this.deleteLTFInputs(homeId, channel); // INPUTS
|
|
137
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.AmountHours`);
|
|
139
138
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.EfficiencyLoss`);
|
|
140
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.RepeatDays`);
|
|
141
139
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.AverageTotalCost`);
|
|
142
140
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStartTime`);
|
|
143
141
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStopTime`);
|
|
@@ -146,15 +144,14 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
146
144
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Percentage`);
|
|
147
145
|
await this.setup_chTriggerPrice(homeId, channel);
|
|
148
146
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Output2`); // OUTPUTS
|
|
147
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.OutputJSON2`);
|
|
149
148
|
await this.setup_chOutput(homeId, channel);
|
|
150
149
|
this.setup_chOutputJSON(homeId, channel);
|
|
151
150
|
break;
|
|
152
151
|
case projectUtils_1.enCalcType.BestSingleHours:
|
|
153
|
-
await this.
|
|
154
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.
|
|
155
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StopTime`);
|
|
152
|
+
await this.deleteLTFInputs(homeId, channel); // INPUTS
|
|
153
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.TriggerPrice`);
|
|
156
154
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.EfficiencyLoss`);
|
|
157
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.RepeatDays`);
|
|
158
155
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.AverageTotalCost`);
|
|
159
156
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStartTime`);
|
|
160
157
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStopTime`);
|
|
@@ -163,15 +160,14 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
163
160
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Percentage`);
|
|
164
161
|
await this.setup_chAmountHours(homeId, channel);
|
|
165
162
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Output2`); // OUTPUTS
|
|
163
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.OutputJSON2`);
|
|
166
164
|
await this.setup_chOutput(homeId, channel);
|
|
167
165
|
this.setup_chOutputJSON(homeId, channel);
|
|
168
166
|
break;
|
|
169
167
|
case projectUtils_1.enCalcType.BestHoursBlock:
|
|
170
|
-
await this.
|
|
171
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.
|
|
172
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StopTime`);
|
|
168
|
+
await this.deleteLTFInputs(homeId, channel); // INPUTS
|
|
169
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.TriggerPrice`);
|
|
173
170
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.EfficiencyLoss`);
|
|
174
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.RepeatDays`);
|
|
175
171
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Percentage`);
|
|
176
172
|
await this.setup_chAmountHours(homeId, channel);
|
|
177
173
|
this.setup_chAverageTotalCost(homeId, channel);
|
|
@@ -180,6 +176,7 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
180
176
|
this.setup_chBlockStart(homeId, channel);
|
|
181
177
|
this.setup_chBlockEnd(homeId, channel);
|
|
182
178
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Output2`); // OUTPUTS
|
|
179
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.OutputJSON2`);
|
|
183
180
|
await this.setup_chOutput(homeId, channel);
|
|
184
181
|
this.setup_chOutputJSON(homeId, channel);
|
|
185
182
|
break;
|
|
@@ -189,11 +186,11 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
189
186
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.AverageTotalCost`);
|
|
190
187
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStartTime`);
|
|
191
188
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStopTime`);
|
|
189
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Percentage`);
|
|
190
|
+
await this.setupLTFInputs(homeId, channel);
|
|
192
191
|
await this.setup_chTriggerPrice(homeId, channel);
|
|
193
|
-
await this.setup_chStartTime(homeId, channel);
|
|
194
|
-
await this.setup_chStopTime(homeId, channel);
|
|
195
|
-
await this.setup_chRepeatDays(homeId, channel);
|
|
196
192
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Output2`); // OUTPUTS
|
|
193
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.OutputJSON2`);
|
|
197
194
|
await this.setup_chOutput(homeId, channel);
|
|
198
195
|
this.setup_chOutputJSON(homeId, channel);
|
|
199
196
|
break;
|
|
@@ -204,11 +201,10 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
204
201
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStartTime`);
|
|
205
202
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStopTime`);
|
|
206
203
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Percentage`);
|
|
204
|
+
await this.setupLTFInputs(homeId, channel);
|
|
207
205
|
await this.setup_chAmountHours(homeId, channel);
|
|
208
|
-
await this.setup_chStartTime(homeId, channel);
|
|
209
|
-
await this.setup_chStopTime(homeId, channel);
|
|
210
|
-
await this.setup_chRepeatDays(homeId, channel);
|
|
211
206
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Output2`); // OUTPUTS
|
|
207
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.OutputJSON2`);
|
|
212
208
|
await this.setup_chOutput(homeId, channel);
|
|
213
209
|
this.setup_chOutputJSON(homeId, channel);
|
|
214
210
|
break;
|
|
@@ -216,24 +212,21 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
216
212
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.TriggerPrice`); // INPUTS
|
|
217
213
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.EfficiencyLoss`);
|
|
218
214
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Percentage`);
|
|
215
|
+
await this.setupLTFInputs(homeId, channel);
|
|
219
216
|
await this.setup_chAmountHours(homeId, channel);
|
|
220
|
-
await this.setup_chStartTime(homeId, channel);
|
|
221
|
-
await this.setup_chStopTime(homeId, channel);
|
|
222
|
-
await this.setup_chRepeatDays(homeId, channel);
|
|
223
217
|
this.setup_chAverageTotalCost(homeId, channel);
|
|
224
218
|
this.setup_chBlockStartFullHour(homeId, channel);
|
|
225
219
|
this.setup_chBlockEndFullHour(homeId, channel);
|
|
226
220
|
this.setup_chBlockStart(homeId, channel);
|
|
227
221
|
this.setup_chBlockEnd(homeId, channel);
|
|
228
222
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Output2`); // OUTPUTS
|
|
223
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.OutputJSON2`);
|
|
229
224
|
await this.setup_chOutput(homeId, channel);
|
|
230
225
|
this.setup_chOutputJSON(homeId, channel);
|
|
231
226
|
break;
|
|
232
227
|
case projectUtils_1.enCalcType.SmartBatteryBuffer:
|
|
233
|
-
await this.
|
|
234
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.
|
|
235
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StopTime`);
|
|
236
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.RepeatDays`);
|
|
228
|
+
await this.deleteLTFInputs(homeId, channel); // INPUTS
|
|
229
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.TriggerPrice`);
|
|
237
230
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.AverageTotalCost`);
|
|
238
231
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStartTime`);
|
|
239
232
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStopTime`);
|
|
@@ -243,16 +236,15 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
243
236
|
await this.setup_chAmountHours(homeId, channel);
|
|
244
237
|
await this.setup_chEfficiencyLoss(homeId, channel);
|
|
245
238
|
await this.setup_chOutput(homeId, channel); // OUTPUTS
|
|
246
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.OutputJSON`);
|
|
247
239
|
await this.setup_chOutput2(homeId, channel);
|
|
240
|
+
this.setup_chOutputJSON(homeId, channel);
|
|
241
|
+
this.setup_chOutputJSON2(homeId, channel);
|
|
248
242
|
break;
|
|
249
243
|
case projectUtils_1.enCalcType.BestPercentage:
|
|
250
|
-
await this.
|
|
244
|
+
await this.deleteLTFInputs(homeId, channel); // INPUTS
|
|
245
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.AmountHours`);
|
|
251
246
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.TriggerPrice`);
|
|
252
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StartTime`);
|
|
253
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StopTime`);
|
|
254
247
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.EfficiencyLoss`);
|
|
255
|
-
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.RepeatDays`);
|
|
256
248
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.AverageTotalCost`);
|
|
257
249
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStartTime`);
|
|
258
250
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStopTime`);
|
|
@@ -260,6 +252,7 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
260
252
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStop`);
|
|
261
253
|
await this.setup_chPercentage(homeId, channel);
|
|
262
254
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Output2`); // OUTPUTS
|
|
255
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.OutputJSON2`);
|
|
263
256
|
await this.setup_chOutput(homeId, channel);
|
|
264
257
|
this.setup_chOutputJSON(homeId, channel);
|
|
265
258
|
break;
|
|
@@ -270,11 +263,10 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
270
263
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.AverageTotalCost`);
|
|
271
264
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStartTime`);
|
|
272
265
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.BlockStopTime`);
|
|
273
|
-
await this.
|
|
274
|
-
await this.setup_chStopTime(homeId, channel);
|
|
275
|
-
await this.setup_chRepeatDays(homeId, channel);
|
|
266
|
+
await this.setupLTFInputs(homeId, channel);
|
|
276
267
|
await this.setup_chPercentage(homeId, channel);
|
|
277
268
|
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.Output2`); // OUTPUTS
|
|
269
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.OutputJSON2`);
|
|
278
270
|
await this.setup_chOutput(homeId, channel);
|
|
279
271
|
this.setup_chOutputJSON(homeId, channel);
|
|
280
272
|
break;
|
|
@@ -298,6 +290,72 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
298
290
|
this.adapter.log.warn(this.generateErrorMessage(error, `setup of states for calculator`));
|
|
299
291
|
}
|
|
300
292
|
}
|
|
293
|
+
async setupLTFInputs(homeId, channel) {
|
|
294
|
+
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
295
|
+
try {
|
|
296
|
+
//*** chStartTime ***
|
|
297
|
+
if (channelConfig.chStartTime === undefined) {
|
|
298
|
+
const today = new Date();
|
|
299
|
+
today.setHours(0, 0, 0, 0); // sets clock to 0:00
|
|
300
|
+
channelConfig.chStartTime = today;
|
|
301
|
+
}
|
|
302
|
+
void this.checkAndSetValue(`Homes.${homeId}.Calculations.${channel}.StartTime`, channelConfig.chStartTime.toISOString(), `Start time for this channel`, `date`, true, true);
|
|
303
|
+
const valueStartTime = await this.getStateValue(`Homes.${homeId}.Calculations.${channel}.StartTime`);
|
|
304
|
+
if (typeof valueStartTime === "string") {
|
|
305
|
+
channelConfig.chStartTime.setTime(Date.parse(valueStartTime));
|
|
306
|
+
this.adapter.log.debug(`setup calculator settings state in home: ${homeId} - channel: ${channel}-${channelConfig.chName} - set to StartTime: ${channelConfig.chStartTime.toISOString()}`);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
this.adapter.log.debug(`Wrong type for chStartTime: ${valueStartTime}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
this.adapter.log.warn(this.generateErrorMessage(error, `setup of state StartTime for calculator`));
|
|
314
|
+
}
|
|
315
|
+
try {
|
|
316
|
+
//*** chStopTime ***
|
|
317
|
+
if (channelConfig.chStopTime === undefined) {
|
|
318
|
+
const today = new Date();
|
|
319
|
+
today.setHours(23, 59, 0, 0); // sets clock to 0:00
|
|
320
|
+
channelConfig.chStopTime = today;
|
|
321
|
+
}
|
|
322
|
+
void this.checkAndSetValue(`Homes.${homeId}.Calculations.${channel}.StopTime`, channelConfig.chStopTime.toISOString(), `Stop time for this channel`, `date`, true, true);
|
|
323
|
+
const valueStopTime = await this.getStateValue(`Homes.${homeId}.Calculations.${channel}.StopTime`);
|
|
324
|
+
if (typeof valueStopTime === "string") {
|
|
325
|
+
channelConfig.chStopTime.setTime(Date.parse(valueStopTime));
|
|
326
|
+
this.adapter.log.debug(`setup calculator settings state in home: ${homeId} - channel: ${channel}-${channelConfig.chName} - set to StopTime: ${channelConfig.chStopTime.toISOString()}`);
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
this.adapter.log.debug(`Wrong type for chStopTime: ${valueStopTime}`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
catch (error) {
|
|
333
|
+
this.adapter.log.warn(this.generateErrorMessage(error, `setup of state StopTime for calculator`));
|
|
334
|
+
}
|
|
335
|
+
try {
|
|
336
|
+
//*** chRepeatDays ***
|
|
337
|
+
if (channelConfig.chRepeatDays === undefined) {
|
|
338
|
+
channelConfig.chRepeatDays = 0;
|
|
339
|
+
}
|
|
340
|
+
void this.checkAndSetValueNumber(`Homes.${homeId}.Calculations.${channel}.RepeatDays`, channelConfig.chRepeatDays, `number of days to shift this LTF channel for repetition`, undefined, `level`, true, true);
|
|
341
|
+
const valueRepeatDays = await this.getStateValue(`Homes.${homeId}.Calculations.${channel}.RepeatDays`);
|
|
342
|
+
if (typeof valueRepeatDays === "number") {
|
|
343
|
+
channelConfig.chRepeatDays = valueRepeatDays;
|
|
344
|
+
this.adapter.log.debug(`setup calculator settings state in home: ${homeId} - channel: ${channel}-${channelConfig.chName} - set to RepeatDays: ${channelConfig.chRepeatDays}`);
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
this.adapter.log.debug(`Wrong type for chTriggerPrice: ${valueRepeatDays}`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
this.adapter.log.warn(this.generateErrorMessage(error, `setup of state RepeatDays for calculator`));
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
async deleteLTFInputs(homeId, channel) {
|
|
355
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StartTime`);
|
|
356
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StopTime`);
|
|
357
|
+
await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.RepeatDays`);
|
|
358
|
+
}
|
|
301
359
|
async setup_chOutput(homeId, channel) {
|
|
302
360
|
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
303
361
|
if (channelConfig?.chTargetState && channelConfig.chTargetState.length > 10 && !channelConfig.chTargetState.startsWith("choose your state to drive")) {
|
|
@@ -340,6 +398,18 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
340
398
|
this.adapter.log.warn(this.generateErrorMessage(error, `write state OutputJSON for calculator in Home ${homeId}, Channel ${channel}`));
|
|
341
399
|
}
|
|
342
400
|
}
|
|
401
|
+
setup_chOutputJSON2(homeId, channel, delMode = false) {
|
|
402
|
+
try {
|
|
403
|
+
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
404
|
+
void this.checkAndSetValue(`Homes.${homeId}.Calculations.${channel}.OutputJSON2`, `[]`, `JSON output 2 to see the schedule the channel will follow`, `json`, false, true);
|
|
405
|
+
if (!delMode) {
|
|
406
|
+
this.adapter.log.debug(`setup calculator output state OutputJSON2 in home: ${homeId} - channel: ${channel}-${channelConfig.chName}`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
catch (error) {
|
|
410
|
+
this.adapter.log.warn(this.generateErrorMessage(error, `write state OutputJSON2 for calculator in Home ${homeId}, Channel ${channel}`));
|
|
411
|
+
}
|
|
412
|
+
}
|
|
343
413
|
async setup_chTriggerPrice(homeId, channel) {
|
|
344
414
|
try {
|
|
345
415
|
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
@@ -402,7 +472,8 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
402
472
|
this.adapter.log.warn(this.generateErrorMessage(error, `setup of state Percentage for calculator`));
|
|
403
473
|
}
|
|
404
474
|
}
|
|
405
|
-
|
|
475
|
+
/* WIP DELETE
|
|
476
|
+
private async setup_chStartTime(homeId: string, channel: number): Promise<void> {
|
|
406
477
|
try {
|
|
407
478
|
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
408
479
|
//*** chStartTime ***
|
|
@@ -411,21 +482,28 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
411
482
|
today.setHours(0, 0, 0, 0); // sets clock to 0:00
|
|
412
483
|
channelConfig.chStartTime = today;
|
|
413
484
|
}
|
|
414
|
-
void this.checkAndSetValue(
|
|
485
|
+
void this.checkAndSetValue(
|
|
486
|
+
`Homes.${homeId}.Calculations.${channel}.StartTime`,
|
|
487
|
+
channelConfig.chStartTime.toISOString(),
|
|
488
|
+
`Start time for this channel`,
|
|
489
|
+
`date`,
|
|
490
|
+
true,
|
|
491
|
+
true,
|
|
492
|
+
);
|
|
415
493
|
const valueStartTime = await this.getStateValue(`Homes.${homeId}.Calculations.${channel}.StartTime`);
|
|
416
494
|
if (typeof valueStartTime === "string") {
|
|
417
495
|
channelConfig.chStartTime.setTime(Date.parse(valueStartTime));
|
|
418
|
-
this.adapter.log.debug(
|
|
419
|
-
|
|
420
|
-
|
|
496
|
+
this.adapter.log.debug(
|
|
497
|
+
`setup calculator settings state in home: ${homeId} - channel: ${channel}-${channelConfig.chName} - set to StartTime: ${channelConfig.chStartTime.toISOString()}`,
|
|
498
|
+
);
|
|
499
|
+
} else {
|
|
421
500
|
this.adapter.log.debug(`Wrong type for chStartTime: ${valueStartTime}`);
|
|
422
501
|
}
|
|
423
|
-
}
|
|
424
|
-
catch (error) {
|
|
502
|
+
} catch (error) {
|
|
425
503
|
this.adapter.log.warn(this.generateErrorMessage(error, `setup of state StartTime for calculator`));
|
|
426
504
|
}
|
|
427
505
|
}
|
|
428
|
-
async setup_chStopTime(homeId, channel) {
|
|
506
|
+
private async setup_chStopTime(homeId: string, channel: number): Promise<void> {
|
|
429
507
|
try {
|
|
430
508
|
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
431
509
|
//*** chStopTime ***
|
|
@@ -434,41 +512,57 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
434
512
|
today.setHours(23, 59, 0, 0); // sets clock to 0:00
|
|
435
513
|
channelConfig.chStopTime = today;
|
|
436
514
|
}
|
|
437
|
-
void this.checkAndSetValue(
|
|
515
|
+
void this.checkAndSetValue(
|
|
516
|
+
`Homes.${homeId}.Calculations.${channel}.StopTime`,
|
|
517
|
+
channelConfig.chStopTime.toISOString(),
|
|
518
|
+
`Stop time for this channel`,
|
|
519
|
+
`date`,
|
|
520
|
+
true,
|
|
521
|
+
true,
|
|
522
|
+
);
|
|
438
523
|
const valueStopTime = await this.getStateValue(`Homes.${homeId}.Calculations.${channel}.StopTime`);
|
|
439
524
|
if (typeof valueStopTime === "string") {
|
|
440
525
|
channelConfig.chStopTime.setTime(Date.parse(valueStopTime));
|
|
441
|
-
this.adapter.log.debug(
|
|
442
|
-
|
|
443
|
-
|
|
526
|
+
this.adapter.log.debug(
|
|
527
|
+
`setup calculator settings state in home: ${homeId} - channel: ${channel}-${channelConfig.chName} - set to StopTime: ${channelConfig.chStopTime.toISOString()}`,
|
|
528
|
+
);
|
|
529
|
+
} else {
|
|
444
530
|
this.adapter.log.debug(`Wrong type for chStopTime: ${valueStopTime}`);
|
|
445
531
|
}
|
|
446
|
-
}
|
|
447
|
-
catch (error) {
|
|
532
|
+
} catch (error) {
|
|
448
533
|
this.adapter.log.warn(this.generateErrorMessage(error, `setup of state StopTime for calculator`));
|
|
449
534
|
}
|
|
450
535
|
}
|
|
451
|
-
async setup_chRepeatDays(homeId, channel) {
|
|
536
|
+
private async setup_chRepeatDays(homeId: string, channel: number): Promise<void> {
|
|
452
537
|
try {
|
|
453
538
|
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
454
539
|
//*** chRepeatDays ***
|
|
455
540
|
if (channelConfig.chRepeatDays === undefined) {
|
|
456
541
|
channelConfig.chRepeatDays = 0;
|
|
457
542
|
}
|
|
458
|
-
void this.checkAndSetValueNumber(
|
|
543
|
+
void this.checkAndSetValueNumber(
|
|
544
|
+
`Homes.${homeId}.Calculations.${channel}.RepeatDays`,
|
|
545
|
+
channelConfig.chRepeatDays,
|
|
546
|
+
`number of days to shift this LTF channel for repetition`,
|
|
547
|
+
undefined,
|
|
548
|
+
`level`,
|
|
549
|
+
true,
|
|
550
|
+
true,
|
|
551
|
+
);
|
|
459
552
|
const valueRepeatDays = await this.getStateValue(`Homes.${homeId}.Calculations.${channel}.RepeatDays`);
|
|
460
553
|
if (typeof valueRepeatDays === "number") {
|
|
461
554
|
channelConfig.chRepeatDays = valueRepeatDays;
|
|
462
|
-
this.adapter.log.debug(
|
|
463
|
-
|
|
464
|
-
|
|
555
|
+
this.adapter.log.debug(
|
|
556
|
+
`setup calculator settings state in home: ${homeId} - channel: ${channel}-${channelConfig.chName} - set to RepeatDays: ${channelConfig.chRepeatDays}`,
|
|
557
|
+
);
|
|
558
|
+
} else {
|
|
465
559
|
this.adapter.log.debug(`Wrong type for chTriggerPrice: ${valueRepeatDays}`);
|
|
466
560
|
}
|
|
467
|
-
}
|
|
468
|
-
catch (error) {
|
|
561
|
+
} catch (error) {
|
|
469
562
|
this.adapter.log.warn(this.generateErrorMessage(error, `setup of state RepeatDays for calculator`));
|
|
470
563
|
}
|
|
471
564
|
}
|
|
565
|
+
*/
|
|
472
566
|
async setup_chEfficiencyLoss(homeId, channel) {
|
|
473
567
|
try {
|
|
474
568
|
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
@@ -687,16 +781,28 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
687
781
|
}
|
|
688
782
|
}
|
|
689
783
|
async executeCalculatorBestCost(channel, modeLTF = false) {
|
|
784
|
+
const now = new Date();
|
|
785
|
+
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
786
|
+
let valueToSet = channelConfig.chValueOff;
|
|
690
787
|
try {
|
|
691
|
-
const now = new Date();
|
|
692
|
-
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
693
|
-
let valueToSet = channelConfig.chValueOff;
|
|
694
788
|
if (!channelConfig.chActive) {
|
|
695
789
|
// not active
|
|
696
790
|
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, `[]`, true);
|
|
697
791
|
}
|
|
698
792
|
else if (modeLTF && now < channelConfig.chStartTime) {
|
|
699
793
|
// chActive but before LTF
|
|
794
|
+
const filteredPrices = await this.getPricesLTF(channel, modeLTF, true);
|
|
795
|
+
//#region *** Mark the entries with the result and create JSON output ***
|
|
796
|
+
const jsonOutput = filteredPrices
|
|
797
|
+
.map((entry) => ({
|
|
798
|
+
hour: new Date(entry.startsAt).getHours(), // extract the hour from startsAt
|
|
799
|
+
startsAt: entry.startsAt,
|
|
800
|
+
total: entry.total,
|
|
801
|
+
output: channelConfig.chTriggerPrice > entry.total ? true : false, // mark all cheap hours
|
|
802
|
+
}))
|
|
803
|
+
.sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime()); // Sort by startsAt
|
|
804
|
+
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, JSON.stringify(jsonOutput, null, 2), true);
|
|
805
|
+
//#endregion
|
|
700
806
|
}
|
|
701
807
|
else if (modeLTF && now > channelConfig.chStopTime) {
|
|
702
808
|
// chActive but after LTF
|
|
@@ -727,20 +833,38 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
727
833
|
this.setChannelOutStates(channel, valueToSet);
|
|
728
834
|
}
|
|
729
835
|
catch (error) {
|
|
730
|
-
this.adapter.log.warn(this.generateErrorMessage(error, `execute calculator for
|
|
836
|
+
this.adapter.log.warn(this.generateErrorMessage(error, `execute calculator for ${(0, projectUtils_1.getCalcTypeDescription)(channelConfig.chType)} in channel ${channel}`));
|
|
731
837
|
}
|
|
732
838
|
}
|
|
733
839
|
async executeCalculatorBestSingleHours(channel, modeLTF = false) {
|
|
840
|
+
const now = new Date();
|
|
841
|
+
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
842
|
+
let valueToSet = channelConfig.chValueOff;
|
|
734
843
|
try {
|
|
735
|
-
const now = new Date();
|
|
736
|
-
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
737
|
-
let valueToSet = channelConfig.chValueOff;
|
|
738
844
|
if (!channelConfig.chActive) {
|
|
739
845
|
// not active -> choose chValueOff
|
|
740
846
|
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, `[]`, true);
|
|
741
847
|
}
|
|
742
848
|
else if (modeLTF && now < channelConfig.chStartTime) {
|
|
743
849
|
// chActive but before LTF -> choose chValueOff
|
|
850
|
+
const filteredPrices = await this.getPricesLTF(channel, modeLTF);
|
|
851
|
+
//#region *** Find channel result ***
|
|
852
|
+
// sort by total cost
|
|
853
|
+
filteredPrices.sort((a, b) => a.total - b.total);
|
|
854
|
+
// get first chAmountHours entries und test for matching hour
|
|
855
|
+
const channelResult = filteredPrices.slice(0, channelConfig.chAmountHours).map((entry) => checkHourMatch(entry));
|
|
856
|
+
//#endregion
|
|
857
|
+
//#region *** Mark the entries with the result and create JSON output ***
|
|
858
|
+
const jsonOutput = filteredPrices
|
|
859
|
+
.map((entry, index) => ({
|
|
860
|
+
hour: new Date(entry.startsAt).getHours(), // extract the hour from startsAt
|
|
861
|
+
startsAt: entry.startsAt,
|
|
862
|
+
total: entry.total,
|
|
863
|
+
output: channelResult[index] !== undefined ? true : false, // Check if channelResult[index] is defined
|
|
864
|
+
}))
|
|
865
|
+
.sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime()); // Sort by startsAt
|
|
866
|
+
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, JSON.stringify(jsonOutput, null, 2), true);
|
|
867
|
+
//#endregion
|
|
744
868
|
}
|
|
745
869
|
else if (modeLTF && now > channelConfig.chStopTime) {
|
|
746
870
|
// chActive but after LTF -> choose chValueOff and disable channel or generate new running period
|
|
@@ -775,14 +899,14 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
775
899
|
this.setChannelOutStates(channel, valueToSet);
|
|
776
900
|
}
|
|
777
901
|
catch (error) {
|
|
778
|
-
this.adapter.log.warn(this.generateErrorMessage(error, `execute calculator for
|
|
902
|
+
this.adapter.log.warn(this.generateErrorMessage(error, `execute calculator for ${(0, projectUtils_1.getCalcTypeDescription)(channelConfig.chType)} in channel ${channel}`));
|
|
779
903
|
}
|
|
780
904
|
}
|
|
781
905
|
async executeCalculatorBestHoursBlock(channel, modeLTF = false) {
|
|
906
|
+
const now = new Date();
|
|
907
|
+
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
908
|
+
let valueToSet = channelConfig.chValueOff;
|
|
782
909
|
try {
|
|
783
|
-
const now = new Date();
|
|
784
|
-
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
785
|
-
let valueToSet = channelConfig.chValueOff;
|
|
786
910
|
if (!channelConfig.chActive) {
|
|
787
911
|
// not active -> choose chValueOff
|
|
788
912
|
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, `[]`, true);
|
|
@@ -797,6 +921,34 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
797
921
|
this.setup_chBlockEndFullHour(channelConfig.chHomeID, channel, true);
|
|
798
922
|
this.setup_chBlockStart(channelConfig.chHomeID, channel, true);
|
|
799
923
|
this.setup_chBlockEnd(channelConfig.chHomeID, channel, true);
|
|
924
|
+
const filteredPrices = await this.getPricesLTF(channel, modeLTF);
|
|
925
|
+
//#region *** Find channel result ***
|
|
926
|
+
let minSum = Number.MAX_VALUE;
|
|
927
|
+
let startIndex = 0;
|
|
928
|
+
const n = Math.min(channelConfig.chAmountHours, filteredPrices.length);
|
|
929
|
+
for (let i = 0; i < filteredPrices.length - n + 1; i++) {
|
|
930
|
+
let sum = 0;
|
|
931
|
+
for (let j = i; j < i + n; j++) {
|
|
932
|
+
sum += filteredPrices[j].total;
|
|
933
|
+
}
|
|
934
|
+
if (sum < minSum) {
|
|
935
|
+
minSum = sum;
|
|
936
|
+
startIndex = i;
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
const channelResult = filteredPrices.slice(startIndex, startIndex + n).map((entry) => checkHourMatch(entry));
|
|
940
|
+
//#endregion
|
|
941
|
+
//#region *** Mark the entries with the result and create JSON output ***
|
|
942
|
+
const jsonOutput = filteredPrices
|
|
943
|
+
.map((entry, index) => ({
|
|
944
|
+
hour: new Date(entry.startsAt).getHours(), // extract the hour from startsAt
|
|
945
|
+
startsAt: entry.startsAt,
|
|
946
|
+
total: entry.total,
|
|
947
|
+
output: channelResult[index - startIndex] !== undefined ? true : false, // Check if channelResult[index] is defined
|
|
948
|
+
}))
|
|
949
|
+
.sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime()); // Sort by startsAt
|
|
950
|
+
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, JSON.stringify(jsonOutput, null, 2), true);
|
|
951
|
+
//#endregion
|
|
800
952
|
}
|
|
801
953
|
else if (modeLTF && now > channelConfig.chStopTime) {
|
|
802
954
|
// chActive but after LTF -> choose chValueOff and disable channel or generate new running period
|
|
@@ -830,7 +982,7 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
830
982
|
valueToSet = channelConfig.chValueOn;
|
|
831
983
|
}
|
|
832
984
|
//#endregion
|
|
833
|
-
|
|
985
|
+
//#region *** Mark the entries with the result and create JSON output ***
|
|
834
986
|
const jsonOutput = filteredPrices
|
|
835
987
|
.map((entry, index) => ({
|
|
836
988
|
hour: new Date(entry.startsAt).getHours(), // extract the hour from startsAt
|
|
@@ -840,6 +992,7 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
840
992
|
}))
|
|
841
993
|
.sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime()); // Sort by startsAt
|
|
842
994
|
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, JSON.stringify(jsonOutput, null, 2), true);
|
|
995
|
+
//#endregion
|
|
843
996
|
// calculate average cost of determined block of hours, write to data point
|
|
844
997
|
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.AverageTotalCost`, Math.round(1000 * (minSum / n)) / 1000, true);
|
|
845
998
|
//#region *** Write start and stop time of determined block to data points ***
|
|
@@ -854,7 +1007,7 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
854
1007
|
this.setChannelOutStates(channel, valueToSet);
|
|
855
1008
|
}
|
|
856
1009
|
catch (error) {
|
|
857
|
-
this.adapter.log.warn(this.generateErrorMessage(error, `execute calculator for
|
|
1010
|
+
this.adapter.log.warn(this.generateErrorMessage(error, `execute calculator for ${(0, projectUtils_1.getCalcTypeDescription)(channelConfig.chType)} in channel ${channel}`));
|
|
858
1011
|
}
|
|
859
1012
|
}
|
|
860
1013
|
async executeCalculatorSmartBatteryBuffer(channel) {
|
|
@@ -888,25 +1041,28 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
888
1041
|
- Expensive Hours - disable battery charging (OFF-1) and enable feed into home energy system (ON-2)
|
|
889
1042
|
*/
|
|
890
1043
|
//#endregion
|
|
1044
|
+
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
1045
|
+
let valueToSet = channelConfig.chValueOff;
|
|
1046
|
+
let valueToSet2 = channelConfig.chValueOff2;
|
|
891
1047
|
try {
|
|
892
|
-
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
893
|
-
let valueToSet = channelConfig.chValueOff;
|
|
894
|
-
let valueToSet2 = channelConfig.chValueOff2;
|
|
895
1048
|
if (!channelConfig.chActive) {
|
|
896
|
-
// Not Active - disable battery charging (OFF-1) and also disable feed into home energy system (OFF-2)
|
|
1049
|
+
// Not Active - disable battery charging (OFF-1) and also disable feed into home energy system (OFF-2) - not by channel!!
|
|
1050
|
+
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, `[]`, true);
|
|
1051
|
+
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON2`, `[]`, true);
|
|
897
1052
|
}
|
|
898
1053
|
else {
|
|
899
1054
|
// chActive -> choose desired values
|
|
900
1055
|
const pricesToday = JSON.parse(await this.getStateValue(`Homes.${channelConfig.chHomeID}.PricesToday.json`));
|
|
901
1056
|
const maxCheapCount = await this.getStateValue(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.AmountHours`);
|
|
902
1057
|
const efficiencyLoss = await this.getStateValue(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.EfficiencyLoss`);
|
|
903
|
-
// sort by total price
|
|
904
|
-
pricesToday.sort((a, b) => a.total - b.total);
|
|
905
1058
|
const cheapHours = [];
|
|
906
1059
|
const normalHours = [];
|
|
907
1060
|
const expensiveHours = [];
|
|
908
1061
|
let cheapIndex = 0;
|
|
909
1062
|
let minDelta = 0;
|
|
1063
|
+
//#region *** Find channel result ***
|
|
1064
|
+
// sort by total price
|
|
1065
|
+
pricesToday.sort((a, b) => a.total - b.total);
|
|
910
1066
|
while (cheapIndex < pricesToday.length && cheapHours.length < maxCheapCount) {
|
|
911
1067
|
const currentHour = pricesToday[cheapIndex];
|
|
912
1068
|
if (currentHour.total < pricesToday[pricesToday.length - 1].total - minDelta) {
|
|
@@ -935,6 +1091,7 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
935
1091
|
const resultCheap = cheapHours.map((entry) => checkHourMatch(entry));
|
|
936
1092
|
const resultNormal = normalHours.map((entry) => checkHourMatch(entry));
|
|
937
1093
|
const resultExpensive = expensiveHours.map((entry) => checkHourMatch(entry));
|
|
1094
|
+
//#endregion
|
|
938
1095
|
// identify if an element is true and generate output
|
|
939
1096
|
if (resultCheap.some(value => value)) {
|
|
940
1097
|
// Cheap Hours - enable battery charging (ON-1) and disable feed into home energy system (OFF-2)
|
|
@@ -954,6 +1111,26 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
954
1111
|
else {
|
|
955
1112
|
this.adapter.log.warn(this.generateErrorMessage(`no result found for SBB`, `execute calculator for smart battery buffer in channel ${channel}`));
|
|
956
1113
|
}
|
|
1114
|
+
//#region *** Mark the entries with the result and create JSON output ***
|
|
1115
|
+
const jsonOutput = pricesToday
|
|
1116
|
+
.map((entry, index) => ({
|
|
1117
|
+
hour: new Date(entry.startsAt).getHours(), // extract the hour from startsAt
|
|
1118
|
+
startsAt: entry.startsAt,
|
|
1119
|
+
total: entry.total,
|
|
1120
|
+
output: resultCheap[index] !== undefined ? true : false, // Check if resultCheap[index] is defined
|
|
1121
|
+
}))
|
|
1122
|
+
.sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime()); // Sort by startsAt
|
|
1123
|
+
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, JSON.stringify(jsonOutput, null, 2), true);
|
|
1124
|
+
const jsonOutput2 = pricesToday
|
|
1125
|
+
.map((entry, index) => ({
|
|
1126
|
+
hour: new Date(entry.startsAt).getHours(), // extract the hour from startsAt
|
|
1127
|
+
startsAt: entry.startsAt,
|
|
1128
|
+
total: entry.total,
|
|
1129
|
+
output: resultExpensive[index] !== undefined ? true : false, // Check if resultCheap[index] is defined
|
|
1130
|
+
}))
|
|
1131
|
+
.sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime()); // Sort by startsAt
|
|
1132
|
+
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON2`, JSON.stringify(jsonOutput2, null, 2), true);
|
|
1133
|
+
//#endregion
|
|
957
1134
|
function calculateMinDelta(cheapHours, efficiencyLoss) {
|
|
958
1135
|
const cheapTotalSum = cheapHours.reduce((sum, hour) => sum + hour.total, 0);
|
|
959
1136
|
const cheapAverage = cheapTotalSum / cheapHours.length;
|
|
@@ -963,22 +1140,44 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
963
1140
|
this.setChannelOutStates(channel, valueToSet, valueToSet2);
|
|
964
1141
|
}
|
|
965
1142
|
catch (error) {
|
|
966
|
-
this.adapter.log.warn(this.generateErrorMessage(error, `execute calculator for
|
|
1143
|
+
this.adapter.log.warn(this.generateErrorMessage(error, `execute calculator for ${(0, projectUtils_1.getCalcTypeDescription)(channelConfig.chType)} in channel ${channel}`));
|
|
967
1144
|
}
|
|
968
1145
|
}
|
|
969
1146
|
async executeCalculatorBestPercentage(channel, modeLTF = false) {
|
|
1147
|
+
const now = new Date();
|
|
1148
|
+
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
1149
|
+
let valueToSet = channelConfig.chValueOff;
|
|
1150
|
+
const percentage = channelConfig.chPercentage;
|
|
970
1151
|
try {
|
|
971
|
-
const now = new Date();
|
|
972
|
-
const channelConfig = this.adapter.config.CalculatorList[channel];
|
|
973
|
-
let valueToSet = channelConfig.chValueOff;
|
|
974
1152
|
if (!channelConfig.chActive) {
|
|
975
1153
|
// not active -> choose chValueOff
|
|
1154
|
+
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, `[]`, true);
|
|
976
1155
|
}
|
|
977
1156
|
else if (modeLTF && now < channelConfig.chStartTime) {
|
|
978
1157
|
// chActive but before LTF -> choose chValueOff
|
|
1158
|
+
const filteredPrices = await this.getPricesLTF(channel, modeLTF);
|
|
1159
|
+
//#region *** Find channel result ***
|
|
1160
|
+
// sort by total cost
|
|
1161
|
+
filteredPrices.sort((a, b) => a.total - b.total);
|
|
1162
|
+
const cheapestPrice = filteredPrices[0]?.total;
|
|
1163
|
+
const allowedPrices = filteredPrices.filter(entry => entry.total <= cheapestPrice * (1 + percentage / 100));
|
|
1164
|
+
const channelResult = allowedPrices.map((entry) => checkHourMatch(entry));
|
|
1165
|
+
//#endregion
|
|
1166
|
+
//#region *** Mark the entries with the result and create JSON output ***
|
|
1167
|
+
const jsonOutput = filteredPrices
|
|
1168
|
+
.map((entry, index) => ({
|
|
1169
|
+
hour: new Date(entry.startsAt).getHours(), // extract the hour from startsAt
|
|
1170
|
+
startsAt: entry.startsAt,
|
|
1171
|
+
total: entry.total,
|
|
1172
|
+
output: channelResult[index] !== undefined ? true : false, // Check if channelResult[index] is defined
|
|
1173
|
+
}))
|
|
1174
|
+
.sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime()); // Sort by startsAt
|
|
1175
|
+
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, JSON.stringify(jsonOutput, null, 2), true);
|
|
1176
|
+
//#endregion
|
|
979
1177
|
}
|
|
980
1178
|
else if (modeLTF && now > channelConfig.chStopTime) {
|
|
981
1179
|
// chActive but after LTF -> choose chValueOff and disable channel or generate new running period
|
|
1180
|
+
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, `[]`, true);
|
|
982
1181
|
this.handleAfterLTF(channel);
|
|
983
1182
|
}
|
|
984
1183
|
else {
|
|
@@ -988,7 +1187,6 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
988
1187
|
// sort by total cost
|
|
989
1188
|
filteredPrices.sort((a, b) => a.total - b.total);
|
|
990
1189
|
const cheapestPrice = filteredPrices[0]?.total;
|
|
991
|
-
const percentage = channelConfig.chPercentage;
|
|
992
1190
|
const allowedPrices = filteredPrices.filter(entry => entry.total <= cheapestPrice * (1 + percentage / 100));
|
|
993
1191
|
const channelResult = allowedPrices.map((entry) => checkHourMatch(entry));
|
|
994
1192
|
// identify if any element is true
|
|
@@ -996,7 +1194,7 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
996
1194
|
valueToSet = channelConfig.chValueOn;
|
|
997
1195
|
}
|
|
998
1196
|
//#endregion
|
|
999
|
-
|
|
1197
|
+
//#region *** Mark the entries with the result and create JSON output ***
|
|
1000
1198
|
const jsonOutput = filteredPrices
|
|
1001
1199
|
.map((entry, index) => ({
|
|
1002
1200
|
hour: new Date(entry.startsAt).getHours(), // extract the hour from startsAt
|
|
@@ -1006,13 +1204,31 @@ class TibberCalculator extends projectUtils_1.ProjectUtils {
|
|
|
1006
1204
|
}))
|
|
1007
1205
|
.sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime()); // Sort by startsAt
|
|
1008
1206
|
void this.adapter.setState(`Homes.${channelConfig.chHomeID}.Calculations.${channel}.OutputJSON`, JSON.stringify(jsonOutput, null, 2), true);
|
|
1207
|
+
//#endregion
|
|
1009
1208
|
}
|
|
1010
1209
|
this.setChannelOutStates(channel, valueToSet);
|
|
1011
1210
|
}
|
|
1012
1211
|
catch (error) {
|
|
1013
|
-
this.adapter.log.warn(this.generateErrorMessage(error, `execute calculator for
|
|
1212
|
+
this.adapter.log.warn(this.generateErrorMessage(error, `execute calculator for ${(0, projectUtils_1.getCalcTypeDescription)(channelConfig.chType)} in channel ${channel}`));
|
|
1014
1213
|
}
|
|
1015
1214
|
}
|
|
1215
|
+
/**
|
|
1216
|
+
* Sets the output state(s) for a specific calculator channel.
|
|
1217
|
+
*
|
|
1218
|
+
* Depending on the configuration of the channel, the function sets either a custom target state or a default state for the specified channel.
|
|
1219
|
+
* Optionally, a second value can also be set.
|
|
1220
|
+
*
|
|
1221
|
+
* @param channel - The index of the channel in the configuration list (`CalculatorList`).
|
|
1222
|
+
* @param valueToSet - The primary value to set for the channel's output state.
|
|
1223
|
+
* @param valueToSet2 - An optional secondary value to set for the channel's second output state. Defaults to `EMPTY`.
|
|
1224
|
+
*
|
|
1225
|
+
* ### Function Behavior:
|
|
1226
|
+
* - If a custom `chTargetState` is defined for the channel (length > 10 and does not start with "choose your state to drive"),
|
|
1227
|
+
* the function sets this custom target state using `setForeignStateAsync`.
|
|
1228
|
+
* - Otherwise, it sets a default state for the channel in the format `Homes.{chHomeID}.Calculations.{channel}.Output`.
|
|
1229
|
+
* - Logs debug information about the state being set, including the channel type and the value.
|
|
1230
|
+
* - If `valueToSet2` is not `EMPTY`, the function repeats the process for a secondary target state.
|
|
1231
|
+
*/
|
|
1016
1232
|
setChannelOutStates(channel, valueToSet, valueToSet2 = `EMPTY`) {
|
|
1017
1233
|
let sOutState = ``;
|
|
1018
1234
|
const channelConfig = this.adapter.config.CalculatorList[channel];
|