iobroker.alpha-ess 1.2.0 → 1.3.0-beta.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 CHANGED
@@ -57,12 +57,21 @@ How to find SN and Check code for registration is described here: https://github
57
57
  - **Interval to read charging settings:** Unit: minutes.
58
58
  - **Interval to read discharging settings:** Unit: minutes.
59
59
  - **Interval to read summary data:** Unit: minutes.
60
+ - **Interval to read wallbox data:** Unit: minutes.
60
61
 
61
62
  ## Disclaimer
62
63
 
63
64
  **All product and company names or logos are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them or any associated subsidiaries! This personal project is maintained in spare time and has no business goal.**
64
65
 
65
66
  ## Changelog
67
+ ### 1.3.0-beta.0 (2023-11-18)
68
+
69
+ - (Gaspode) Support wallbox with Open API
70
+
71
+ ### 1.2.1 (2023-11-11)
72
+
73
+ - (Gaspode) Fixed severe error in ClosedAPI
74
+
66
75
  ### 1.2.0 (2023-11-10)
67
76
 
68
77
  - (Gaspode) Added additional realtime attributes for OpenAPI
@@ -13,5 +13,6 @@
13
13
  "Personal APP Secret": "Persönliches Application Secret",
14
14
  "Interval to read charging settings": "Intervall zum Lesen der Ladeeinstellungen [min]",
15
15
  "Interval to read discharging settings": "Intervall zum Lesen der Entladeeinstellungen [min]",
16
+ "Interval to read wallbox data": "Intervall zum Auslesen der Wallbox-Daten [min]",
16
17
  "Sorry. Closed API currently not supported!": "Entschuldigung. Closed API wird aufgrund von Änderungen durch Alpha-ESS derzeit nicht unterstützt!"
17
18
  }
@@ -13,5 +13,6 @@
13
13
  "Personal APP Secret": "Personal Application Secret",
14
14
  "Interval to read charging settings": "Interval to read charging settings [min]",
15
15
  "Interval to read discharging settings": "Interval to read discharging settings [min]",
16
+ "Interval to read wallbox data": "Interval to read wallbox data [min]",
16
17
  "Sorry. Closed API currently not supported!": "Sorry. Closed API currently not supported due to changes by Alpha-ESS!"
17
18
  }
@@ -13,5 +13,6 @@
13
13
  "Personal APP Secret": "Secreto de aplicación personal",
14
14
  "Interval to read charging settings": "Intervalo para leer la configuración de carga",
15
15
  "Interval to read discharging settings": "Intervalo para leer la configuración de descarga",
16
+ "Interval to read wallbox data": "Intervalo para leer los datos del wallbox [min]",
16
17
  "Sorry. Closed API currently not supported!": "Lo siento. ¡La API cerrada actualmente no es compatible debido a cambios realizados por Alpha-ESS!"
17
18
  }
@@ -13,5 +13,6 @@
13
13
  "Personal APP Secret": "Secret d'application personnel",
14
14
  "Interval to read charging settings": "Intervalle pour lire les paramètres de charge",
15
15
  "Interval to read discharging settings": "Intervalle pour lire les paramètres de décharge",
16
+ "Interval to read wallbox data": "Intervalle de lecture des données de la wallbox [min]",
16
17
  "Sorry. Closed API currently not supported!": "Désolé. API fermée actuellement non prise en charge en raison de modifications apportées par Alpha-ESS !"
17
18
  }
@@ -13,5 +13,6 @@
13
13
  "Personal APP Secret": "Segreto dell'applicazione personale",
14
14
  "Interval to read charging settings": "Intervallo per leggere le impostazioni di ricarica",
15
15
  "Interval to read discharging settings": "Intervallo per leggere le impostazioni di scarica",
16
+ "Interval to read wallbox data": "Intervallo per leggere i dati della Wallbox [min]",
16
17
  "Sorry. Closed API currently not supported!": "Scusa. API chiusa attualmente non supportata a causa di modifiche apportate da Alpha-ESS!"
17
18
  }
@@ -13,5 +13,6 @@
13
13
  "Personal APP Secret": "Persoonlijk toepassingsgeheim",
14
14
  "Interval to read charging settings": "Interval om laadinstellingen te lezen",
15
15
  "Interval to read discharging settings": "Interval om ontlaadinstellingen te lezen",
16
+ "Interval to read wallbox data": "Interval voor het lezen van wallbox-gegevens [min]",
16
17
  "Sorry. Closed API currently not supported!": "Sorry. Gesloten API momenteel niet ondersteund vanwege wijzigingen door Alpha-ESS!"
17
18
  }
@@ -13,5 +13,6 @@
13
13
  "Personal APP Secret": "Tajny wniosek osobisty",
14
14
  "Interval to read charging settings": "Interwał odczytu ustawień ładowania",
15
15
  "Interval to read discharging settings": "Interwał odczytu ustawień rozładowania",
16
+ "Interval to read wallbox data": "Interwał odczytu danych wallboxa [min]",
16
17
  "Sorry. Closed API currently not supported!": "Przepraszam. Zamknięte API obecnie nie jest obsługiwane ze względu na zmiany wprowadzone przez Alpha-ESS!"
17
18
  }
@@ -13,5 +13,6 @@
13
13
  "Personal APP Secret": "Segredo de aplicativo pessoal",
