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.
@@ -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.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.AmountHours`); // INPUTS
137
- await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StartTime`);
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.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.TriggerPrice`); // INPUTS
154
- await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StartTime`);
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.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.TriggerPrice`); // INPUTS
171
- await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StartTime`);
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.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.TriggerPrice`); // INPUTS
234
- await this.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.StartTime`);
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.adapter.delObjectAsync(`Homes.${homeId}.Calculations.${channel}.AmountHours`); // INPUTS
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.setup_chStartTime(homeId, channel);
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
- async setup_chStartTime(homeId, channel) {
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(`Homes.${homeId}.Calculations.${channel}.StartTime`, channelConfig.chStartTime.toISOString(), `Start time for this channel`, `date`, true, true);
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(`setup calculator settings state in home: ${homeId} - channel: ${channel}-${channelConfig.chName} - set to StartTime: ${channelConfig.chStartTime.toISOString()}`);
419
- }
420
- else {
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(`Homes.${homeId}.Calculations.${channel}.StopTime`, channelConfig.chStopTime.toISOString(), `Stop time for this channel`, `date`, true, true);
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(`setup calculator settings state in home: ${homeId} - channel: ${channel}-${channelConfig.chName} - set to StopTime: ${channelConfig.chStopTime.toISOString()}`);
442
- }
443
- else {
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(`Homes.${homeId}.Calculations.${channel}.RepeatDays`, channelConfig.chRepeatDays, `number of days to shift this LTF channel for repetition`, undefined, `level`, true, true);
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(`setup calculator settings state in home: ${homeId} - channel: ${channel}-${channelConfig.chName} - set to RepeatDays: ${channelConfig.chRepeatDays}`);
463
- }
464
- else {
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 best price ${modeLTF ? "LTF " : ""}in channel ${channel}`));
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 best single hours ${modeLTF ? "LTF " : ""}in channel ${channel}`));
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
- // mark the entries with the result and create JSON output
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 best hours block ${modeLTF ? "LTF " : ""}in channel ${channel}`));
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 smart battery buffer in channel ${channel}`));
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
- // mark the entries with the result and create JSON output
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 best percentage ${modeLTF ? "LTF " : ""}in channel ${channel}`));
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];