iobroker.senec 1.6.4 → 1.6.6

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.
@@ -404,306 +404,6 @@ const state_trans = {
404
404
  18: 'Senec.Home V3 Hybrid duo (18)',
405
405
  19: 'Senec.Home V3 Hybrid (19)'
406
406
  },
407
- 'STATISTIC.CURRENT_STATE.0': {
408
- 0: 'INITIALZUSTAND (0)',
409
- 1: 'KEINE KOMMUNIKATION LADEGERAET (1)',
410
- 2: 'FEHLER LEISTUNGSMESSGERAET (2)',
411
- 3: 'RUNDSTEUEREMPFAENGER (3)',
412
- 4: 'ERSTLADUNG (4)',
413
- 5: 'WARTUNGSLADUNG (5)',
414
- 6: 'WARTUNGSLADUNG FERTIG (6)',
415
- 7: 'WARTUNG NOTWENDIG (7)',
416
- 8: 'MAN. SICHERHEITSLADUNG (8)',
417
- 9: 'SICHERHEITSLADUNG FERTIG (9)',
418
- 10: 'VOLLLADUNG (10)',
419
- 11: 'AUSGLEICHSLADUNG: LADEN (11)',
420
- 12: 'SULFATLADUNG: LADEN (12)',
421
- 13: 'AKKU VOLL (13)',
422
- 14: 'LADEN (14)',
423
- 15: 'AKKU LEER (15)',
424
- 16: 'ENTLADEN (16)',
425
- 17: 'PV + ENTLADEN (17)',
426
- 18: 'NETZ + ENTLADEN (18)',
427
- 19: 'PASSIV (19)',
428
- 20: 'AUSGESCHALTET (20)',
429
- 21: 'EIGENVERBRAUCH (21)',
430
- 22: 'NEUSTART (22)',
431
- 23: 'MAN. AUSGLEICHSLADUNG: LADEN (23)',
432
- 24: 'MAN. SULFATLADUNG: LADEN (24)',
433
- 25: 'SICHERHEITSLADUNG (25)',
434
- 26: 'AKKU-SCHUTZBETRIEB (26)',
435
- 27: 'EG FEHLER (27)',
436
- 28: 'EG LADEN (28)',
437
- 29: 'EG ENTLADEN (29)',
438
- 30: 'EG PASSIV (30)',
439
- 31: 'EG LADEN VERBOTEN (31)',
440
- 32: 'EG ENTLADEN VERBOTEN (32)',
441
- 33: 'NOTLADUNG (33)',
442
- 34: 'SOFTWAREAKTUALISIERUNG (34)',
443
- 35: 'FEHLER: NA-SCHUTZ (35)',
444
- 36: 'FEHLER: NA-SCHUTZ NETZ (36)',
445
- 37: 'FEHLER: NA-SCHUTZ HARDWARE (37)',
446
- 38: 'KEINE SERVERVERBINDUNG (38)',
447
- 39: 'BMS FEHLER (39)',
448
- 40: 'WARTUNG: FILTER (40)',
449
- 41: 'SCHLAFMODUS (41)',
450
- 42: 'WARTE AUF ÜBERSCHUSS (42)',
451
- 43: 'KAPAZITÄTSTEST: LADEN (43)',
452
- 44: 'KAPAZITÄTSTEST: ENTLADEN (44)',
453
- 45: 'MAN. SULFATLADUNG: WARTEN (45)',
454
- 46: 'MAN. SULFATLADUNG: FERTIG (46)',
455
- 47: 'MAN. SULFATLADUNG: FEHLER (47)',
456
- 48: 'AUSGLEICHSLADUNG: WARTEN (48)',
457
- 49: 'NOTLADUNG: FEHLER (49)',
458
- 50: 'MAN: AUSGLEICHSLADUNG: WARTEN (50)',
459
- 51: 'MAN: AUSGLEICHSLADUNG: FEHLER (51)',
460
- 52: 'MAN: AUSGLEICHSLADUNG: FERTIG (52)',
461
- 53: 'AUTO: SULFATLADUNG: WARTEN (53)',
462
- 54: 'LADESCHLUSSPHASE (54)',
463
- 55: 'BATTERIETRENNSCHALTER AUS (55)',
464
- 56: 'PEAK-SHAVING: WARTEN (56)',
465
- 57: 'FEHLER LADEGERAET (57)',
466
- 58: 'NPU-FEHLER (58)',
467
- 59: 'BMS OFFLINE (59)',
468
- 60: 'WARTUNGSLADUNG FEHLER (60)',
469
- 61: 'MAN. SICHERHEITSLADUNG FEHLER (61)',
470
- 62: 'SICHERHEITSLADUNG FEHLER (62)',
471
- 63: 'KEINE MASTERVERBINDUNG (63)',
472
- 64: 'LITHIUM SICHERHEITSMODUS AKTIV (64)',
473
- 65: 'LITHIUM SICHERHEITSMODUS BEENDET (65)',
474
- 66: 'FEHLER BATTERIESPANNUNG (66)',
475
- 67: 'BMS DC AUSGESCHALTET (67)',
476
- 68: 'NETZINITIALISIERUNG (68)',
477
- 69: 'NETZSTABILISIERUNG (69)',
478
- 70: 'FERNABSCHALTUNG (70)',
479
- 71: 'OFFPEAK-LADEN (71)',
480
- 72: 'FEHLER HALBBRÜCKE (72)',
481
- 73: 'BMS: FEHLER BETRIEBSTEMPERATUR (73)',
482
- 74: 'FACOTRY SETTINGS NICHT GEFUNDEN (74)',
483
- 75: 'NETZERSATZBETRIEB (75)',
484
- 76: 'NETZERSATZBETRIEB AKKU LEER (76)',
485
- 77: 'NETZERSATZBETRIEB FEHLER (77)',
486
- 78: 'INITIALISIERUNG (78)',
487
- 79: 'INSTALLATIONSMODUS (79)',
488
- 80: 'NETZAUSFALL (80)',
489
- 81: 'BMS UPDATE ERFORDERLICH (81)',
490
- 82: 'BMS KONFIGURATION ERFORDERLICH (82)',
491
- 83: 'ISOLATIONSTEST (83)',
492
- 84: 'SELBSTTEST (84)',
493
- 85: 'EXTERNE STEUERUNG (85)',
494
- 86: 'TEMPERATUR SENSOR FEHLER (86)',
495
- 87: 'NETZBETREIBER: LADEN GESPERRT (87)',
496
- 88: 'NETZBETREIBER: ENTLADEN GESPERRT (88)',
497
- 89: 'RESERVEKAPAZITÄT (89)',
498
- 90: 'SELBSTTEST FEHLER (90)',
499
- 91: 'ISOLATIONSFEHLER (91)',
500
- 92: 'PV-MODUS (92)',
501
- 93: 'FERNABSCHALTUNG NETZBETREIBER (93)',
502
- 94: 'FEHLER DRM0 (94)',
503
- 95: 'BATTERIEDIAGNOSE (95)',
504
- 96: 'BATTERIE BALANCIERUNG (96)',
505
- 97: 'SICHERHEITSENTLADUNG (97)'
506
- },
507
- 'STATISTIC.CURRENT_STATE.1': {
508
- 0: 'INITIALSTATE',
509
- 1: 'ERROR INVERTER COMMUNICATION',
510
- 2: 'ERROR ELECTRICY METER',
511
- 3: 'RIPPLE CONTROL RECEIVER',
512
- 4: 'INITIAL CHARGE',
513
- 5: 'MAINTENANCE CHARGE',
514
- 6: 'MAINTENANCE READY',
515
- 7: 'MAINTENANCE REQUIRED',
516
- 8: 'MAN. SAFETY CHARGE',
517
- 9: 'SAFETY CHARGE READY',
518
- 10: 'FULL CHARGE',
519
- 11: 'EQUALIZATION: CHARGE',
520
- 12: 'DESULFATATION: CHARGE',
521
- 13: 'BATTERY FULL',
522
- 14: 'CHARGE',
523
- 15: 'BATTERY EMPTY',
524
- 16: 'DISCHARGE',
525
- 17: 'PV + DISCHARGE',
526
- 18: 'GRID + DISCHARGE',
527
- 19: 'PASSIVE',
528
- 20: 'OFF',
529
- 21: 'OWN CONSUMPTION',
530
- 22: 'RESTART',
531
- 23: 'MAN. EQUALIZATION: CHARGE',
532
- 24: 'MAN. DESULFATATION: CHARGE',
533
- 25: 'SAFETY CHARGE',
534
- 26: 'BATTERY PROTECTION MODE',
535
- 27: 'EG ERROR',
536
- 28: 'EG CHARGE',
537
- 29: 'EG DISCHARGE',
538
- 30: 'EG PASSIVE',
539
- 31: 'EG PROHIBIT CHARGE',
540
- 32: 'EG PROHIBIT DISCHARGE',
541
- 33: 'EMERGANCY CHARGE',
542
- 34: 'SOFTWARE UPDATE',
543
- 35: 'NSP ERROR',
544
- 36: 'NSP ERROR: GRID',
545
- 37: 'NSP ERROR: HARDWRE',
546
- 38: 'NO SERVER CONNECTION',
547
- 39: 'BMS ERROR',
548
- 40: 'MAINTENANCE: FILTER',
549
- 41: 'SLEEPING MODE',
550
- 42: 'WAITING EXCESS',
551
- 43: 'CAPACITY TEST: CHARGE',
552
- 44: 'CAPACITY TEST: DISCHARGE',
553
- 45: 'MAN. DESULFATATION: WAIT',
554
- 46: 'MAN. DESULFATATION: READY',
555
- 47: 'MAN. DESULFATATION: ERROR',
556
- 48: 'EQUALIZATION: WAIT',
557
- 49: 'EMERGANCY CHARGE: ERROR',
558
- 50: 'MAN. EQUALIZATION: WAIT',
559
- 51: 'MAN. EQUALIZATION: ERROR',
560
- 52: 'MAN: EQUALIZATION: READY',
561
- 53: 'AUTO. DESULFATATION: WAIT',
562
- 54: 'ABSORPTION PHASE',
563
- 55: 'DC-SWITCH OFF',
564
- 56: 'PEAK-SHAVING: WAIT',
565
- 57: 'ERROR BATTERY INVERTER',
566
- 58: 'NPU-ERROR',
567
- 59: 'BMS OFFLINE',
568
- 60: 'MAINTENANCE CHARGE ERROR',
569
- 61: 'MAN. SAFETY CHARGE ERROR',
570
- 62: 'SAFETY CHARGE ERROR',
571
- 63: 'NO CONNECTION TO MASTER',
572
- 64: 'LITHIUM SAFE MODE ACTIVE',
573
- 65: 'LITHIUM SAFE MODE DONE',
574
- 66: 'BATTERY VOLTAGE ERROR',
575
- 67: 'BMS DC SWITCHED OFF',
576
- 68: 'GRID INITIALIZATION',
577
- 69: 'GRID STABILIZATION',
578
- 70: 'REMOTE SHUTDOWN',
579
- 71: 'OFFPEAK-CHARGE',
580
- 72: 'ERROR HALFBRIDGE',
581
- 73: 'BMS: ERROR OPERATING TEMPERATURE',
582
- 74: 'FACOTRY SETTINGS NOT FOUND',
583
- 75: 'BACKUP POWER MODE - ACTIVE',
584
- 76: 'BACKUP POWER MODE - BATTERY EMPTY',
585
- 77: 'BACKUP POWER MODE ERROR',
586
- 78: 'INITIALISING',
587
- 79: 'INSTALLATION MODE',
588
- 80: 'GRID OFFLINE',
589
- 81: 'BMS UPDATE NEEDED',
590
- 82: 'BMS CONFIGURATION NEEDED',
591
- 83: 'INSULATION TEST',
592
- 84: 'SELFTEST',
593
- 85: 'EXTERNAL CONTROL',
594
- 86: 'ERROR: TEMPERATURESENSOR',
595
- 87: 'GRID OPERATOR: CHARGE PROHIBITED',
596
- 88: 'GRID OPERATOR: DISCHARGE PROHIBITED',
597
- 89: 'SPARE CAPACITY',
598
- 90: 'SELFTEST ERROR',
599
- 91: 'EARTH FAULT',
600
- 92: 'PV-MODE',
601
- 93: 'REMOTE SHUTDOWN GRID OPERATOR',
602
- 94: 'ERROR DRM0',
603
- 95: 'BATTERY DIAGNOSIS',
604
- 96: 'BATTERY BALANCING',
605
- 97: 'SAFETY DISCHARGE'
606
- },
607
- 'STATISTIC.CURRENT_STATE.2': {
608
- 0: 'STATO INIZIALE',
609
- 1: 'ERRORE COMMUNICAZIONE INVERTER',
610
- 2: 'ERRORE WATTMETRO',
611
- 3: 'RICEVITORE RIPPLE CONTROL',
612
- 4: 'PRIMA CARICA',
613
- 5: 'CARICA DI MANTENIMENTO',
614
- 6: 'CARICA DI MANTENIMENTO COMPLETATA',
615
- 7: 'MANUTENZIONE: NECESSARIA',
616
- 8: 'CARICA DI SICUREZZA MANUALE',
617
- 9: 'CARICA DI SICUREZZA COMPLETA',
618
- 10: 'CARICA COMPLETA',
619
- 11: 'CARICA DI EQUALIZZAZIONE',
620
- 12: 'CARICA DI DESOLFATAZIONE',
621
- 13: 'ACCUMULATORE CARICO',
622
- 14: 'CARICA',
623
- 15: 'ACCUMULATORE SCARICO',
624
- 16: 'SCARICA',
625
- 17: 'FV + SCARICA',
626
- 18: 'RETE + SCARICA',
627
- 19: 'PASSIVO',
628
- 20: 'SPENTO',
629
- 21: 'AUTOCONSUMO',
630
- 22: 'RIAVVIO',
631
- 23: 'CARICA DI EQUALIZZAZIONE MANUALE',
632
- 24: 'CARICA DI DESOLFATAZIONE MANUALE',
633
- 25: 'CARICA DI SICUREZZA',
634
- 26: 'MODALITÀ PROTEZIONE ACCUMULATORE',
635
- 27: 'ERRORE EG',
636
- 28: 'EG: CARICA',
637
- 29: 'EG: SCARICA',
638
- 30: 'EG: PASSIVO',
639
- 31: 'CARICA EG PROIBITA',
640
- 32: 'SCARICAMENTO EG PROIBITO',
641
- 33: 'CARICA D\'EMERGENZA',
642
- 34: 'AGGIORNAMENTO SOFTWARE',
643
- 35: 'ERRORE SPI',
644
- 36: 'ERRORE SPI: RETE ',
645
- 37: 'ERRORE SPI: HARDWARE ',
646
- 38: 'NESSUNA CONNESSIONE AL SERVER',
647
- 39: 'ERRORE BMS',
648
- 40: 'SOSTITUZIONE DEL FILTRO NECESSARIA',
649
- 41: 'BATTERIA AL LITIO SPENTA',
650
- 42: 'IN ATTESA DI SURPLUS ENERGETICO',
651
- 43: 'TEST DI CAPACITÀ: CARICA',
652
- 44: 'TEST DI CAPACITÀ: SCARICA',
653
- 45: 'CARICA DI DESOLFATAZIONE MANUALE: ATTESA',
654
- 46: 'CARICA DI DESOLFATAZIONE MANUALE: COMPLETA',
655
- 47: 'CARICA DI DESOLFATAZIONE MANUALE: ERRORE',
656
- 48: 'EQUALIZZAZIONE: ATTESA',
657
- 49: 'CARICA D\'EMERGENZA: ERRORE',
658
- 50: 'EQUALIZZAZIONE MANUALE: ATTESA',
659
- 51: 'EQUALIZZAZIONE MANUALE: ERRORE',
660
- 52: 'EQUALIZZAZIONE MANUALE: COMPLETA',
661
- 53: 'CARICA DI DESOLFATAZIONE: ATTESA',
662
- 54: 'FASE FINALE CARICA',
663
- 55: 'SEZIONATORE BATTERIA OFF',
664
- 56: 'PEAK SHAVING: ATTESA',
665
- 57: 'ERRORE DISPOSITIVO DI CARICA',
666
- 58: 'ERRORE NPU',
667
- 59: 'BMS DISCONESSO',
668
- 60: 'CARICA DI MANUTENZIONE ERRORE',
669
- 61: 'CARICA DI SICUREZZA MANUALE ERRORE',
670
- 62: 'CARICA DI SICUREZZA ERRORE',
671
- 63: 'NESSUNA CONNESSIONE MASTER',
672
- 64: 'MODALITA DI PROTEZIONE LITIO ATTIVA',
673
- 65: 'MODALITA DI PROTEZIONE LITIO COMPLETA',
674
- 66: 'ERORE DI TENSIONE BATTERIA',
675
- 67: 'BMS DC SPENTO',
676
- 68: 'INIZIALIZZAZIONE DELLA RETE',
677
- 69: 'STABILIZZAZIONE DELLA RETE',
678
- 70: 'ARRESTO REMOTO',
679
- 71: 'OFFPEAK-CARICA',
680
- 72: 'ERRORE MEZZO PONTE',
681
- 73: 'BMS: ERRORE TEMPERATURA DI FUNZIONAMENTO',
682
- 74: 'FACOTRY SETTINGS NON TROVATO',
683
- 75: 'FUNZIONAMENTO ISOLATO',
684
- 76: 'FUNZIONAMENTO ISOLATO ACCUMULATORE SCARICO',
685
- 77: 'ERORE DI FUNZIONAMENTO ISOLATO',
686
- 78: 'INIZIALIZZAZIONE',
687
- 79: 'MODALITA INSTALLAZIONE',
688
- 80: 'RETE OFFLINE',
689
- 81: 'AGGIORNAMENTO BMS NECESSARIO',
690
- 82: 'CONFIGURAZIONE BMS NECESSARIA',
691
- 83: 'TEST DI ISOLAMENTO',
692
- 84: 'AUTOTEST',
693
- 85: 'CONTROLLO ESTERNO',
694
- 86: 'ERRORE SENSORE DI TEMPERATURA',
695
- 87: 'OPERATORE DI RETE: CARICA BLOCCATA',
696
- 88: 'OPERATORE DI RETE: SCARICA BLOCCATA',
697
- 89: 'CAPACITA INUTILIZZATA',
698
- 90: 'ERRORE DI AUTOTEST',
699
- 91: 'FAGLIA TERRESTRE',
700
- 92: 'MODALITÀ FOTOVOLTAICA',
701
- 93: 'SPEGNIMENTO A DISTANZA OPERATORE DI RETE',
702
- 94: 'ERRORE DRM0',
703
- 95: 'DIAGNOSI DELLA BATTERIA',
704
- 96: 'BILANCIAMENTO DELLA BATTERIA',
705
- 97: 'SCARICO DI SICUREZZA'
706
- },
707
407
  'WALLBOX.STATE.0' : {
708
408
  161: 'Warte auf E-Fahrzeug (161)',
709
409
  177: 'E-Fahrzeug fragt Ladung an (177)',
package/main.js CHANGED
@@ -28,8 +28,7 @@ let retry = 0; // retry-counter
28
28
  let retryLowPrio = 0; // retry-counter
29
29
  let connectVia = "http://";
30
30
 
31
- const allKnownObjects = new Set(["BAT1","BAT1OBJ1","BAT1OBJ2","BAT1OBJ3","BMS","BMS_PARA","CASC","DEBUG","DISPLAY","ENERGY","FACTORY","FEATURES","FILE","GRIDCONFIG","ISKRA","LOG","PM1","PM1OBJ1","PM1OBJ2","PV1","PWR_UNIT","RTC","SELFTEST_RESULTS","SOCKETS","STATISTIC","STECA","SYS_UPDATE","TEMPMEASURE","TEST","UPDATE","WALLBOX","WIZARD"]);
32
- // STATISTICS is faded out by senec. Keeping it while we still have machines getting it. This will also deprecate all calculated valued in the "_calc" branch.
31
+ const allKnownObjects = new Set(["BAT1","BAT1OBJ1","BMS","BMS_PARA","BMZ_CURRENT_LIMITS","CASC","CELL_DEVIATION_ROC","CURRENT_IMBALANCE_CONTROL","DEBUG","ENERGY","FACTORY","FEATURES","GRIDCONFIG","ISKRA","LOG","PM1","PM1OBJ1","PM1OBJ2","PV1","PWR_UNIT","RTC","SENEC_IO_INPUT","SENEC_IO_OUTPUT","SELFTEST_RESULTS","SOCKETS","STECA","SYS_UPDATE","TEMPMEASURE","TEST","UPDATE","WALLBOX","WIZARD"]);
33
32
 
34
33
  const highPrioObjects = new Map;
35
34
  let lowPrioForm = "";
@@ -130,11 +129,6 @@ class Senec extends utils.Adapter {
130
129
  ["FREQ","U_AC","I_AC","P_AC","P_TOTAL"].forEach(item => objectsSet.add(item));
131
130
  if (this.config.disclaimer && this.config.highPrio_PM1OBJ2_active) this.addUserDps(value, objectsSet, this.config.highPrio_PM1OBJ2);
132
131
  break;
133
- case "STATISTIC":
134
- // soon to be deprecated
135
- ["LIVE_GRID_EXPORT","LIVE_GRID_IMPORT","LIVE_HOUSE_CONS","LIVE_PV_GEN","LIVE_BAT_CHARGE_MASTER","LIVE_BAT_DISCHARGE_MASTER"].forEach(item => objectsSet.add(item));
136
- if (this.config.disclaimer && this.config.highPrio_STATISTIC_active) this.addUserDps(value, objectsSet, this.config.highPrio_STATISTIC);
137
- break;
138
132
  case "WALLBOX":
139
133
  if (this.config.disclaimer && this.config.highPrio_WALLBOX_active) this.addUserDps(value, objectsSet, this.config.highPrio_WALLBOX);
140
134
  break;
@@ -144,15 +138,6 @@ class Senec extends utils.Adapter {
144
138
  case "BAT1OBJ1":
145
139
  if (this.config.disclaimer && this.config.highPrio_BAT1OBJ1_active) this.addUserDps(value, objectsSet, this.config.highPrio_BAT1OBJ1);
146
140
  break;
147
- case "BAT1OBJ2":
148
- if (this.config.disclaimer && this.config.highPrio_BAT1OBJ2_active) this.addUserDps(value, objectsSet, this.config.highPrio_BAT2OBJ1);
149
- break;
150
- case "BAT1OBJ3":
151
- if (this.config.disclaimer && this.config.highPrio_BAT1OBJ3_active) this.addUserDps(value, objectsSet, this.config.highPrio_BAT3OBJ1);
152
- break;
153
- case "BAT1OBJ4":
154
- if (this.config.disclaimer && this.config.highPrio_BAT1OBJ4_active) this.addUserDps(value, objectsSet, this.config.highPrio_BAT4OBJ1);
155
- break;
156
141
  case "TEMPMEASURE":
157
142
  if (this.config.disclaimer && this.config.highPrio_TEMPMEASURE_active) this.addUserDps(value, objectsSet, this.config.highPrio_TEMPMEASURE);
158
143
  break;
@@ -292,12 +277,12 @@ class Senec extends utils.Adapter {
292
277
  apiKnownSystems.push(systemId);
293
278
  for (const[key2, value2] of Object.entries(value)) {
294
279
  if (typeof value2 === "object")
295
- this.doState(pfx + systemId + "." + key2, JSON.stringify(value2), "", "", false);
280
+ await this.doState(pfx + systemId + "." + key2, JSON.stringify(value2), "", "", false);
296
281
  else
297
- this.doState(pfx + systemId + "." + key2, value2, "", "", false);
282
+ await this.doState(pfx + systemId + "." + key2, value2, "", "", false);
298
283
  }
299
284
  }
300
- this.doState(pfx + 'IDs', JSON.stringify(apiKnownSystems), "Anlagen IDs", "", false);
285
+ await this.doState(pfx + 'IDs', JSON.stringify(apiKnownSystems), "Anlagen IDs", "", false);
301
286
  } catch (error) {
302
287
  throw new Error("Error reading Systems Information from Senec AppAPI. (" + error + ").");
303
288
  }
@@ -409,7 +394,7 @@ class Senec extends utils.Adapter {
409
394
  var body = "";
410
395
  try {
411
396
  for (let i = 0; i < apiKnownSystems.length; i++) {
412
- const baseUrl = apiSystemsUrl + "/" + apiKnownSystems[i]
397
+ const baseUrl = apiSystemsUrl + "/" + apiKnownSystems[i];
413
398
  var url = "";
414
399
  const tzObj = await this.getStateAsync("_api.Anlagen." + apiKnownSystems[i] + ".zeitzone");
415
400
  const tz = tzObj ? encodeURIComponent(tzObj.val) : encodeURIComponent("Europe/Berlin");
@@ -420,17 +405,14 @@ class Senec extends utils.Adapter {
420
405
  await this.decodeDashboard(apiKnownSystems[i], JSON.parse(body));
421
406
 
422
407
  for (let[key, value] of dates.entries()) {
423
- // statistik today
408
+ // statistik for period
424
409
  url = baseUrl + "/statistik?periode=" + api_trans[key].api + "&datum=" + value + "&locale=de_DE&timezone=" + tz;
425
410
  body = await this.doGet(url, "", this, this.config.pollingTimeout, false);
426
411
  await this.decodeStatistik(apiKnownSystems[i], JSON.parse(body), api_trans[key].dp);
427
412
  }
428
413
 
429
- // // wallboxes - only if wallbox exists? - Without: error 500
430
- //var url = apiSystemsUrl + "/" + apiKnownSystems[i] + "/wallboxes/1";
431
- //body = await this.doGet(url, "", this, this.config.pollingTimeout, false);
432
- //this.log.info("Abilities: " + body);
433
- //await this.decodeWallbox(apiKnownSystems[i], JSON.parse(body));
414
+ if (this.config.api_alltimeRebuild) await this.rebuildAllTimeHistory(apiKnownSystems[i]);
415
+
434
416
  }
435
417
  retry = 0;
436
418
  if (unloaded) return;
@@ -447,16 +429,19 @@ class Senec extends utils.Adapter {
447
429
  }
448
430
  }
449
431
 
432
+ /**
433
+ * Decodes Dashboard information from SENEC App API
434
+ */
450
435
  async decodeDashboard(system, obj) {
451
436
  const pfx = "_api.Anlagen." + system + ".Dashboard.";
452
437
  for (const[key, value] of Object.entries(obj)) {
453
438
  if (key == "zeitstempel" || key == "electricVehicleConnected") {
454
- this.doState(pfx + key, value, "", "", false);
439
+ await this.doState(pfx + key, value, "", "", false);
455
440
  } else {
456
441
  for (const[key2, value2] of Object.entries(value)) {
457
- this.doState(pfx + key + "." + key2, Number((value2.wert).toFixed(2)), "", value2.einheit, false);
442
+ await this.doState(pfx + key + "." + key2, Number((value2.wert).toFixed(2)), "", value2.einheit, false);
458
443
  if (kiloList.includes(value2.einheit)) {
459
- this.doState(pfx + key + "." + key2 + " (k" + value2.einheit + ")", Number((value2.wert / 1000).toFixed(2)), "", "k" + value2.einheit, false);
444
+ await this.doState(pfx + key + "." + key2 + " (k" + value2.einheit + ")", Number((value2.wert / 1000).toFixed(2)), "", "k" + value2.einheit, false);
460
445
  }
461
446
  }
462
447
  }
@@ -464,21 +449,106 @@ class Senec extends utils.Adapter {
464
449
 
465
450
  }
466
451
 
452
+ /**
453
+ * Decodes Statistik information from SENEC App API
454
+ */
467
455
  async decodeStatistik(system, obj, period) {
456
+ if (obj == null || obj == undefined || obj.aggregation == null || obj.aggregation == undefined) return; // could happen (e.g.) if we pull information for "last year" when the appliance isn't that old yet
468
457
  const pfx = "_api.Anlagen." + system + ".Statistik." + period + ".";
469
458
  for (const[key, value] of Object.entries(obj.aggregation)) {
470
459
  // only reading 'aggregation' - no interest in fine granular information
471
460
  if (key == "startzeitpunkt") {
472
- this.doState(pfx + key, value, "", "", false);
461
+ await this.doState(pfx + key, value, "", "", false);
473
462
  } else {
474
- this.doState(pfx + key, Number((value.wert).toFixed(2)), "", value.einheit, false);
475
- if (kiloList.includes(value.einheit)) {
476
- this.doState(pfx + key + " (k"+ value.einheit + ")", Number((value.wert / 1000).toFixed(2)), "", "k" + value.einheit, false);
463
+ if (!this.config.api_alltimeRebuild) { // don't update DPs if we are AllTime-Rebuild-Process
464
+ await this.doState(pfx + key, Number((value.wert).toFixed(2)), "", value.einheit, false);
465
+ if (kiloList.includes(value.einheit)) {
466
+ await this.doState(pfx + key + " (k"+ value.einheit + ")", Number((value.wert / 1000).toFixed(2)), "", "k" + value.einheit, false);
467
+ }
477
468
  }
469
+ if (period == api_trans["THIS_YEAR"].dp) await this.insertAllTimeHistory(system, key, new Date(obj.aggregation.startzeitpunkt).getFullYear(), Number((value.wert).toFixed(0)), value.einheit);
478
470
  }
479
471
  }
480
472
  const autarky = Number((((obj.aggregation.stromerzeugung.wert - obj.aggregation.netzeinspeisung.wert - obj.aggregation.speicherbeladung.wert + obj.aggregation.speicherentnahme.wert) / obj.aggregation.stromverbrauch.wert) * 100).toFixed(2));
481
- this.doState(pfx + "Autarkie", autarky, "", "%", false);
473
+ await this.doState(pfx + "Autarkie", autarky, "", "%", false);
474
+ await this.updateAllTimeHistory(system);
475
+ }
476
+
477
+ /**
478
+ * inserts a value for a given key and year into AllTimeValueStore
479
+ */
480
+ async insertAllTimeHistory(system, key, year, value, einheit) {
481
+ const pfx = "_api.Anlagen." + system + ".Statistik.AllTime.";
482
+ const valueStore = pfx + "valueStore";
483
+ const statsObj = await this.getStateAsync(valueStore);
484
+ const stats = statsObj ? JSON.parse(statsObj.val) : {};
485
+ if (!stats[key]) stats[key] = {};
486
+ if (!stats[key][year]) stats[key][year] = {};
487
+ stats[key][year] = value;
488
+ stats[key]["einheit"] = einheit;
489
+ await this.doState(valueStore, JSON.stringify(stats), "", "", false);
490
+ }
491
+
492
+ /**
493
+ * Updated AllTimeHistory based on what we have in our AllTimeValueStore
494
+ */
495
+ async updateAllTimeHistory(system) {
496
+ const pfx = "_api.Anlagen." + system + ".Statistik.AllTime.";
497
+ const valueStore = pfx + "valueStore";
498
+ const statsObj = await this.getStateAsync(valueStore);
499
+ const stats = statsObj ? JSON.parse(statsObj.val) : {};
500
+ const sums = {};
501
+ for (const[key, value] of Object.entries(stats)) {
502
+ var einheit = "";
503
+ var sum = 0.0;
504
+ for (const[key2, value2] of Object.entries(value)) {
505
+ if (key2 == "einheit") {
506
+ einheit = value2;
507
+ } else {
508
+ sum += value2;
509
+ }
510
+ }
511
+ sums[key] = sum;
512
+ if (kiloList.includes(einheit)) {
513
+ await this.doState(pfx + key, Number((sum / 1000).toFixed(0)), "", "k" + einheit, false);
514
+ } else {
515
+ await this.doState(pfx + key, Number(sum.toFixed(0)), "", einheit, false);
516
+ }
517
+ }
518
+ const autarky = Number((((sums.stromerzeugung - sums.netzeinspeisung - sums.speicherbeladung + sums.speicherentnahme) / sums.stromverbrauch) * 100).toFixed(0));
519
+ await this.doState(pfx + "Autarkie", autarky, "", "%", false);
520
+ }
521
+
522
+ /**
523
+ * Rebuilds AllTimeHistory from SENEC App API
524
+ */
525
+ async rebuildAllTimeHistory(system) {
526
+ if (!this.config.api_use || !apiConnected) {
527
+ this.log.info('Usage of SENEC App API not configured or not connected.');
528
+ return;
529
+ }
530
+
531
+ this.log.info("Rebuilding AllTime History ...");
532
+ var year = new Date(new Date().getFullYear() - 1, 1, 1).toISOString().split('T')[0]; // starting last year, because we already got current year covered
533
+ var body = "";
534
+ try {
535
+ while (new Date(year).getFullYear() > 2008) { // senec was founded in 2009 by Mathias Hammer as Deutsche Energieversorgung GmbH (DEV) - so no way we have older data :)
536
+ this.log.info("Rebuilding AllTime History - Year: " + new Date(year).getFullYear());
537
+ const baseUrl = apiSystemsUrl + "/" + system
538
+ var url = "";
539
+ const tzObj = await this.getStateAsync("_api.Anlagen." + system + ".zeitzone");
540
+ const tz = tzObj ? encodeURIComponent(tzObj.val) : encodeURIComponent("Europe/Berlin");
541
+ url = baseUrl + "/statistik?periode=JAHR&datum=" + year + "&locale=de_DE&timezone=" + tz;
542
+ body = await this.doGet(url, "", this, this.config.pollingTimeout, false);
543
+ await this.decodeStatistik(system, JSON.parse(body), api_trans["THIS_YEAR"].dp);
544
+ year = new Date(new Date(year).getFullYear() - 1, 1, 1).toISOString().split('T')[0];
545
+ if (unloaded) return;
546
+ }
547
+ } catch (error) {
548
+ this.log.info("Rebuild ended.");
549
+ }
550
+ this.log.info("Restarting ...");
551
+ this.extendForeignObject(`system.adapter.${this.namespace}`, {native: {api_alltimeRebuild: false}});
482
552
  }
483
553
 
484
554
  /**
@@ -536,7 +606,6 @@ class Senec extends utils.Adapter {
536
606
  val: value,
537
607
  ack: true
538
608
  });
539
- await this.checkUpdateSelfStat(name); // soon to be deprecated
540
609
  await this.doDecode(name, value);
541
610
  }
542
611
 
@@ -562,16 +631,6 @@ class Senec extends utils.Adapter {
562
631
  await this.doState(name + "_Text", trans, desc, "", true);
563
632
  }
564
633
  }
565
-
566
- /**
567
- * Helper routine
568
- */
569
- async checkUpdateSelfStat(name) {
570
- // soon to be deprecated
571
- if (name === "STATISTIC.LIVE_GRID_EXPORT" || name === "STATISTIC.LIVE_GRID_IMPORT" || name === "STATISTIC.LIVE_HOUSE_CONS" || name === "STATISTIC.LIVE_PV_GEN" || name === "STATISTIC.LIVE_BAT_CHARGE_MASTER" || name === "STATISTIC.LIVE_BAT_DISCHARGE_MASTER") {
572
- await this.updateSelfStat(name);
573
- }
574
- }
575
634
 
576
635
  /**
577
636
  * evaluates data polled from SENEC system.
@@ -600,109 +659,6 @@ class Senec extends utils.Adapter {
600
659
  }
601
660
  }
602
661
  }
603
-
604
- async updateSelfStat(name, value) {
605
- // soon to be deprecated
606
- await this.updateSelfStatHelper(name, value, ".today", ".yesterday", ".refValue", "Day", getCurDay());
607
- await this.updateSelfStatHelper(name, value, ".week", ".lastWeek", ".refValueWeek", "Week", getCurWeek());
608
- await this.updateSelfStatHelper(name, value, ".month", ".lastMonth", ".refValueMonth", "Month", getCurMonth());
609
- await this.updateSelfStatHelper(name, value, ".year", ".lastYear", ".refValueYear", "Year", getCurYear());
610
- return;
611
- }
612
-
613
- async updateSelfStatHelper(name, value, today, yesterday, refValue, day, curDay) {
614
- // soon to be deprecated
615
- const key = "_calc." + name.substring(10);
616
-
617
- const refDayObj = await this.getStateAsync(key + ".ref" + day);
618
- const refDay = refDayObj ? refDayObj.val : -1;
619
-
620
- const valCurObj = await this.getStateAsync(name);
621
- const valCur = valCurObj ? valCurObj.val : 0;
622
-
623
- const valRefObj = await this.getStateAsync(key + refValue);
624
- const valRef = valRefObj ? valRefObj.val : 0;
625
- const valTodayObj = await this.getStateAsync(key + today);
626
- const valToday = valTodayObj ? valTodayObj.val : 0;
627
-
628
- const descToday = (state_attr[key + today] !== undefined) ? state_attr[key + today].name : key;
629
- const unitToday = (state_attr[key + today] !== undefined) ? state_attr[key + today].unit : "";
630
- const descYesterday = (state_attr[key + yesterday] !== undefined) ? state_attr[key + yesterday].name : key;
631
- const unitYesterday = (state_attr[key + yesterday] !== undefined) ? state_attr[key + yesterday].unit : "";
632
- const descRef = (state_attr[key + refValue] !== undefined) ? state_attr[key + refValue].name : key;
633
- const unitRef = (state_attr[key + refValue] !== undefined) ? state_attr[key + refValue].unit : "";
634
- const descRefDay = (state_attr[key + ".ref" + day] !== undefined) ? state_attr[key + ".ref" + day].name : key;
635
- const unitRefDay = (state_attr[key + ".ref" + day] !== undefined) ? state_attr[key + ".ref" + day].unit : "";
636
-
637
- if (refDay != curDay) {
638
- this.log.debug("(Calc) New " + day + " (or first value seen). Updating stat data for: " + name.substring(10));
639
- // Change of day
640
- await this.doState(key + ".ref" + day, curDay, descRefDay, unitRefDay, false);
641
- await this.doState(key + yesterday, valToday, descYesterday, unitYesterday, false);
642
- await this.doState(key + today, 0, descToday, unitToday, false);
643
- if (valRef < valCur) {
644
- await this.doState(key + refValue, valCur, descRef, unitRef, true);
645
- } else {
646
- this.log.warn("(Calc) Not updating reference value for: " + name.substring(10) + "! Old RefValue (" + valRef + ") >= new RefValue (" + valCur + "). Impossible situation. If this is intentional, please update via admin!");
647
- }
648
- } else {
649
- this.log.debug("(Calc) Updating " + day +" value for: " + name.substring(10) + ": " + Number((valCur - valRef).toFixed(2)));
650
- // update today's value
651
- await this.doState(key + today, Number((valCur - valRef).toFixed(2)), descToday, unitToday, false);
652
- }
653
-
654
- if (name === "STATISTIC.LIVE_HOUSE_CONS") await this.updateAutarkyHelper(today, yesterday, day, curDay); // otherwise we get way too many updates
655
-
656
- }
657
-
658
- async updateAutarkyHelper(today, yesterday, day, curDay) {
659
- // soon to be deprecated
660
- const key = "_calc.Autarky";
661
-
662
- // reference object to decide on change of day
663
- const refDayObj = await this.getStateAsync(key + ".ref" + day);
664
- const refDay = refDayObj ? refDayObj.val : -1;
665
- // current day's value (needed in case of day-change)
666
- const valTodayObj = await this.getStateAsync(key + today);
667
- const valToday = valTodayObj ? valTodayObj.val : 0;
668
-
669
- // reading values required for calc
670
- const valBatChargeObj = await this.getStateAsync("_calc.LIVE_BAT_CHARGE_MASTER" + today);
671
- const valBatCharge = valBatChargeObj ? valBatChargeObj.val : 0;
672
- const valBatDischargeObj = await this.getStateAsync("_calc.LIVE_BAT_DISCHARGE_MASTER" + today);
673
- const valBatDischarge = valBatDischargeObj ? valBatDischargeObj.val : 0;
674
- const valGridExpObj = await this.getStateAsync("_calc.LIVE_GRID_EXPORT" + today);
675
- const valGridExp = valGridExpObj ? valGridExpObj.val : 0;
676
- const valGridImpObj = await this.getStateAsync("_calc.LIVE_GRID_IMPORT" + today);
677
- const valGridImp = valGridImpObj ? valGridImpObj.val : 0;
678
- const valHouseConsObj = await this.getStateAsync("_calc.LIVE_HOUSE_CONS" + today);
679
- const valHouseCons = valHouseConsObj ? valHouseConsObj.val : 1;
680
- const valPVGenObj = await this.getStateAsync("_calc.LIVE_PV_GEN" + today);
681
- const valPVGen = valPVGenObj ? valPVGenObj.val : 0;
682
-
683
- const descToday = (state_attr[key + today] !== undefined) ? state_attr[key + today].name : key;
684
- const unitToday = (state_attr[key + today] !== undefined) ? state_attr[key + today].unit : "%";
685
- const descYesterday = (state_attr[key + yesterday] !== undefined) ? state_attr[key + yesterday].name : key;
686
- const unitYesterday = (state_attr[key + yesterday] !== undefined) ? state_attr[key + yesterday].unit : "%";
687
- const descRefDay = (state_attr[key + ".ref" + day] !== undefined) ? state_attr[key + ".ref" + day].name : key;
688
- const unitRefDay = (state_attr[key + ".ref" + day] !== undefined) ? state_attr[key + ".ref" + day].unit : "";
689
-
690
- if (refDay != curDay) {
691
- this.log.debug("(Autarky) New " + day + " (or first value seen). Updating Autarky data for: " + key + " " + day);
692
- // Change of day
693
- await this.doState(key + ".ref" + day, curDay, descRefDay, unitRefDay, false);
694
- await this.doState(key + yesterday, valToday, descYesterday, unitYesterday, false);
695
- // await this.doState(key + today, 0, descToday, unitToday, false); // we don't need to reset autarky to 0 because it is calculated by reference values.
696
- // instead do the regular calc right after the change of day
697
- }
698
- // update today's value - but beware of div/0
699
- var newVal = 0;
700
- if (valHouseCons > 0) {
701
- newVal = Number((((valPVGen - valGridExp - valBatCharge + valBatDischarge) / valHouseCons) * 100).toFixed(0));
702
- this.log.debug("(Autarky) Updating Autarky " + day +" value for: " + key + today + ": " + newVal);
703
- await this.doState(key + today, newVal, descToday, unitToday, false);
704
- }
705
- }
706
662
 
707
663
  }
708
664