14
14
  "Interval to read charging settings": "Intervalo para ler as configurações de carregamento",
15
15
  "Interval to read discharging settings": "Intervalo para ler as configurações de descarga",
16
+ "Interval to read wallbox data": "Intervalo para leitura dos dados da Wallbox [min]",
16
17
  "Sorry. Closed API currently not supported!": "Desculpe. API fechada atualmente não suportada devido a alterações do Alpha-ESS!"
17
18
  }
@@ -13,5 +13,6 @@
13
13
  "Personal APP Secret": "Секрет личного приложения",
14
14
  "Interval to read charging settings": "Интервал чтения настроек зарядки",
15
15
  "Interval to read discharging settings": "Интервал чтения настроек разрядки",
16
+ "Interval to read wallbox data": "Интервал чтения данных Wallbox [мин]",
16
17
  "Sorry. Closed API currently not supported!": "Извини. Закрытый API в настоящее время не поддерживается из-за изменений Alpha-ESS!"
17
18
  }
@@ -13,5 +13,6 @@
13
13
  "Personal APP Secret": "Особистий секрет програми",
14
14
  "Interval to read charging settings": "Інтервал зчитування параметрів заряджання",
15
15
  "Interval to read discharging settings": "Інтервал зчитування параметрів розрядки",
16
+ "Interval to read wallbox data": "Інтервал зчитування даних Wallbox [хв]",
16
17
  "Sorry. Closed API currently not supported!": "вибач Закритий API наразі не підтримується через зміни Alpha-ESS!"
17
18
  }
@@ -13,5 +13,6 @@
13
13
  "Personal APP Secret": "个人申请秘诀",
14
14
  "Interval to read charging settings": "读取充电设置的间隔",
15
15
  "Interval to read discharging settings": "读取放电设置的间隔",
16
+ "Interval to read wallbox data": "读取 Wallbox 数据的时间间隔 [min]",
16
17
  "Sorry. Closed API currently not supported!": "对不起。由于 Alpha-ESS 的更改,目前不支持封闭 API!"
17
18
  }
@@ -155,6 +155,20 @@
155
155
  "disabled": "!data.enableSummarydata",
156
156
  "hidden": "data.apiType == 1 || data.apiType == 3"
157
157
  },
158
+ "enableWallbox": {
159
+ "type": "checkbox",
160
+ "newLine": true,
161
+ "hidden": "true"
162
+ },
163
+ "intervalWallboxMins": {
164
+ "sm": 5,
165
+ "min": 1,
166
+ "type": "number",
167
+ "label": "Interval to read wallbox data",
168
+ "newLine": false,
169
+ "disabled": "!data.oAEnableWallbox",
170
+ "hidden": "true"
171
+ },
158
172
  "oAEnableRealtime": {
159
173
  "type": "checkbox",
160
174
  "newLine": true,
@@ -253,6 +267,20 @@
253
267
  "disabled": "!data.oAEnableSummary",
254
268
  "hidden": "data.apiType == 0"
255
269
  },
