iobroker.alpha-ess 1.2.1 → 1.3.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/admin/i18n/de/translations.json +1 -0
- package/admin/i18n/en/translations.json +1 -0
- package/admin/i18n/es/translations.json +1 -0
- package/admin/i18n/fr/translations.json +1 -0
- package/admin/i18n/it/translations.json +1 -0
- package/admin/i18n/nl/translations.json +1 -0
- package/admin/i18n/pl/translations.json +1 -0
- package/admin/i18n/pt/translations.json +1 -0
- package/admin/i18n/ru/translations.json +1 -0
- package/admin/i18n/uk/translations.json +1 -0
- package/admin/i18n/zh-cn/translations.json +1 -0
- package/admin/jsonConfig.json +28 -0
- package/io-package.json +32 -28
- package/main.js +326 -74
- package/package.json +2 -2
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. Caution: Currently only one Wallbox is supported.
|
|
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.1 (2023-11-21)
|
|
68
|
+
|
|
69
|
+
- (Gaspode) Start and stop charging of wallbox with Open API
|
|
70
|
+
|
|
71
|
+
### 1.3.0-beta.0 (2023-11-18)
|
|
72
|
+
|
|
73
|
+
- (Gaspode) Support wallbox with Open API
|
|
74
|
+
|
|
66
75
|
### 1.2.1 (2023-11-11)
|
|
67
76
|
|
|
68
77
|
- (Gaspode) Fixed severe error in ClosedAPI
|
|
@@ -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
|
}
|
package/admin/jsonConfig.json
CHANGED
|
@@ -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.
|
|
4
|
+
"version": "1.3.0-beta.1",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.3.0-beta.1": {
|
|
7
|
+
"en": "Start and stop charging of wallbox with Open API",
|
|
8
|
+
"de": "Starten und stoppen des Ladevorgangs der Wallbox mit Open API",
|
|
9
|
+
"ru": "Начните и остановите зарядку настенного ящика с Open API",
|
|
10
|
+
"pt": "Iniciar e parar de carregar de wallbox com API aberta",
|
|
11
|
+
"nl": "Begin en stop met het inladen van een muurkist met open API",
|
|
12
|
+
"fr": "Démarrer et arrêter le chargement de la boîte murale avec Open API",
|
|
13
|
+
"it": "Avviare e interrompere la ricarica di wallbox con Open API",
|
|
14
|
+
"es": "Comience y deje de cargar Wallbox con Open API",
|
|
15
|
+
"pl": "Start i zatrzymanie ładowania skrzynki z Open API",
|
|
16
|
+
"uk": "Старт і зупинка зарядки стінок з відкритим API",
|
|
17
|
+
"zh-cn": "A. 开端和停止向开放的阿联酋投掷石箱"
|
|
18
|
+
},
|
|
19
|
+
"1.3.0-beta.0": {
|
|
20
|
+
"en": "Support wallbox with Open API",
|
|
21
|
+
"de": "Wallbox Unterstützung mit Open API",
|
|
22
|
+
"ru": "Поддержка настенного ящика с Open API",
|
|
23
|
+
"pt": "Suporte wallbox com API aberta",
|
|
24
|
+
"nl": "Steun muur met open API",
|
|
25
|
+
"fr": "Porte-monnaie support avec Open API",
|
|
26
|
+
"it": "Supporto wallbox con Open API",
|
|
27
|
+
"es": "Soporte de pared con Open API",
|
|
28
|
+
"pl": "Współdzielnia z API Open",
|
|
29
|
+
"uk": "Підтримка настінної коробки з відкритим API",
|
|
30
|
+
"zh-cn": "A. 开放式API的支助墙箱"
|
|
31
|
+
},
|
|
6
32
|
"1.2.1": {
|
|
7
33
|
"en": "Fixed severe error in ClosedAPI",
|
|
8
34
|
"de": "Schweren Fehler in ClosedAPI behoben",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "Wymagana wersja węzła do 16 lub nowa",
|
|
68
94
|
"uk": "Оновлено необхідну версію вершини до 16 або нових",
|
|
69
95
|
"zh-cn": "A. 最新要求的无误版本到16个或新成员"
|
|
70
|
-
},
|
|
71
|
-
"1.0.1": {
|
|
72
|
-
"en": "Adapted fetching energy values using 'Closed API' to latest API changes by Alpha-ESS",
|
|
73
|
-
"de": "Closed API: Energiewerte an neueste API-Änderungen von Alpha-ESS angepasst",
|
|
74
|
-
"ru": "Адаптированные выкачивание энергетических ценностей с помощью 'Closed API' для последних изменений API от Alpha-ESS",
|
|
75
|
-
"pt": "Valores de energia de busca adaptados usando ' API fechada' para as últimas alterações de API por Alpha-ESS",
|
|
76
|
-
"nl": "API verandert door Alpha-ESSS",
|
|
77
|
-
"fr": "Récupération des valeurs d'énergie à l'aide de 'API fermée' aux dernières modifications de l'API par Alpha-ESS",
|
|
78
|
-
"it": "Adattato l'ottenimento di valori energetici utilizzando 'API archiviate' alle ultime modifiche API di Alpha-ESS",
|
|
79
|
-
"es": "Valores de energía adaptados de búsqueda usando 'Closed API' para los últimos cambios de API por Alpha-ESS",
|
|
80
|
-
"pl": "Adapted fetching energy values używając 'Closed API' do najnowszych zmian API przez Alpha-ESS",
|
|
81
|
-
"uk": "Адаптивовані коефіцієнти відтікання енергії за допомогою 'Closed API' для останніх змін API від Alpha-ESS",
|
|
82
|
-
"zh-cn": "利用“无能”的能源价值降低到Alpha-ESS新生动的改变"
|
|
83
|
-
},
|
|
84
|
-
"1.0.0": {
|
|
85
|
-
"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",
|
|
86
|
-
"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",
|
|
87
|
-
"ru": "Поддержка также новый официальный OpenAPI, предоставленный Alpha-ESS\nУстановите государственное качество в соответствии с статусом данных\nНаписание зарядки и разгрузки настроек, реализованных для 'Closed API' и OpenAPI\nУдалить больше не поддерживаемых состояний при запуске автоматически",
|
|
88
|
-
"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",
|
|
89
|
-
"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",
|
|
90
|
-
"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",
|
|
91
|
-
"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",
|
|
92
|
-
"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",
|
|
93
|
-
"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",
|
|
94
|
-
"uk": "Підтримка також нових офіційних OpenAPI, що надається Альфа-ESS\nВстановити якість держави відповідно до стану даних\nНаписання параметрів зарядки та відключення, що реалізовані для \"Closed API\" та OpenAPI\nВидаліть не більше підтримуваних держав при запуску автоматично",
|
|
95
|
-
"zh-cn": "还支持阿尔法-萨斯新官方开放协会\n相应地确定数据状况的国家质量\n确定和履行执行的消费和开放的消费者协会和开放协会环境\n自动取消不再支持的开办国家"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
|
@@ -182,6 +182,8 @@
|
|
|
182
182
|
"intervalStatisticalTodaydataMins": 5,
|
|
183
183
|
"enableSummarydata": false,
|
|
184
184
|
"intervalSummarydataMins": 5,
|
|
185
|
+
"enableWallbox": false,
|
|
186
|
+
"intervalWallboxMins": 5,
|
|
185
187
|
"updateUnchangedStates": false,
|
|
186
188
|
"appID": "",
|
|
187
189
|
"appSecret": "",
|
|
@@ -199,7 +201,9 @@
|
|
|
199
201
|
"oAEnableStatisticsToday": false,
|
|
200
202
|
"oAIntervalStatisticsTodayMins": 5,
|
|
201
203
|
"oAEnableSummary": true,
|
|
202
|
-
"oAIntervalSummaryMins": 5
|
|
204
|
+
"oAIntervalSummaryMins": 5,
|
|
205
|
+
"oAEnableWallbox": false,
|
|
206
|
+
"oAIntervalWallboxMins": 5
|
|
203
207
|
},
|
|
204
208
|
"objects": [],
|
|
205
209
|
"instanceObjects": [
|
package/main.js
CHANGED
|
@@ -17,7 +17,6 @@ const CA_AUTHSUFFIX = 'ui893ed';
|
|
|
17
17
|
const CA_BaseURI = 'https://www.alphaess-cloud.com/';
|
|
18
18
|
const OA_BaseURI = 'https://openapi.alphaess.com/api';
|
|
19
19
|
|
|
20
|
-
const WriteTimeoutIntervalInS = 5;
|
|
21
20
|
const ReadAfterWriteTimeoutIntervalInS = 2;
|
|
22
21
|
|
|
23
22
|
const REQUEST_TIMEOUT = 10000;
|
|
@@ -305,6 +304,7 @@ class OpenAPI {
|
|
|
305
304
|
Group: 'Settings_Charge'
|
|
306
305
|
, fnct: this.getChargeConfigInfo.bind(this)
|
|
307
306
|
, writeFnct: this.writeConfigInfo.bind(this)
|
|
307
|
+
, writeTimeoutIntervalInS: 5
|
|
308
308
|
, requestName: 'updateChargeConfigInfo'
|
|
309
309
|
, enabledName: 'oAEnableSettingsCharge'
|
|
310
310
|
, intervalName: 'oAIntervalSettingsChargeMins'
|
|
@@ -369,6 +369,7 @@ class OpenAPI {
|
|
|
369
369
|
Group: 'Settings_Discharge'
|
|
370
370
|
, fnct: this.getDisChargeConfigInfo.bind(this)
|
|
371
371
|
, writeFnct: this.writeConfigInfo.bind(this)
|
|
372
|
+
, writeTimeoutIntervalInS: 5
|
|
372
373
|
, requestName: 'updateDisChargeConfigInfo'
|
|
373
374
|
, enabledName: 'oAEnableSettingsDischarge'
|
|
374
375
|
, intervalName: 'oAIntervalSettingsDischargeMins'
|
|
@@ -558,7 +559,79 @@ class OpenAPI {
|
|
|
558
559
|
, type: 'number'
|
|
559
560
|
, unit: 'kWh'
|
|
560
561
|
}]
|
|
562
|
+
},
|
|
563
|
+
{
|
|
564
|
+
Group: 'Wallbox'
|
|
565
|
+
, fnct: this.getWallboxData.bind(this)
|
|
566
|
+
, writeFnct: this.writeWallboxChargerControl.bind(this)
|
|
567
|
+
, writeTimeoutIntervalInS: 0
|
|
568
|
+
, requestName: 'remoteControlEvCharger'
|
|
569
|
+
, enabledName: 'oAEnableWallbox'
|
|
570
|
+
, intervalName: 'oAIntervalWallboxMins'
|
|
571
|
+
, intervalFactor: 60
|
|
572
|
+
, states: [
|
|
573
|
+
{
|
|
574
|
+
alphaAttrName: 'evchargerSn'
|
|
575
|
+
, role: 'value'
|
|
576
|
+
, id: 'SN'
|
|
577
|
+
, name: 'Wallbox serial number'
|
|
578
|
+
, type: 'string'
|
|
579
|
+
, unit: ''
|
|
580
|
+
, isStatic: true
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
alphaAttrName: 'evchargerModel'
|
|
584
|
+
, role: 'value'
|
|
585
|
+
, id: 'Model'
|
|
586
|
+
, name: 'Wallbox model'
|
|
587
|
+
, type: 'string'
|
|
588
|
+
, unit: ''
|
|
589
|
+
, isStatic: true
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
alphaAttrName: 'remoteControlEvChargerStart'
|
|
593
|
+
, role: 'button.start'
|
|
594
|
+
, id: 'Charging_Start'
|
|
595
|
+
, name: 'Charging Start'
|
|
596
|
+
, type: 'boolean'
|
|
597
|
+
, unit: ''
|
|
598
|
+
, isStatic: true
|
|
599
|
+
, writeable: true
|
|
600
|
+
, readable: false
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
alphaAttrName: 'remoteControlEvChargerStop'
|
|
604
|
+
, role: 'button.stop'
|
|
605
|
+
, id: 'Charging_Stop'
|
|
606
|
+
, name: 'Charging Stop'
|
|
607
|
+
, type: 'boolean'
|
|
608
|
+
, unit: ''
|
|
609
|
+
, isStatic: true
|
|
610
|
+
, writeable: true
|
|
611
|
+
, readable: false
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
alphaAttrName: 'evchargerStatus'
|
|
615
|
+
, role: 'value'
|
|
616
|
+
, id: 'Status'
|
|
617
|
+
, name: 'Wallbox status'
|
|
618
|
+
, type: 'number'
|
|
619
|
+
, unit: ''
|
|
620
|
+
, states: {
|
|
621
|
+
0: '0 - Unknown',
|
|
622
|
+
1: '1 - Available state (not plugged in)',
|
|
623
|
+
2: '2 - Preparing state of insertion (plugged in and not activated)',
|
|
624
|
+
3: '3 - Charging state (charging with power output)',
|
|
625
|
+
4: '4 - SuspendedEVSE pile Suspended at the terminal (already started but no available power)',
|
|
626
|
+
5: '5 - SuspendedEV Suspended at the vehicle end (with available power, waiting for the car to respond)',
|
|
627
|
+
6: '6 - Finishing The charging end state (actively swiping the card to stop or EMS stop control)',
|
|
628
|
+
7: '7 - Unknown',
|
|
629
|
+
8: '8 - Unknown',
|
|
630
|
+
9: '9 - Faulted fault state (pile failure)'
|
|
631
|
+
}
|
|
632
|
+
}]
|
|
561
633
|
}];
|
|
634
|
+
|
|
562
635
|
this.adapter = adapter;
|
|
563
636
|
this.emptyBody = { data: null };
|
|
564
637
|
}
|
|
@@ -648,7 +721,7 @@ class OpenAPI {
|
|
|
648
721
|
}
|
|
649
722
|
}
|
|
650
723
|
catch (e) {
|
|
651
|
-
this.adapter.log.error('
|
|
724
|
+
this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
|
|
652
725
|
await this.handleError(this.emptyBody, group);
|
|
653
726
|
}
|
|
654
727
|
await this.startGroupTimeout(group);
|
|
@@ -674,7 +747,7 @@ class OpenAPI {
|
|
|
674
747
|
}
|
|
675
748
|
}
|
|
676
749
|
catch (e) {
|
|
677
|
-
this.adapter.log.error('
|
|
750
|
+
this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
|
|
678
751
|
await this.handleError(this.emptyBody, group);
|
|
679
752
|
}
|
|
680
753
|
await this.startGroupTimeout(group);
|
|
@@ -712,7 +785,7 @@ class OpenAPI {
|
|
|
712
785
|
}
|
|
713
786
|
}
|
|
714
787
|
catch (e) {
|
|
715
|
-
this.adapter.log.error('
|
|
788
|
+
this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
|
|
716
789
|
await this.handleError(this.emptyBody, group);
|
|
717
790
|
}
|
|
718
791
|
await this.startGroupTimeout(group);
|
|
@@ -736,7 +809,7 @@ class OpenAPI {
|
|
|
736
809
|
}
|
|
737
810
|
}
|
|
738
811
|
catch (e) {
|
|
739
|
-
this.adapter.log.error('
|
|
812
|
+
this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
|
|
740
813
|
await this.handleError(this.emptyBody, group);
|
|
741
814
|
}
|
|
742
815
|
await this.startGroupTimeout(group);
|
|
@@ -762,7 +835,45 @@ class OpenAPI {
|
|
|
762
835
|
}
|
|
763
836
|
}
|
|
764
837
|
catch (e) {
|
|
765
|
-
this.adapter.log.error('
|
|
838
|
+
this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
|
|
839
|
+
await this.handleError(this.emptyBody, group);
|
|
840
|
+
}
|
|
841
|
+
await this.startGroupTimeout(group);
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* @param {string} group
|
|
846
|
+
*/
|
|
847
|
+
async getWallboxData(group) {
|
|
848
|
+
try {
|
|
849
|
+
this.adapter.stopGroupTimeout(group);
|
|
850
|
+
|
|
851
|
+
this.adapter.log.debug('Fetching ' + group + ' data...');
|
|
852
|
+
// First we need to get SN if not already done:
|
|
853
|
+
let snState = await this.adapter.getStateAsync(`${group}.SN`);
|
|
854
|
+
if (!snState || typeof snState.val === 'string' && snState.val.length == 0) {
|
|
855
|
+
await this.getWallboxSn(group);
|
|
856
|
+
snState = await this.adapter.getStateAsync(`${group}.SN`);
|
|
857
|
+
// In this special case we reset the created indicator because more states must be created for this group in the next step
|
|
858
|
+
this.adapter.createdStates[group] = false;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
if (snState && typeof snState.val === 'string' && snState.val.length > 0) {
|
|
862
|
+
this.adapter.log.debug(`Using Wallbox SN: ${snState.val}`);
|
|
863
|
+
const res = await this.getRequest(`getEvChargerStatusBySn?sysSn=${this.adapter.config.systemId}&evchargerSn=${snState.val}`, {});
|
|
864
|
+
if (res && res['status'] == 200 && res.data && res.data.data) {
|
|
865
|
+
await this.adapter.createAndUpdateStates(group, res.data.data);
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
await this.handleError(res, group);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
else {
|
|
872
|
+
this.adapter.log.error('No wallbox SN could be found!');
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
catch (e) {
|
|
876
|
+
this.adapter.log.error('Fetching data for group ' + group + ': Exception occurred: ' + e);
|
|
766
877
|
await this.handleError(this.emptyBody, group);
|
|
767
878
|
}
|
|
768
879
|
await this.startGroupTimeout(group);
|
|
@@ -771,7 +882,32 @@ class OpenAPI {
|
|
|
771
882
|
/**
|
|
772
883
|
* @param {string} group
|
|
773
884
|
*/
|
|
774
|
-
async
|
|
885
|
+
async getWallboxSn(group) {
|
|
886
|
+
try {
|
|
887
|
+
this.adapter.log.debug('Fetching Wallbox SN ...');
|
|
888
|
+
|
|
889
|
+
const res = await this.getRequest(`getEvChargerConfigList?sysSn=${this.adapter.config.systemId}`, {});
|
|
890
|
+
if (res && res['status'] == 200 && res.data && res.data.data) {
|
|
891
|
+
|
|
892
|
+
if (res.data.data.length > 1) {
|
|
893
|
+
this.adapter.log.warn('More than one wallbox found! Only the first wallbox is currently supported by this adapter!');
|
|
894
|
+
}
|
|
895
|
+
await this.adapter.createAndUpdateStates(group, res.data.data[0]);
|
|
896
|
+
}
|
|
897
|
+
else {
|
|
898
|
+
await this.handleError(res, group);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
catch (e) {
|
|
902
|
+
this.adapter.log.error('Fetching Wallbox SN: Exception occurred: ' + e);
|
|
903
|
+
await this.handleError(this.emptyBody, group);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* @param {string} group
|
|
909
|
+
*/
|
|
910
|
+
async writeConfigInfo(group, _updState, _updStateInfo) {
|
|
775
911
|
const nextReadTimeout = ReadAfterWriteTimeoutIntervalInS;
|
|
776
912
|
try {
|
|
777
913
|
this.adapter.stopGroupWriteTimeout(group);
|
|
@@ -820,6 +956,60 @@ class OpenAPI {
|
|
|
820
956
|
this.adapter.startGroupTimeout(nextReadTimeout, group);
|
|
821
957
|
}
|
|
822
958
|
|
|
959
|
+
/**
|
|
960
|
+
* @param {string} group
|
|
961
|
+
* @param {ioBroker.State} updState
|
|
962
|
+
* @param {any} updStateInfo
|
|
963
|
+
*/
|
|
964
|
+
async writeWallboxChargerControl(group, updState, updStateInfo) {
|
|
965
|
+
try {
|
|
966
|
+
this.adapter.stopGroupWriteTimeout(group);
|
|
967
|
+
this.adapter.stopGroupTimeout(group);
|
|
968
|
+
|
|
969
|
+
this.adapter.log.debug('Writing ' + group + ' data...');
|
|
970
|
+
|
|
971
|
+
const gidx = this.stateInfoList.findIndex((/** @type {{ Group: string; }} */ i) => i.Group == group);
|
|
972
|
+
if (gidx >= 0) {
|
|
973
|
+
|
|
974
|
+
const chargerSnState = await this.adapter.getStateAsync(group + '.SN');
|
|
975
|
+
|
|
976
|
+
if (chargerSnState) {
|
|
977
|
+
this.adapter.log.debug(`Using Wallbox SN: ${chargerSnState.val}`);
|
|
978
|
+
|
|
979
|
+
const body = {};
|
|
980
|
+
|
|
981
|
+
if (updStateInfo.role == 'button.start') {
|
|
982
|
+
body['controlMode'] = 1;
|
|
983
|
+
}
|
|
984
|
+
else {
|
|
985
|
+
body['controlMode'] = 0;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
body['sysSn'] = this.adapter.config.systemId;
|
|
989
|
+
body['evchargerSn'] = chargerSnState.val;
|
|
990
|
+
|
|
991
|
+
this.adapter.log.debug(`Write group ${group}: ${JSON.stringify(body)}`);
|
|
992
|
+
|
|
993
|
+
const res = await this.postRequest(this.adapter.getStateInfoList()[gidx].requestName, body, {});
|
|
994
|
+
if (res && res['status'] == 200 && res.data) {
|
|
995
|
+
this.adapter.log.info('Written values fror group ' + group);
|
|
996
|
+
}
|
|
997
|
+
else {
|
|
998
|
+
await this.handleError(res, group);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
else {
|
|
1002
|
+
this.adapter.log.error('State ' + group + '.evchargerSn not found!');
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
catch (e) {
|
|
1007
|
+
this.adapter.log.error('Writing data for group ' + group + ': Exception occurred: ' + e);
|
|
1008
|
+
await this.handleError(this.emptyBody, group);
|
|
1009
|
+
}
|
|
1010
|
+
this.adapter.startGroupTimeout(ReadAfterWriteTimeoutIntervalInS, group);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
823
1013
|
/**
|
|
824
1014
|
* @param {string} group
|
|
825
1015
|
*/
|
|
@@ -848,24 +1038,28 @@ class OpenAPI {
|
|
|
848
1038
|
await this.adapter.setStateChangedAsync('info.connection', false, true);
|
|
849
1039
|
this.adapter.errorCount++;
|
|
850
1040
|
if (res.data && res.data.code && res.data.code != 0) {
|
|
851
|
-
this.adapter.log.error(
|
|
1041
|
+
this.adapter.log.error(`Alpha ESS Api returns an error! Group: ${group}`);
|
|
852
1042
|
switch (res.data.code) {
|
|
853
|
-
case 6001: this.adapter.log.
|
|
854
|
-
case 6002: this.adapter.log.
|
|
855
|
-
case 6003: this.adapter.log.
|
|
856
|
-
case 6004: this.adapter.log.
|
|
857
|
-
case 6005: this.adapter.log.
|
|
858
|
-
case 6006: this.adapter.log.
|
|
859
|
-
case 6007: this.adapter.log.
|
|
860
|
-
case 6008: this.adapter.log.
|
|
861
|
-
case 6009: this.adapter.log.
|
|
862
|
-
case 6010: this.adapter.log.
|
|
863
|
-
case 6011: this.adapter.log.
|
|
864
|
-
case 6012: this.adapter.log.
|
|
865
|
-
case
|
|
866
|
-
case
|
|
867
|
-
case
|
|
868
|
-
|
|
1043
|
+
case 6001: this.adapter.log.info(`Error code: ${res.data.code} - Parameter error (#${this.adapter.errorCount})`); break;
|
|
1044
|
+
case 6002: this.adapter.log.info(`Error code: ${res.data.code} - The SN is not bound to the user (#${this.adapter.errorCount})`); break;
|
|
1045
|
+
case 6003: this.adapter.log.info(`Error code: ${res.data.code} - You have bound this SN (#${this.adapter.errorCount})`); break;
|
|
1046
|
+
case 6004: this.adapter.log.info(`Error code: ${res.data.code} - CheckCode error (#${this.adapter.errorCount})`); break;
|
|
1047
|
+
case 6005: this.adapter.log.info(`Error code: ${res.data.code} - This appId is not bound to the SN (#${this.adapter.errorCount})`); break;
|
|
1048
|
+
case 6006: this.adapter.log.info(`Error code: ${res.data.code} - Timestamp error (#${this.adapter.errorCount})`); break;
|
|
1049
|
+
case 6007: this.adapter.log.info(`Error code: ${res.data.code} - Sign verification error (#${this.adapter.errorCount})`); break;
|
|
1050
|
+
case 6008: this.adapter.log.info(`Error code: ${res.data.code} - Set failed (#${this.adapter.errorCount})`); break;
|
|
1051
|
+
case 6009: this.adapter.log.info(`Error code: ${res.data.code} - Whitelist verification failed (#${this.adapter.errorCount})`); break;
|
|
1052
|
+
case 6010: this.adapter.log.info(`Error code: ${res.data.code} - Sign is empty (#${this.adapter.errorCount})`); break;
|
|
1053
|
+
case 6011: this.adapter.log.info(`Error code: ${res.data.code} - timestamp is empty (#${this.adapter.errorCount})`); break;
|
|
1054
|
+
case 6012: this.adapter.log.info(`Error code: ${res.data.code} - AppId is empty (#${this.adapter.errorCount})`); break;
|
|
1055
|
+
case 6016: this.adapter.log.info(`Error code: ${res.data.code} - Data does not exist or has been deleted (#${this.adapter.errorCount})`); break;
|
|
1056
|
+
case 6026: this.adapter.log.info(`Error code: ${res.data.code} - Internal Error (#${this.adapter.errorCount})`); break;
|
|
1057
|
+
case 6029: this.adapter.log.info(`Error code: ${res.data.code} - operation failed (#${this.adapter.errorCount})`); break;
|
|
1058
|
+
case 6038: this.adapter.log.info(`Error code: ${res.data.code} - system sn does not exist (#${this.adapter.errorCount})`); break;
|
|
1059
|
+
case 6042: this.adapter.log.info(`Error code: ${res.data.code} - system offline (#${this.adapter.errorCount})`); break;
|
|
1060
|
+
case 6046: this.adapter.log.info(`Error code: ${res.data.code} - Verification code error (#${this.adapter.errorCount})`); break;
|
|
1061
|
+
case 6053: this.adapter.log.info(`Error code: ${res.data.code} - The request was too fast, please try again later (#${this.adapter.errorCount})`); break;
|
|
1062
|
+
default: this.adapter.log.info(`Error code: ${res.data.code} - Unknown error (#${this.adapter.errorCount})`);
|
|
869
1063
|
}
|
|
870
1064
|
if (res.data.code == 6002 ||
|
|
871
1065
|
res.data.code == 6003 ||
|
|
@@ -880,7 +1074,7 @@ class OpenAPI {
|
|
|
880
1074
|
}
|
|
881
1075
|
}
|
|
882
1076
|
else {
|
|
883
|
-
this.adapter.log.error(`Unknown error occurred: ${JSON.stringify(res.data)} (#${this.adapter.errorCount})`);
|
|
1077
|
+
this.adapter.log.error(`Unknown error occurred: ${JSON.stringify(res.data)} (#${this.adapter.errorCount}) Group:${group}`);
|
|
884
1078
|
}
|
|
885
1079
|
await this.adapter.setQualityForGroup(group, 0x44);
|
|
886
1080
|
}
|
|
@@ -1059,6 +1253,7 @@ class ClosedAPI {
|
|
|
1059
1253
|
Group: 'Settings'
|
|
1060
1254
|
, fnct: this.fetchSettingsData.bind(this)
|
|
1061
1255
|
, writeFnct: this.writeSettingsData.bind(this)
|
|
1256
|
+
, writeTimeoutIntervalInS: 5
|
|
1062
1257
|
, enabledName: 'enableSettingsdata'
|
|
1063
1258
|
, intervalName: 'intervalSettingsdataMins'
|
|
1064
1259
|
, intervalFactor: 60
|
|
@@ -1521,6 +1716,15 @@ class ClosedAPI {
|
|
|
1521
1716
|
, unit: ''
|
|
1522
1717
|
, dayIndex: false
|
|
1523
1718
|
}]
|
|
1719
|
+
},
|
|
1720
|
+
{
|
|
1721
|
+
// Just a dummy to ensure that this group is deleted
|
|
1722
|
+
Group: 'Wallbox'
|
|
1723
|
+
, fnct: this.fetchWallboxDataDummy.bind(this)
|
|
1724
|
+
, enabledName: 'enableWallbox'
|
|
1725
|
+
, intervalName: 'intervalWallboxMins'
|
|
1726
|
+
, intervalFactor: 60
|
|
1727
|
+
, states: []
|
|
1524
1728
|
}];
|
|
1525
1729
|
|
|
1526
1730
|
this.Auth =
|
|
@@ -1796,6 +2000,13 @@ class ClosedAPI {
|
|
|
1796
2000
|
this.adapter.log.warn(`Internal error (group ${group}): function fetchSettingsDischargeDataDummy should never be called.`);
|
|
1797
2001
|
}
|
|
1798
2002
|
|
|
2003
|
+
/**
|
|
2004
|
+
* @param {string} group
|
|
2005
|
+
*/
|
|
2006
|
+
async fetchWallboxDataDummy(group) {
|
|
2007
|
+
this.adapter.log.warn(`Internal error (group ${group}): function fetchWallboxDataDummy should never be called.`);
|
|
2008
|
+
}
|
|
2009
|
+
|
|
1799
2010
|
/**
|
|
1800
2011
|
* Get realtime data from alpha-ess and start timer for next execution
|
|
1801
2012
|
* @param {string} group
|
|
@@ -1916,7 +2127,7 @@ class ClosedAPI {
|
|
|
1916
2127
|
/**
|
|
1917
2128
|
* @param {string} group
|
|
1918
2129
|
*/
|
|
1919
|
-
async writeSettingsData(group) {
|
|
2130
|
+
async writeSettingsData(group, _updState, _updStateInfo) {
|
|
1920
2131
|
try {
|
|
1921
2132
|
this.adapter.stopGroupWriteTimeout(group);
|
|
1922
2133
|
this.adapter.stopGroupTimeout(group);
|
|
@@ -2072,12 +2283,14 @@ class AlphaEss extends utils.Adapter {
|
|
|
2072
2283
|
this.log.debug('config oAIntervalSettingsChargeMins ' + this.config.oAIntervalSettingsChargeMins);
|
|
2073
2284
|
this.log.debug('config oAIntervalSettingsDischargeMins ' + this.config.oAIntervalSettingsDischargeMins);
|
|
2074
2285
|
this.log.debug('config oAIntervalSummaryMins: ' + this.config.oAIntervalSummaryMins);
|
|
2075
|
-
this.log.debug('config
|
|
2076
|
-
this.log.debug('config
|
|
2077
|
-
this.log.debug('config
|
|
2078
|
-
this.log.debug('config
|
|
2079
|
-
this.log.debug('config
|
|
2080
|
-
this.log.debug('config
|
|
2286
|
+
this.log.debug('config oAIntervalWallboxMins: ' + this.config.oAIntervalWallboxMins);
|
|
2287
|
+
this.log.debug('config oAEnableRealtime: ' + this.config.oAEnableRealtime);
|
|
2288
|
+
this.log.debug('config oAEnableEnergy: ' + this.config.oAEnableEnergy);
|
|
2289
|
+
this.log.debug('config oAEnableSettingsCharge: ' + this.config.oAEnableSettingsCharge);
|
|
2290
|
+
this.log.debug('config oAEnableSettingsCharge: ' + this.config.oAEnableSettingsCharge);
|
|
2291
|
+
this.log.debug('config oAEnableSettingsDischarge: ' + this.config.oAEnableSettingsDischarge);
|
|
2292
|
+
this.log.debug('config oAEnableSummary: ' + this.config.oAEnableSummary);
|
|
2293
|
+
this.log.debug('config oAEnableWallbox: ' + this.config.oAEnableWallbox);
|
|
2081
2294
|
this.log.debug('config updateUnchangedStates: ' + this.config.updateUnchangedStates);
|
|
2082
2295
|
}
|
|
2083
2296
|
|
|
@@ -2203,7 +2416,12 @@ class AlphaEss extends utils.Adapter {
|
|
|
2203
2416
|
|
|
2204
2417
|
this.verifyValue(state.val, group, stateInfo);
|
|
2205
2418
|
|
|
2206
|
-
this.
|
|
2419
|
+
const gidx = this.getStateInfoList().findIndex((/** @type {{ Group: string; }} */ i) => i.Group == group);
|
|
2420
|
+
|
|
2421
|
+
if (gidx >= 0) {
|
|
2422
|
+
const writeTimeOut = this.getStateInfoList()[gidx].writeTimeoutIntervalInS;
|
|
2423
|
+
this.startGroupWriteTimeout(writeTimeOut ? writeTimeOut : 0, group, state, stateInfo);
|
|
2424
|
+
}
|
|
2207
2425
|
}
|
|
2208
2426
|
else {
|
|
2209
2427
|
this.log.debug(`Validation already in progress: ${id}`);
|
|
@@ -2338,15 +2556,17 @@ class AlphaEss extends utils.Adapter {
|
|
|
2338
2556
|
* Start a timer for a given group
|
|
2339
2557
|
* @param {number} intervalInS
|
|
2340
2558
|
* @param {string} group
|
|
2559
|
+
* @param {ioBroker.State} updState
|
|
2560
|
+
* @param {{ alphaAttrName: string; role: string; id: string; name: string; type: string; unit: string; dayIndex?: undefined; } | { alphaAttrName: string; role: string; id: string; name: string; type: string; unit: string; dayIndex: boolean; } | { alphaAttrName: string; role: string; id: string; name: string; type: string; unit: string; writeable: boolean; } | { alphaAttrName: string; role: string; id: string; name: string; type: string; unit: string; round: number; factor?: undefined; } | { alphaAttrName: string; role: string; id: string; name: string; type: string; unit: string; factor: number; round: number; } | { alphaAttrName: string; role: string; id: string; name: string; type: string; unit: string; round?: undefined; factor?: undefined; } | { alphaAttrName: string; role: string; id: string; name: string; type: string; unit: string; isStatic: boolean; writeable?: undefined; readable?: undefined; states?: undefined; } | { alphaAttrName: string; role: string; id: string; name: string; type: string; unit: string; states: { 0: string; 1: string; 2: string; 3: string; 4: string; 5: string; 6: string; 7: string; 8: string; 9: string; }; isStatic?: undefined; writeable?: undefined; readable?: undefined; }} updStateInfo
|
|
2341
2561
|
*/
|
|
2342
|
-
startGroupWriteTimeout(intervalInS, group) {
|
|
2562
|
+
startGroupWriteTimeout(intervalInS, group, updState, updStateInfo) {
|
|
2343
2563
|
const gidx = this.getStateInfoList().findIndex((/** @type {{ Group: string; }} */ i) => i.Group == group);
|
|
2344
2564
|
if (!this.getStateInfoList()[gidx].writeTimeoutHandle) {
|
|
2345
2565
|
const interval = intervalInS * 1000;
|
|
2346
2566
|
this.log.debug('Write Timeout with interval ' + interval + ' ms started for group ' + group);
|
|
2347
2567
|
const wf = this.getStateInfoList()[gidx].writeFnct;
|
|
2348
2568
|
if (wf) {
|
|
2349
|
-
this.getStateInfoList()[gidx].writeTimeoutHandle = this.setTimeout(() => { wf(group); }, interval);
|
|
2569
|
+
this.getStateInfoList()[gidx].writeTimeoutHandle = this.setTimeout(() => { wf(group, updState, updStateInfo); }, interval);
|
|
2350
2570
|
}
|
|
2351
2571
|
}
|
|
2352
2572
|
}
|
|
@@ -2378,10 +2598,11 @@ class AlphaEss extends utils.Adapter {
|
|
|
2378
2598
|
/**
|
|
2379
2599
|
* Create states when called the first time, update state values in each call
|
|
2380
2600
|
* @param {string} group
|
|
2381
|
-
* @param {{ [s: string]: any; }} data
|
|
2601
|
+
* @param {{ [s: string]: any; } | null} data
|
|
2382
2602
|
*/
|
|
2383
2603
|
async createAndUpdateStates(group, data) {
|
|
2384
2604
|
try {
|
|
2605
|
+
|
|
2385
2606
|
if (data) {
|
|
2386
2607
|
await this.setStateChangedAsync('info.connection', true, true);
|
|
2387
2608
|
this.errorCount = 0;
|
|
@@ -2390,6 +2611,8 @@ class AlphaEss extends utils.Adapter {
|
|
|
2390
2611
|
|
|
2391
2612
|
if (!this.createdStates[group]) {
|
|
2392
2613
|
|
|
2614
|
+
const setObjectFunc = await this.isMigrationNecessary() ? this.setObjectMigrationAsync : this.setObjectNormalAsync;
|
|
2615
|
+
|
|
2393
2616
|
// Delete no longer supported states for this group
|
|
2394
2617
|
const gidx = this.getStateInfoList().findIndex((/** @type {{ Group: string; }} */ i) => i.Group == group);
|
|
2395
2618
|
if (gidx >= 0) {
|
|
@@ -2405,8 +2628,6 @@ class AlphaEss extends utils.Adapter {
|
|
|
2405
2628
|
}
|
|
2406
2629
|
}
|
|
2407
2630
|
|
|
2408
|
-
const setObjectFunc = await this.isMigrationNecessary() ? this.setObjectMigrationAsync : this.setObjectNormalAsync;
|
|
2409
|
-
|
|
2410
2631
|
// Create the folder for this group
|
|
2411
2632
|
await setObjectFunc(group, {
|
|
2412
2633
|
type: 'folder',
|
|
@@ -2418,38 +2639,50 @@ class AlphaEss extends utils.Adapter {
|
|
|
2418
2639
|
native: {}
|
|
2419
2640
|
});
|
|
2420
2641
|
|
|
2642
|
+
// Create all static states:
|
|
2643
|
+
const groupStateList = this.getStateInfoList()[gidx].states;
|
|
2644
|
+
if (!this.createdStates[group]) {
|
|
2645
|
+
for (const stateInfo of groupStateList) {
|
|
2646
|
+
if (stateInfo.isStatic) {
|
|
2647
|
+
await this.createStateForAttribute(group, data, stateInfo.alphaAttrName, stateInfo, setObjectFunc);
|
|
2648
|
+
|
|
2649
|
+
}
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
|
|
2421
2653
|
// Create all states for received elements
|
|
2422
|
-
for (const [alphaAttrName
|
|
2423
|
-
const stateInfo = this.getStateInfoByAlphaAttrName(group, alphaAttrName);
|
|
2654
|
+
for (const [alphaAttrName] of Object.entries(data)) {
|
|
2655
|
+
const stateInfo = await this.getStateInfoByAlphaAttrName(group, alphaAttrName);
|
|
2424
2656
|
if (typeof data[alphaAttrName] !== 'object') {
|
|
2425
|
-
this.createStateForAttribute(group, data,
|
|
2657
|
+
await this.createStateForAttribute(group, data, alphaAttrName, stateInfo, setObjectFunc);
|
|
2426
2658
|
}
|
|
2427
2659
|
else {
|
|
2428
2660
|
// Look for subvalues:
|
|
2429
2661
|
if (data[alphaAttrName]) {
|
|
2430
|
-
for (const [alphaAttrName2
|
|
2431
|
-
const stateInfo2 = this.getStateInfoByAlphaAttrName(group, alphaAttrName2);
|
|
2432
|
-
this.createStateForAttribute(group, data[alphaAttrName],
|
|
2662
|
+
for (const [alphaAttrName2] of Object.entries(data[alphaAttrName])) {
|
|
2663
|
+
const stateInfo2 = await this.getStateInfoByAlphaAttrName(group, alphaAttrName2);
|
|
2664
|
+
await this.createStateForAttribute(group, data[alphaAttrName], alphaAttrName2, stateInfo2, setObjectFunc);
|
|
2433
2665
|
}
|
|
2434
2666
|
}
|
|
2435
2667
|
}
|
|
2436
2668
|
}
|
|
2669
|
+
|
|
2437
2670
|
this.log.info('Initialized states for : ' + group);
|
|
2438
2671
|
this.createdStates[group] = true;
|
|
2439
2672
|
}
|
|
2440
2673
|
|
|
2441
2674
|
// Set values for received states
|
|
2442
2675
|
for (const [alphaAttrName, rawValue] of Object.entries(data)) {
|
|
2443
|
-
const stateInfo = this.getStateInfoByAlphaAttrName(group, alphaAttrName);
|
|
2676
|
+
const stateInfo = await this.getStateInfoByAlphaAttrName(group, alphaAttrName);
|
|
2444
2677
|
if (typeof data[alphaAttrName] !== 'object') {
|
|
2445
|
-
this.setValueForAttribute(group, rawValue, stateInfo, idx);
|
|
2678
|
+
await this.setValueForAttribute(group, rawValue, stateInfo, idx);
|
|
2446
2679
|
}
|
|
2447
2680
|
else {
|
|
2448
2681
|
// Look for subvalues:
|
|
2449
2682
|
if (data[alphaAttrName]) {
|
|
2450
2683
|
for (const [alphaAttrName2, rawValue2] of Object.entries(data[alphaAttrName])) {
|
|
2451
|
-
const stateInfo2 = this.getStateInfoByAlphaAttrName(group, alphaAttrName2);
|
|
2452
|
-
this.setValueForAttribute(group, rawValue2, stateInfo2, idx);
|
|
2684
|
+
const stateInfo2 = await this.getStateInfoByAlphaAttrName(group, alphaAttrName2);
|
|
2685
|
+
await this.setValueForAttribute(group, rawValue2, stateInfo2, idx);
|
|
2453
2686
|
}
|
|
2454
2687
|
}
|
|
2455
2688
|
}
|
|
@@ -2465,11 +2698,10 @@ class AlphaEss extends utils.Adapter {
|
|
|
2465
2698
|
*
|
|
2466
2699
|
* create the state for the received element
|
|
2467
2700
|
* @param {string} group
|
|
2468
|
-
* @param {{[x: string]: any;}} data
|
|
2469
|
-
* @param {string} rawValue
|
|
2701
|
+
* @param {{[x: string]: any;} | null} data
|
|
2470
2702
|
* @param {string} alphaAttrName
|
|
2471
2703
|
*/
|
|
2472
|
-
async createStateForAttribute(group, data,
|
|
2704
|
+
async createStateForAttribute(group, data, alphaAttrName, stateInfo, setObjectFunc) {
|
|
2473
2705
|
if (stateInfo) {
|
|
2474
2706
|
// The type checker has a problem with type: stateInfo.type. I have no clue why.
|
|
2475
2707
|
// All possible types are correct and valid. To get rid of the type checker error, we check for valid types:
|
|
@@ -2480,28 +2712,30 @@ class AlphaEss extends utils.Adapter {
|
|
|
2480
2712
|
name: stateInfo.name + ' [' + stateInfo.alphaAttrName + ']'
|
|
2481
2713
|
, type: stateInfo.type
|
|
2482
2714
|
, role: stateInfo.role
|
|
2483
|
-
, read: true
|
|
2715
|
+
, read: stateInfo.readable != null ? stateInfo.readable : true
|
|
2484
2716
|
, write: stateInfo.writeable ? stateInfo.writeable : false
|
|
2485
|
-
, unit: stateInfo.unit === '{money_type}' ? data['money_type'] : stateInfo.unit === '{moneyType}' ? data['moneyType'] : stateInfo.unit
|
|
2717
|
+
, unit: stateInfo.unit === '{money_type}' && data ? data['money_type'] : stateInfo.unit === '{moneyType}' && data ? data['moneyType'] : stateInfo.unit
|
|
2486
2718
|
, desc: stateInfo.alphaAttrName
|
|
2719
|
+
, states: stateInfo.states
|
|
2487
2720
|
},
|
|
2488
2721
|
native: {},
|
|
2489
2722
|
});
|
|
2723
|
+
this.log.debug('Created object ' + group + '.' + this.osn(stateInfo.alphaAttrName));
|
|
2490
2724
|
if (stateInfo.writeable) {
|
|
2491
2725
|
await this.subscribeStatesAsync(`${group}.${stateInfo.id}`);
|
|
2492
2726
|
this.log.debug(`Subscribed State: ${group}.${stateInfo.id}`);
|
|
2493
2727
|
}
|
|
2494
2728
|
}
|
|
2495
2729
|
else {
|
|
2496
|
-
this.log.error('Internal error: Skipped object ' + group + '.' + alphaAttrName + '
|
|
2730
|
+
this.log.error('Internal error: Skipped object ' + group + '.' + alphaAttrName + ' because of invalid type definition!');
|
|
2497
2731
|
}
|
|
2498
2732
|
}
|
|
2499
2733
|
else {
|
|
2500
2734
|
if (alphaAttrName == 'sysSn' || alphaAttrName == 'theDate') {
|
|
2501
|
-
this.log.debug('Skipped object ' + group + '.' + alphaAttrName
|
|
2735
|
+
this.log.debug('Skipped object ' + group + '.' + alphaAttrName);
|
|
2502
2736
|
}
|
|
2503
2737
|
else {
|
|
2504
|
-
this.log.warn('Skipped object ' + group + '.' + alphaAttrName
|
|
2738
|
+
this.log.warn('Skipped object ' + group + '.' + alphaAttrName);
|
|
2505
2739
|
}
|
|
2506
2740
|
}
|
|
2507
2741
|
}
|
|
@@ -2561,7 +2795,7 @@ class AlphaEss extends utils.Adapter {
|
|
|
2561
2795
|
* @param {string} Group
|
|
2562
2796
|
* @param {string} alphaAttrName
|
|
2563
2797
|
*/
|
|
2564
|
-
getStateInfoByAlphaAttrName(Group, alphaAttrName) {
|
|
2798
|
+
async getStateInfoByAlphaAttrName(Group, alphaAttrName) {
|
|
2565
2799
|
try {
|
|
2566
2800
|
const gidx = this.getStateInfoList().findIndex((/** @type {{ Group: string; }} */ i) => i.Group == Group);
|
|
2567
2801
|
if (gidx >= 0) {
|
|
@@ -2583,12 +2817,12 @@ class AlphaEss extends utils.Adapter {
|
|
|
2583
2817
|
|
|
2584
2818
|
/**
|
|
2585
2819
|
* Answer the state description object for a given group and id
|
|
2586
|
-
* @param {string}
|
|
2820
|
+
* @param {string} group
|
|
2587
2821
|
* @param {string} id
|
|
2588
2822
|
*/
|
|
2589
|
-
getStateInfoById(
|
|
2823
|
+
getStateInfoById(group, id) {
|
|
2590
2824
|
try {
|
|
2591
|
-
const gidx = this.getStateInfoList().findIndex((/** @type {{ Group: string; }} */ i) => i.Group ==
|
|
2825
|
+
const gidx = this.getStateInfoList().findIndex((/** @type {{ Group: string; }} */ i) => i.Group == group);
|
|
2592
2826
|
if (gidx >= 0) {
|
|
2593
2827
|
const currentList = this.getStateInfoList()[gidx].states;
|
|
2594
2828
|
const sidx = currentList.findIndex((/** @type {{ id: string; }} */ i) => i.id == id);
|
|
@@ -2600,7 +2834,7 @@ class AlphaEss extends utils.Adapter {
|
|
|
2600
2834
|
}
|
|
2601
2835
|
catch (e) {
|
|
2602
2836
|
this.log.error('getStateInfo Exception occurred: ' + e);
|
|
2603
|
-
this.log.info('Group: ' +
|
|
2837
|
+
this.log.info('Group: ' + group);
|
|
2604
2838
|
this.log.info('alphaAttrName: ' + id);
|
|
2605
2839
|
return null;
|
|
2606
2840
|
}
|
|
@@ -2613,16 +2847,29 @@ class AlphaEss extends utils.Adapter {
|
|
|
2613
2847
|
*/
|
|
2614
2848
|
async setQualityForGroup(group, q) {
|
|
2615
2849
|
try {
|
|
2616
|
-
const
|
|
2617
|
-
|
|
2618
|
-
const
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2850
|
+
const gidx = this.getStateInfoList().findIndex((/** @type {{ Group: string; }} */ i) => i.Group == group);
|
|
2851
|
+
if (gidx >= 0) {
|
|
2852
|
+
const groupInfo = this.getStateInfoList()[gidx];
|
|
2853
|
+
const groupStates = groupInfo.states;
|
|
2854
|
+
for (let i = 0; i < groupStates.length; i++) {
|
|
2855
|
+
if (!groupStates[i].isStatic) {
|
|
2856
|
+
const newState = await this.getStateAsync(`${groupInfo.Group}.${groupStates[i].id}`);
|
|
2857
|
+
if (newState) {
|
|
2858
|
+
if (newState.q != q && newState.ack) {
|
|
2859
|
+
newState.q = q;
|
|
2860
|
+
this.log.debug(`Set state ${groupInfo.Group}.${groupStates[i].id} to val: ${newState.val}; q: ${newState.q}; ack: ${newState.ack}`);
|
|
2861
|
+
await this.setStateAsync(`${groupInfo.Group}.${groupStates[i].id}`, newState, true);
|
|
2862
|
+
}
|
|
2863
|
+
else {
|
|
2864
|
+
if (!newState.ack) {
|
|
2865
|
+
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}`);
|
|
2866
|
+
}
|
|
2867
|
+
else {
|
|
2868
|
+
this.log.silly(`Set state ${groupInfo.Group}.${groupStates[i].id} NOT to val: ${newState.val}; q: ${newState.q} because quality is unchanged ${newState.q}`);
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2626
2873
|
}
|
|
2627
2874
|
}
|
|
2628
2875
|
}
|
|
@@ -2643,11 +2890,11 @@ class AlphaEss extends utils.Adapter {
|
|
|
2643
2890
|
const groupInfo = this.getStateInfoList()[gidx];
|
|
2644
2891
|
const groupStates = groupInfo.states;
|
|
2645
2892
|
for (let i = 0; i < groupStates.length; i++) {
|
|
2646
|
-
if (groupStates[i].lastUpdateTs) {
|
|
2893
|
+
if (groupStates[i].lastUpdateTs && !groupStates[i].isStatic) {
|
|
2647
2894
|
if (Date.now() - groupStates[i].lastUpdateTs > (groupInfo.interval * 1000 + REQUEST_TIMEOUT)) {
|
|
2648
2895
|
const newState = await this.getStateAsync(`${groupInfo.Group}.${groupStates[i].id}`);
|
|
2649
2896
|
if (newState) {
|
|
2650
|
-
if (newState.q
|
|
2897
|
+
if (newState.q == 0 && newState.ack) {
|
|
2651
2898
|
// Change quality only if it was OK before
|
|
2652
2899
|
newState.q = 0x01;
|
|
2653
2900
|
this.log.warn(`Watchdog: State ${groupInfo.Group}.${groupStates[i].id} not updated for ${Date.now() - groupStates[i].lastUpdateTs} ms`);
|
|
@@ -2655,7 +2902,12 @@ class AlphaEss extends utils.Adapter {
|
|
|
2655
2902
|
await this.setStateAsync(`${groupInfo.Group}.${groupStates[i].id}`, newState, true);
|
|
2656
2903
|
}
|
|
2657
2904
|
else {
|
|
2658
|
-
|
|
2905
|
+
if (!newState.ack) {
|
|
2906
|
+
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}`);
|
|
2907
|
+
}
|
|
2908
|
+
else {
|
|
2909
|
+
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}`);
|
|
2910
|
+
}
|
|
2659
2911
|
}
|
|
2660
2912
|
}
|
|
2661
2913
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.alpha-ess",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0-beta.1",
|
|
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": "^
|
|
49
|
+
"sinon": "^17.0.0",
|
|
50
50
|
"sinon-chai": "^3.7.0",
|
|
51
51
|
"typescript": "~5.2.2"
|
|
52
52
|
},
|