270
+ "oAEnableWallbox": {
271
+ "type": "checkbox",
272
+ "newLine": true,
273
+ "hidden": "data.apiType == 0"
274
+ },
275
+ "oAIntervalWallboxMins": {
276
+ "sm": 5,
277
+ "min": 1,
278
+ "type": "number",
279
+ "label": "Interval to read wallbox data",
280
+ "newLine": false,
281
+ "disabled": "!data.oAEnableWallbox",
282
+ "hidden": "data.apiType == 0"
283
+ },
256
284
  "updateUnchangedStates": {
257
285
  "type": "checkbox",
258
286
  "label": "Update unchanged states",
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "alpha-ess",
4
- "version": "1.2.0",
4
+ "version": "1.3.0-beta.0",
5
5
  "news": {
6
+ "1.3.0-beta.0": {
7
+ "en": "Support wallbox with Open API",
8
+ "de": "Wallbox Unterstützung mit Open API",
9
+ "ru": "Поддержка настенного ящика с Open API",
10
+ "pt": "Suporte wallbox com API aberta",
11
+ "nl": "Steun muur met open API",
12
+ "fr": "Porte-monnaie support avec Open API",
13
+ "it": "Supporto wallbox con Open API",
14
+ "es": "Soporte de pared con Open API",
15
+ "pl": "Współdzielnia z API Open",
16
+ "uk": "Підтримка настінної коробки з відкритим API",
17
+ "zh-cn": "A. 开放式API的支助墙箱"
18
+ },
19
+ "1.2.1": {
20
+ "en": "Fixed severe error in ClosedAPI",
21
+ "de": "Schweren Fehler in ClosedAPI behoben",
22
+ "ru": "Исправлена тяжелая ошибка в ClosedAPI",
23
+ "pt": "Erro grave fixo em ClosedAPI",
24
+ "nl": "Een ernstige fout in ClosedAPI",
25
+ "fr": "Erreur sévère fixe dans le fichier FerméAPI",
26
+ "it": "Risolto grave errore in ClosedAPI",
27
+ "es": "Error severo corregido en CerradaAPI",
28
+ "pl": "Szczegółowy błąd w ClosedAPI",
29
+ "uk": "Виправлено тяжку помилку в ClosedAPI",
30
+ "zh-cn": "A. 近似严重错误"
31
+ },
6
32
  "1.2.0": {
7
33
  "en": "Added additional realtime attributes for OpenAPI",
8
34
  "de": "Zusätzliche Echtzeit-Attribute für OpenAPI hinzugefügt",
@@ -67,19 +93,6 @@
67
93
  "pl": "Adapted fetching energy values używając 'Closed API' do najnowszych zmian API przez Alpha-ESS",
68
94
  "uk": "Адаптивовані коефіцієнти відтікання енергії за допомогою 'Closed API' для останніх змін API від Alpha-ESS",
69
95
  "zh-cn": "利用“无能”的能源价值降低到Alpha-ESS新生动的改变"
70
- },
71
- "1.0.0": {
72
- "en": "Support also the new official OpenAPI provided by Alpha-ESS\nSet state quality accordingly to status of data\nWriting charging and discharging settings implemented for 'Closed API' and OpenAPI\nRemove no more supported states at startup automatically",
73
- "de": "Unterstützung der neuen offiziellen OpenAPI von Alpha-ESS\nQuality von States wird jetzt entsprechend des Zustands der Daten gesetzt\nSchreiben von Lade- und Entladeeinstellungen für 'Closed API' und OpenAPI implementiert\nNicht mehr unterstützte States werden bei Adapter-Neustart automatisch gelöscht",
74
- "ru": "Поддержка также новый официальный OpenAPI, предоставленный Alpha-ESS\nУстановите государственное качество в соответствии с статусом данных\nНаписание зарядки и разгрузки настроек, реализованных для 'Closed API' и OpenAPI\nУдалить больше не поддерживаемых состояний при запуске автоматически",
75
- "pt": "Suporte também o novo OpenAPI oficial fornecido pela Alpha-ESS\nDefina a qualidade do estado de acordo com o status dos dados\nEscrevendo as configurações de carregamento e descarregamento implementadas para ' API fechada' e OpenAPI\nRemover estados não mais suportados na inicialização automaticamente",
76
- "nl": "Vertaling:\nZet de staatskwaliteit in aanmerking van gegevens\nSchrijven en ontladen opstellingen voor 'Closed API' en OpenAPI'\nVerwijder geen ondersteunende staten bij start-up automatisch",
77
- "fr": "Soutien également le nouveau OpenAPI officiel fourni par Alpha-ESS\nDéfinir la qualité de l'état en conséquence à l'état des données\nRédaction des paramètres de chargement et de déchargement mis en œuvre pour 'API perdu' et OpenAPI\nEnlever plus d'états supportés au démarrage automatiquement",
78
- "it": "Supporto anche il nuovo OpenAPI ufficiale fornito da Alpha-ESS\nImpostare la qualità dello stato di conseguenza allo stato dei dati\nScrivere le impostazioni di ricarica e discarica implementate per 'Closed API' e OpenAPI\nNon rimuovere più stati supportati all'avvio automaticamente",
79
- "es": "Apoyar también el nuevo OpenAPI oficial proporcionado por Alpha-ESS\nEstablecer la calidad del estado en consecuencia al estado de los datos\nEscribir ajustes de carga y descarga implementados para 'Closed API' y OpenAPI\nEliminar no más estados compatibles en el inicio automáticamente",
80
- "pl": "Wspiera również nowy oficjalny interfejs OpenAPI zapewniany przez Alpha-ESS\nUstalono jakość państwa zgodnie z statusem danych\nPisanie ładowania i rozładowania wdrożonych ustawień API oraz OpenAPI\nRemove nie będzie więcej wspieranych państw",
81
- "uk": "Підтримка також нових офіційних OpenAPI, що надається Альфа-ESS\nВстановити якість держави відповідно до стану даних\nНаписання параметрів зарядки та відключення, що реалізовані для \"Closed API\" та OpenAPI\nВидаліть не більше підтримуваних держав при запуску автоматично",
82
- "zh-cn": "还支持阿尔法-萨斯新官方开放协会\n相应地确定数据状况的国家质量\n确定和履行执行的消费和开放的消费者协会和开放协会环境\n自动取消不再支持的开办国家"
83
96
  }
84
97
  },
85
98
  "titleLang": {
@@ -169,6 +182,8 @@
169
182
  "intervalStatisticalTodaydataMins": 5,
170
183
  "enableSummarydata": false,
171
184
  "intervalSummarydataMins": 5,
185
+ "enableWallbox": false,
186
+ "intervalWallboxMins": 5,
172
187
  "updateUnchangedStates": false,
173
188
  "appID": "",
174
189
  "appSecret": "",
@@ -186,7 +201,9 @@
186
201
  "oAEnableStatisticsToday": false,
187
202
  "oAIntervalStatisticsTodayMins": 5,
188
203
  "oAEnableSummary": true,
189
- "oAIntervalSummaryMins": 5
204
+ "oAIntervalSummaryMins": 5,
205
+ "oAEnableWallbox": false,
206
+ "oAIntervalWallboxMins": 5
190
207
  },
191
208
  "objects": [],
192
209
  "instanceObjects": [
package/main.js CHANGED
@@ -558,7 +558,54 @@ class OpenAPI {
558
558
  , type: 'number'
559
559
  , unit: 'kWh'
560
560
  }]
561
+ },
562
+ {
563
+ Group: 'Wallbox'
564
+ , fnct: this.getWallboxData.bind(this)
565
+ , enabledName: 'oAEnableWallbox'
566
+ , intervalName: 'oAIntervalWallboxMins'
567
+ , intervalFactor: 60
568
+ , states: [
569
+ {
570
+ alphaAttrName: 'evchargerSn'
571
+ , role: 'value'
572
+ , id: 'SN'
573
+ , name: 'Wallbox serial number'
574
+ , type: 'string'
575
+ , unit: ''
576
+ , isStatic: true
577
+ },
578
+ {
579
+ alphaAttrName: 'evchargerModel'
580
+ , role: 'value'
581
+ , id: 'Model'
582
+ , name: 'Wallbox model'
583
+ , type: 'string'
584
+ , unit: ''
585
+ , isStatic: true
586
+ },
587
+ {
588
+ alphaAttrName: 'evchargerStatus'
589
+ , role: 'value'
590
+ , id: 'Status'
591
+ , name: 'Wallbox status'
592
+ , type: 'number'
593
+ , unit: ''
594
+ , states: {
595
+ 0: '0 - Unknown',
596
+ 1: '1 - Available state (not plugged in)',
597
+ 2: '2 - Preparing state of insertion (plugged in and not activated)',
598
+ 3: '3 - Charging state (charging with power output)',
599
+ 4: '4 - SuspendedEVSE pile Suspended at the terminal (already started but no available power)',
600
+ 5: '5 - SuspendedEV Suspended at the vehicle end (with available power, waiting for the car to respond)',
601
+ 6: '6 - Finishing The charging end state (actively swiping the card to stop or EMS stop control)',
602
+ 7: '7 - Unknown',
603
+ 8: '8 - Unknown',
604
+ 9: '9 - Faulted fault state (pile failure)'
605
+ }
606
+ }]
561
607
  }];
608
+
562
609
  this.adapter = adapter;
563
610
  this.emptyBody = { data: null };
564
611
  }
@@ -648,7 +695,7 @@ class OpenAPI {
648
695
  }
649
696
  }
650
697
  catch (e) {
651
- this.adapter.log.error('Reading data for group ' + group + ': Exception occurred: ' + e);
698
+ this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
652
699
  await this.handleError(this.emptyBody, group);
653
700
  }
654
701
  await this.startGroupTimeout(group);
@@ -674,7 +721,7 @@ class OpenAPI {
674
721
  }
675
722
  }
676
723
  catch (e) {
677
- this.adapter.log.error('Reading data for group ' + group + ': Exception occurred: ' + e);
724
+ this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
678
725
  await this.handleError(this.emptyBody, group);
679
726
  }
680
727
  await this.startGroupTimeout(group);
@@ -712,7 +759,7 @@ class OpenAPI {
712
759
  }
713
760
  }
714
761
  catch (e) {
715
- this.adapter.log.error('Reading data for group ' + group + ': Exception occurred: ' + e);
762
+ this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
716
763
  await this.handleError(this.emptyBody, group);
717
764
  }
718
765
  await this.startGroupTimeout(group);
@@ -736,7 +783,7 @@ class OpenAPI {
736
783
  }
737
784
  }
738
785
  catch (e) {
739
- this.adapter.log.error('Reading data for group ' + group + ': Exception occurred: ' + e);
786
+ this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
740
787
  await this.handleError(this.emptyBody, group);
741
788
  }
742
789
  await this.startGroupTimeout(group);
@@ -762,12 +809,76 @@ class OpenAPI {
762
809
  }
763
810
  }
764
811
  catch (e) {
765
- this.adapter.log.error('Reading data for group ' + group + ': Exception occurred: ' + e);
812
+ this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
813
+ await this.handleError(this.emptyBody, group);
814
+ }
815
+ await this.startGroupTimeout(group);
816
+ }
817
+
818
+ /**
819
+ * @param {string} group
820
+ */
821
+ async getWallboxData(group) {
822
+ try {
823
+ this.adapter.stopGroupTimeout(group);
824
+
825
+ this.adapter.log.debug('Fetching ' + group + ' data...');
826
+
827
+ // First we need to get SN if not already done:
828
+ let snState = await this.adapter.getStateAsync(`${group}.SN`);
829
+ if (!snState || typeof snState.val === 'string' && snState.val.length == 0) {
830
+ await this.getWallboxSn(group);
831
+ snState = await this.adapter.getStateAsync(`${group}.SN`);
832
+ // In this special case we reset the created indicator because more states must be created for this group in the next step
833
+ this.adapter.createdStates[group] = false;
834
+ }
835
+
836
+ if (snState && typeof snState.val === 'string' && snState.val.length > 0) {
837
+ this.adapter.log.debug(`Using Wallbox SN: ${snState.val}`);
838
+ const res = await this.getRequest(`getEvChargerStatusBySn?sysSn=${this.adapter.config.systemId}&evchargerSn=${snState.val}`, {});
839
+ if (res && res['status'] == 200 && res.data && res.data.data) {
840
+ await this.adapter.createAndUpdateStates(group, res.data.data);
841
+ }
842
+ else {
843
+ await this.handleError(res, group);
844
+ }
845
+ }
846
+ else {
847
+ this.adapter.log.error('No wallbox SN could be found!');
848
+ }
849
+ }
850
+ catch (e) {
851
+ this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
766
852
  await this.handleError(this.emptyBody, group);
767
853
  }
768
854
  await this.startGroupTimeout(group);
769
855
  }
770
856
 
857
+ /**
858
+ * @param {string} group
859
+ */
860
+ async getWallboxSn(group) {
861
+ try {
862
+ this.adapter.log.debug('Fetching Wallbox SN ...');
863
+
864
+ const res = await this.getRequest(`getEvChargerConfigList?sysSn=${this.adapter.config.systemId}`, {});
865
+ if (res && res['status'] == 200 && res.data && res.data.data) {
866
+
867
+ if (res.data.data.length > 1) {
868
+ this.adapter.log.warn('More than one wallbox found! Only the first wallbox is currently supported by this adapter!');
869
+ }
870
+ await this.adapter.createAndUpdateStates(group, res.data.data[0]);
871
+ }
872
+ else {
873
+ await this.handleError(res, group);
874
+ }
875
+ }
876
+ catch (e) {
877
+ this.adapter.log.error('Fetching Wallbox SN: Exception occurred: ' + e);
878
+ await this.handleError(this.emptyBody, group);
879
+ }
880
+ }
881
+
771
882
  /**
772
883
  * @param {string} group
773
884
  */
@@ -848,24 +959,28 @@ class OpenAPI {
848
959
  await this.adapter.setStateChangedAsync('info.connection', false, true);
849
960
  this.adapter.errorCount++;
850
961
  if (res.data && res.data.code && res.data.code != 0) {
851
- this.adapter.log.error('Alpha ESS Api returns an error!');
962
+ this.adapter.log.error(`Alpha ESS Api returns an error! Group: ${group}`);
852
963
  switch (res.data.code) {
853
- case 6001: this.adapter.log.error(`Error: ${res.data.code} - Parameter error (#${this.adapter.errorCount})`); break;
854
- case 6002: this.adapter.log.error(`Error: ${res.data.code} - The SN is not bound to the user (#${this.adapter.errorCount})`); break;
855
- case 6003: this.adapter.log.error(`Error: ${res.data.code} - You have bound this SN (#${this.adapter.errorCount})`); break;
856
- case 6004: this.adapter.log.error(`Error: ${res.data.code} - CheckCode error (#${this.adapter.errorCount})`); break;
857
- case 6005: this.adapter.log.error(`Error: ${res.data.code} - This appId is not bound to the SN (#${this.adapter.errorCount})`); break;
858
- case 6006: this.adapter.log.error(`Error: ${res.data.code} - Timestamp error (#${this.adapter.errorCount})`); break;
859
- case 6007: this.adapter.log.error(`Error: ${res.data.code} - Sign verification error (#${this.adapter.errorCount})`); break;
860
- case 6008: this.adapter.log.error(`Error: ${res.data.code} - Set failed (#${this.adapter.errorCount})`); break;
861
- case 6009: this.adapter.log.error(`Error: ${res.data.code} - Whitelist verification failed (#${this.adapter.errorCount})`); break;
862
- case 6010: this.adapter.log.error(`Error: ${res.data.code} - Sign is empty (#${this.adapter.errorCount})`); break;
863
- case 6011: this.adapter.log.error(`Error: ${res.data.code} - timestamp is empty (#${this.adapter.errorCount})`); break;
864
- case 6012: this.adapter.log.error(`Error: ${res.data.code} - AppId is empty (#${this.adapter.errorCount})`); break;
865
- case 6026: this.adapter.log.error(`Error: ${res.data.code} - Internal Error (#${this.adapter.errorCount})`); break;
866
- case 6046: this.adapter.log.error(`Error: ${res.data.code} - Verification code error (#${this.adapter.errorCount})`); break;
867
- case 6053: this.adapter.log.error(`Error: ${res.data.code} - The request was too fast, please try again later (#${this.adapter.errorCount})`); break;
868
- default: this.adapter.log.error(`Error: ${res.data.code} - Unknown error (#${this.adapter.errorCount})`);
964
+ case 6001: this.adapter.log.info(`Error code: ${res.data.code} - Parameter error (#${this.adapter.errorCount})`); break;
965
+ case 6002: this.adapter.log.info(`Error code: ${res.data.code} - The SN is not bound to the user (#${this.adapter.errorCount})`); break;
966
+ case 6003: this.adapter.log.info(`Error code: ${res.data.code} - You have bound this SN (#${this.adapter.errorCount})`); break;
967
+ case 6004: this.adapter.log.info(`Error code: ${res.data.code} - CheckCode error (#${this.adapter.errorCount})`); break;
968
+ case 6005: this.adapter.log.info(`Error code: ${res.data.code} - This appId is not bound to the SN (#${this.adapter.errorCount})`); break;
969
+ case 6006: this.adapter.log.info(`Error code: ${res.data.code} - Timestamp error (#${this.adapter.errorCount})`); break;
970
+ case 6007: this.adapter.log.info(`Error code: ${res.data.code} - Sign verification error (#${this.adapter.errorCount})`); break;
971
+ case 6008: this.adapter.log.info(`Error code: ${res.data.code} - Set failed (#${this.adapter.errorCount})`); break;
972
+ case 6009: this.adapter.log.info(`Error code: ${res.data.code} - Whitelist verification failed (#${this.adapter.errorCount})`); break;
973
+ case 6010: this.adapter.log.info(`Error code: ${res.data.code} - Sign is empty (#${this.adapter.errorCount})`); break;
974
+ case 6011: this.adapter.log.info(`Error code: ${res.data.code} - timestamp is empty (#${this.adapter.errorCount})`); break;
975
+ case 6012: this.adapter.log.info(`Error code: ${res.data.code} - AppId is empty (#${this.adapter.errorCount})`); break;
976
+ case 6016: this.adapter.log.info(`Error code: ${res.data.code} - Data does not exist or has been deleted (#${this.adapter.errorCount})`); break;
977
+ case 6026: this.adapter.log.info(`Error code: ${res.data.code} - Internal Error (#${this.adapter.errorCount})`); break;
978
+ case 6029: this.adapter.log.info(`Error code: ${res.data.code} - operation failed (#${this.adapter.errorCount})`); break;
979
+ case 6038: this.adapter.log.info(`Error code: ${res.data.code} - system sn does not exist (#${this.adapter.errorCount})`); break;
980
+ case 6042: this.adapter.log.info(`Error code: ${res.data.code} - system offline (#${this.adapter.errorCount})`); break;
981
+ case 6046: this.adapter.log.info(`Error code: ${res.data.code} - Verification code error (#${this.adapter.errorCount})`); break;
982
+ case 6053: this.adapter.log.info(`Error code: ${res.data.code} - The request was too fast, please try again later (#${this.adapter.errorCount})`); break;
983
+ default: this.adapter.log.info(`Error code: ${res.data.code} - Unknown error (#${this.adapter.errorCount})`);
869
984
  }
870
985
  if (res.data.code == 6002 ||
871
986
  res.data.code == 6003 ||
@@ -880,7 +995,7 @@ class OpenAPI {
880
995
  }
881
996
  }
882
997
  else {
883
- this.adapter.log.error(`Unknown error occurred: ${JSON.stringify(res.data)} (#${this.adapter.errorCount})`);
998
+ this.adapter.log.error(`Unknown error occurred: ${JSON.stringify(res.data)} (#${this.adapter.errorCount}) Group:${group}`);
884
999
  }
885
1000
  await this.adapter.setQualityForGroup(group, 0x44);
886
1001
  }
@@ -1521,6 +1636,15 @@ class ClosedAPI {
1521
1636
  , unit: ''
1522
1637
  , dayIndex: false
1523
1638
  }]
1639
+ },
1640
+ {
1641
+ // Just a dummy to ensure that this group is deleted
1642
+ Group: 'Wallbox'
1643
+ , fnct: this.fetchWallboxDataDummy.bind(this)
1644
+ , enabledName: 'enableWallbox'
1645
+ , intervalName: 'intervalWallboxMins'
1646
+ , intervalFactor: 60
1647
+ , states: []
1524
1648
  }];
1525
1649
 
1526
1650
  this.Auth =
@@ -1796,6 +1920,13 @@ class ClosedAPI {
1796
1920
  this.adapter.log.warn(`Internal error (group ${group}): function fetchSettingsDischargeDataDummy should never be called.`);
1797
1921
  }
1798
1922
 
1923
+ /**
1924
+ * @param {string} group
1925
+ */
1926
+ async fetchWallboxDataDummy(group) {
1927
+ this.adapter.log.warn(`Internal error (group ${group}): function fetchWallboxDataDummy should never be called.`);
1928
+ }
1929
+
1799
1930
  /**
1800
1931
  * Get realtime data from alpha-ess and start timer for next execution
1801
1932
  * @param {string} group
@@ -2072,12 +2203,14 @@ class AlphaEss extends utils.Adapter {
2072
2203
  this.log.debug('config oAIntervalSettingsChargeMins ' + this.config.oAIntervalSettingsChargeMins);
2073
2204
  this.log.debug('config oAIntervalSettingsDischargeMins ' + this.config.oAIntervalSettingsDischargeMins);
2074
2205
  this.log.debug('config oAIntervalSummaryMins: ' + this.config.oAIntervalSummaryMins);
2075
- this.log.debug('config enableRealtimedata: ' + this.config.oAEnableRealtime);
2076
- this.log.debug('config enableEnergydata: ' + this.config.oAEnableEnergy);
2077
- this.log.debug('config enableSettingsdata: ' + this.config.oAEnableSettingsCharge);
2078
- this.log.debug('config enableStatisticalTodaydata: ' + this.config.oAEnableSettingsDischarge);
2079
- this.log.debug('config enableSummarydata: ' + this.config.oAEnableSettingsDischarge);
2080
- this.log.debug('config enableSummarydata: ' + this.config.oAEnableSummary);
2206
+ this.log.debug('config oAIntervalWallboxMins: ' + this.config.oAIntervalWallboxMins);
2207
+ this.log.debug('config oAEnableRealtime: ' + this.config.oAEnableRealtime);
2208
+ this.log.debug('config oAEnableEnergy: ' + this.config.oAEnableEnergy);
2209
+ this.log.debug('config oAEnableSettingsCharge: ' + this.config.oAEnableSettingsCharge);
2210
+ this.log.debug('config oAEnableSettingsCharge: ' + this.config.oAEnableSettingsCharge);
2211
+ this.log.debug('config oAEnableSettingsDischarge: ' + this.config.oAEnableSettingsDischarge);
2212
+ this.log.debug('config oAEnableSummary: ' + this.config.oAEnableSummary);
2213
+ this.log.debug('config oAEnableWallbox: ' + this.config.oAEnableWallbox);
2081
2214
  this.log.debug('config updateUnchangedStates: ' + this.config.updateUnchangedStates);
2082
2215
  }
2083
2216
 
@@ -2420,15 +2553,17 @@ class AlphaEss extends utils.Adapter {
2420
2553
 
2421
2554
  // Create all states for received elements
2422
2555
  for (const [alphaAttrName, rawValue] of Object.entries(data)) {
2423
- const stateInfo = this.getStateInfoByAlphaAttrName(group, alphaAttrName);
2556
+ const stateInfo = await this.getStateInfoByAlphaAttrName(group, alphaAttrName);
2424
2557
  if (typeof data[alphaAttrName] !== 'object') {
2425
- this.createStateForAttribute(group, data, rawValue, alphaAttrName, stateInfo, setObjectFunc);
2558
+ await this.createStateForAttribute(group, data, rawValue, alphaAttrName, stateInfo, setObjectFunc);
2426
2559
  }
2427
2560
  else {
2428
2561
  // Look for subvalues:
2429
- for (const [alphaAttrName2, rawValue2] of Object.entries(data[alphaAttrName])) {
2430
- const stateInfo2 = this.getStateInfoByAlphaAttrName(group, alphaAttrName2);
2431
- this.createStateForAttribute(group, data[alphaAttrName], rawValue2, alphaAttrName2, stateInfo2, setObjectFunc);
2562
+ if (data[alphaAttrName]) {
2563
+ for (const [alphaAttrName2, rawValue2] of Object.entries(data[alphaAttrName])) {
2564
+ const stateInfo2 = await this.getStateInfoByAlphaAttrName(group, alphaAttrName2);
2565
+ await this.createStateForAttribute(group, data[alphaAttrName], rawValue2, alphaAttrName2, stateInfo2, setObjectFunc);
2566
+ }
2432
2567
  }
2433
2568
  }
2434
2569
  }
@@ -2438,15 +2573,17 @@ class AlphaEss extends utils.Adapter {
2438
2573
 
2439
2574
  // Set values for received states
2440
2575
  for (const [alphaAttrName, rawValue] of Object.entries(data)) {
2441
- const stateInfo = this.getStateInfoByAlphaAttrName(group, alphaAttrName);
2576
+ const stateInfo = await this.getStateInfoByAlphaAttrName(group, alphaAttrName);
2442
2577
  if (typeof data[alphaAttrName] !== 'object') {
2443
- this.setValueForAttribute(group, rawValue, stateInfo, idx);
2578
+ await this.setValueForAttribute(group, rawValue, stateInfo, idx);
2444
2579
  }
2445
2580
  else {
2446
2581
  // Look for subvalues:
2447
- for (const [alphaAttrName2, rawValue2] of Object.entries(data[alphaAttrName])) {
2448
- const stateInfo2 = this.getStateInfoByAlphaAttrName(group, alphaAttrName2);
2449
- this.setValueForAttribute(group, rawValue2, stateInfo2, idx);
2582
+ if (data[alphaAttrName]) {
2583
+ for (const [alphaAttrName2, rawValue2] of Object.entries(data[alphaAttrName])) {
2584
+ const stateInfo2 = await this.getStateInfoByAlphaAttrName(group, alphaAttrName2);
2585
+ await this.setValueForAttribute(group, rawValue2, stateInfo2, idx);
2586
+ }
2450
2587
  }
2451
2588
  }
2452
2589
  }
@@ -2480,9 +2617,11 @@ class AlphaEss extends utils.Adapter {
2480
2617
  , write: stateInfo.writeable ? stateInfo.writeable : false
2481
2618
  , unit: stateInfo.unit === '{money_type}' ? data['money_type'] : stateInfo.unit === '{moneyType}' ? data['moneyType'] : stateInfo.unit
2482
2619
  , desc: stateInfo.alphaAttrName
2620
+ , states: stateInfo.states
2483
2621
  },
2484
2622
  native: {},
2485
2623
  });
2624
+ this.log.debug('Created object ' + group + '.' + this.osn(stateInfo.alphaAttrName) + ' with value ' + rawValue);
2486
2625
  if (stateInfo.writeable) {
2487
2626
  await this.subscribeStatesAsync(`${group}.${stateInfo.id}`);
2488
2627
  this.log.debug(`Subscribed State: ${group}.${stateInfo.id}`);
@@ -2557,7 +2696,7 @@ class AlphaEss extends utils.Adapter {
2557
2696
  * @param {string} Group
2558
2697
  * @param {string} alphaAttrName
2559
2698
  */
2560
- getStateInfoByAlphaAttrName(Group, alphaAttrName) {
2699
+ async getStateInfoByAlphaAttrName(Group, alphaAttrName) {
2561
2700
  try {
2562
2701
  const gidx = this.getStateInfoList().findIndex((/** @type {{ Group: string; }} */ i) => i.Group == Group);
2563
2702
  if (gidx >= 0) {
@@ -2609,16 +2748,29 @@ class AlphaEss extends utils.Adapter {
2609
2748
  */
2610
2749
  async setQualityForGroup(group, q) {
2611
2750
  try {
2612
- const states = await this.getStatesAsync(group + '.*');
2613
- for (const sid in states) {
2614
- const newState = states[sid];
2615
- if (newState.ack) {
2616
- newState.q = q;
2617
- this.log.debug(`Set state ${sid} to val: ${newState.val}; q: ${newState.q}; ack: ${newState.ack}`);
2618
- await this.setStateAsync(sid, newState, true);
2619
- }
2620
- else {
2621
- this.log.debug(`Set state ${sid} NOT to val: ${newState.val}; q: ${newState.q} because ack of this state is ${newState.ack}`);
2751
+ const gidx = this.getStateInfoList().findIndex((/** @type {{ Group: string; }} */ i) => i.Group == group);
2752
+ if (gidx >= 0) {
2753
+ const groupInfo = this.getStateInfoList()[gidx];
2754
+ const groupStates = groupInfo.states;
2755
+ for (let i = 0; i < groupStates.length; i++) {
2756
+ if (!groupStates[i].isStatic) {
2757
+ const newState = await this.getStateAsync(`${groupInfo.Group}.${groupStates[i].id}`);
2758
+ if (newState) {
2759
+ if (newState.q != q && newState.ack) {
2760
+ newState.q = q;
2761
+ this.log.debug(`Set state ${groupInfo.Group}.${groupStates[i].id} to val: ${newState.val}; q: ${newState.q}; ack: ${newState.ack}`);
2762
+ await this.setStateAsync(`${groupInfo.Group}.${groupStates[i].id}`, newState, true);
2763
+ }
2764
+ else {
2765
+ if (!newState.ack) {
2766
+ this.log.silly(`Set state ${groupInfo.Group}.${groupStates[i].id} NOT to val: ${newState.val}; q: ${newState.q} because ack of this state is ${newState.ack}`);
2767
+ }
2768
+ else {
2769
+ this.log.silly(`Set state ${groupInfo.Group}.${groupStates[i].id} NOT to val: ${newState.val}; q: ${newState.q} because quality is unchanged ${newState.q}`);
2770
+ }
2771
+ }
2772
+ }
2773
+ }
2622
2774
  }
2623
2775
  }
2624
2776
  }
@@ -2639,11 +2791,11 @@ class AlphaEss extends utils.Adapter {
2639
2791
  const groupInfo = this.getStateInfoList()[gidx];
2640
2792
  const groupStates = groupInfo.states;
2641
2793
  for (let i = 0; i < groupStates.length; i++) {
2642
- if (groupStates[i].lastUpdateTs) {
2794
+ if (groupStates[i].lastUpdateTs && !groupStates[i].isStatic) {
2643
2795
  if (Date.now() - groupStates[i].lastUpdateTs > (groupInfo.interval * 1000 + REQUEST_TIMEOUT)) {
2644
2796
  const newState = await this.getStateAsync(`${groupInfo.Group}.${groupStates[i].id}`);
2645
2797
  if (newState) {
2646
- if (newState.q != 0 && newState.ack) {
2798
+ if (newState.q == 0 && newState.ack) {
2647
2799
  // Change quality only if it was OK before
2648
2800
  newState.q = 0x01;
2649
2801
  this.log.warn(`Watchdog: State ${groupInfo.Group}.${groupStates[i].id} not updated for ${Date.now() - groupStates[i].lastUpdateTs} ms`);
@@ -2651,7 +2803,12 @@ class AlphaEss extends utils.Adapter {
2651
2803
  await this.setStateAsync(`${groupInfo.Group}.${groupStates[i].id}`, newState, true);
2652
2804
  }
2653
2805
  else {
2654
- this.log.silly(`Watchdog: Quality of state ${groupInfo.Group}.${groupStates[i].id} not changed, was already set to ${newState.q} and ack is ${newState.ack}!`);
2806
+ if (!newState.ack) {
2807
+ this.log.silly(`Set state ${groupInfo.Group}.${groupStates[i].id} NOT to val: ${newState.val}; q: ${newState.q} because ack of this state is ${newState.ack}`);
2808
+ }
2809
+ else {
2810
+ this.log.silly(`Set state ${groupInfo.Group}.${groupStates[i].id} NOT to val: ${newState.val}; q: ${newState.q} because quality is already not OK: ${newState.q}`);
2811
+ }
2655
2812
  }
2656
2813
  }
2657
2814
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.alpha-ess",
3
- "version": "1.2.0",
3
+ "version": "1.3.0-beta.0",
4
4
  "description": "Read and write data from and to Alpha ESS systems.",
5
5
  "author": {
6
6
  "name": "Gaspode",
@@ -46,7 +46,7 @@
46
46
  "mocha": "^10.2.0",
47
47
  "prettier": "^2.8.7",
48
48
  "proxyquire": "^2.1.3",
49
- "sinon": "^15.2.0",
49
+ "sinon": "^17.0.0",
50
50
  "sinon-chai": "^3.7.0",
51
51
  "typescript": "~5.2.2"
52
52
  },