iobroker.bmw 2.8.2 → 2.8.3
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 +4 -0
- package/admin/index_m.html +36 -0
- package/admin/words.js +50 -49
- package/eslint.config.cjs +50 -0
- package/io-package.json +20 -18
- package/lib/extractKeys.js +2 -0
- package/main.js +78 -50
- package/package.json +12 -9
package/README.md
CHANGED
package/admin/index_m.html
CHANGED
|
@@ -81,11 +81,47 @@
|
|
|
81
81
|
<label for="password" class="translate">App Password</label>
|
|
82
82
|
</div>
|
|
83
83
|
</div>
|
|
84
|
+
<div class="row">
|
|
85
|
+
<div class="col s6 input-field" id="captchaResponse">
|
|
86
|
+
Check Captcha Box and press Submit. Save the form.
|
|
87
|
+
<div>
|
|
88
|
+
<form id="captcha_form" action="#" method="post">
|
|
89
|
+
<!-- hCaptcha widget -->
|
|
90
|
+
<div class="h-captcha" data-sitekey="7244955f-8f30-4445-adff-4fefe059f815"></div>
|
|
91
|
+
<br />
|
|
92
|
+
<button type="submit" class="btn">Submit</button>
|
|
93
|
+
</form>
|
|
94
|
+
|
|
95
|
+
<!-- hCaptcha script -->
|
|
96
|
+
<script src="https://hcaptcha.com/1/api.js" async defer></script>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
<p></p>
|
|
100
|
+
<script>
|
|
101
|
+
document.getElementById('captcha_form').addEventListener('submit', function (event) {
|
|
102
|
+
event.preventDefault(); // Prevent the default form submission
|
|
103
|
+
|
|
104
|
+
const hCaptchaResponse = document.querySelector('[name="h-captcha-response"]').value;
|
|
105
|
+
const responseElement = document.getElementById('captchaResponse');
|
|
106
|
+
|
|
107
|
+
if (hCaptchaResponse) {
|
|
108
|
+
document.getElementById('captcha').value = hCaptchaResponse;
|
|
109
|
+
//trigger change event
|
|
110
|
+
var event = new Event('change');
|
|
111
|
+
document.getElementById('captcha').dispatchEvent(event);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
</script>
|
|
115
|
+
|
|
116
|
+
<input type="text" class="value" id="captcha" />
|
|
117
|
+
<label for="captcha" class="translate">Captcha</label>
|
|
118
|
+
</div>
|
|
84
119
|
<div class="row">
|
|
85
120
|
<div class="col s2 input-field">
|
|
86
121
|
<select id="brand" class="value">
|
|
87
122
|
<option value="bmw">BMW</option>
|
|
88
123
|
<option value="mini">Mini</option>
|
|
124
|
+
<option value="toyota">Toyota Supra</option>
|
|
89
125
|
</select>
|
|
90
126
|
<label for="brand" class="translate">Brand</label>
|
|
91
127
|
</div>
|
package/admin/words.js
CHANGED
|
@@ -1,65 +1,66 @@
|
|
|
1
|
+
// eslint-disable-next-line no-unused-vars
|
|
1
2
|
/*global systemDictionary:true */
|
|
2
|
-
|
|
3
|
+
'use strict';
|
|
3
4
|
|
|
4
5
|
systemDictionary = {
|
|
5
|
-
|
|
6
|
-
en:
|
|
7
|
-
de:
|
|
8
|
-
ru:
|
|
9
|
-
pt:
|
|
10
|
-
nl:
|
|
6
|
+
'bmw adapter settings': {
|
|
7
|
+
en: 'Adapter settings for bmw',
|
|
8
|
+
de: 'Adaptereinstellungen für bmw',
|
|
9
|
+
ru: 'Настройки адаптера для bmw',
|
|
10
|
+
pt: 'Configurações do adaptador para bmw',
|
|
11
|
+
nl: 'Adapterinstellingen voor bmw',
|
|
11
12
|
fr: "Paramètres d'adaptateur pour bmw",
|
|
12
13
|
it: "Impostazioni dell'adattatore per bmw",
|
|
13
|
-
es:
|
|
14
|
-
pl:
|
|
15
|
-
|
|
14
|
+
es: 'Ajustes del adaptador para bmw',
|
|
15
|
+
pl: 'Ustawienia adaptera dla bmw',
|
|
16
|
+
'zh-cn': 'bmw2的适配器设置',
|
|
16
17
|
},
|
|
17
|
-
|
|
18
|
-
en:
|
|
19
|
-
de:
|
|
20
|
-
ru:
|
|
21
|
-
pt:
|
|
22
|
-
nl:
|
|
18
|
+
'App Email': {
|
|
19
|
+
en: 'App Email',
|
|
20
|
+
de: 'App-E-Mail',
|
|
21
|
+
ru: 'Электронная почта приложения',
|
|
22
|
+
pt: 'Email do aplicativo',
|
|
23
|
+
nl: 'App-e-mail',
|
|
23
24
|
fr: "Courriel de l'application",
|
|
24
25
|
it: "E-mail dell'app",
|
|
25
|
-
es:
|
|
26
|
-
pl:
|
|
27
|
-
|
|
26
|
+
es: 'Correo electrónico de la aplicación',
|
|
27
|
+
pl: 'E-mail aplikacji',
|
|
28
|
+
'zh-cn': '应用电子邮件',
|
|
28
29
|
},
|
|
29
|
-
|
|
30
|
-
en:
|
|
31
|
-
de:
|
|
32
|
-
ru:
|
|
33
|
-
pt:
|
|
34
|
-
nl:
|
|
30
|
+
'App Password': {
|
|
31
|
+
en: 'App Password',
|
|
32
|
+
de: 'App-Passwort',
|
|
33
|
+
ru: 'Пароль приложения',
|
|
34
|
+
pt: 'Senha de app',
|
|
35
|
+
nl: 'App-wachtwoord',
|
|
35
36
|
fr: "Mot de passe de l'application",
|
|
36
37
|
it: "Password dell'app",
|
|
37
|
-
es:
|
|
38
|
-
pl:
|
|
39
|
-
|
|
38
|
+
es: 'Contraseña de la aplicación',
|
|
39
|
+
pl: 'Hasło do aplikacji',
|
|
40
|
+
'zh-cn': '应用密码',
|
|
40
41
|
},
|
|
41
|
-
|
|
42
|
-
en:
|
|
43
|
-
de:
|
|
44
|
-
ru:
|
|
45
|
-
pt:
|
|
46
|
-
nl:
|
|
47
|
-
fr:
|
|
48
|
-
it:
|
|
49
|
-
es:
|
|
50
|
-
pl:
|
|
51
|
-
|
|
42
|
+
'Update interval (in minutes)': {
|
|
43
|
+
en: 'Update interval (in minutes)',
|
|
44
|
+
de: 'Aktualisierungsintervall (in Minuten)',
|
|
45
|
+
ru: 'Интервал обновления (в минутах)',
|
|
46
|
+
pt: 'Intervalo de atualização (em minutos)',
|
|
47
|
+
nl: 'Update-interval (in minuten)',
|
|
48
|
+
fr: 'Intervalle de mise à jour (en minutes)',
|
|
49
|
+
it: 'Intervallo di aggiornamento (in minuti)',
|
|
50
|
+
es: 'Intervalo de actualización (en minutos)',
|
|
51
|
+
pl: 'Interwał aktualizacji (w minutach)',
|
|
52
|
+
'zh-cn': '更新间隔(分钟)',
|
|
52
53
|
},
|
|
53
54
|
Brand: {
|
|
54
|
-
en:
|
|
55
|
-
de:
|
|
56
|
-
ru:
|
|
57
|
-
pt:
|
|
58
|
-
nl:
|
|
59
|
-
fr:
|
|
60
|
-
it:
|
|
61
|
-
es:
|
|
62
|
-
pl:
|
|
63
|
-
|
|
55
|
+
en: 'Brand',
|
|
56
|
+
de: 'Marke',
|
|
57
|
+
ru: 'Марка',
|
|
58
|
+
pt: 'Marca',
|
|
59
|
+
nl: 'Brand',
|
|
60
|
+
fr: 'Marque',
|
|
61
|
+
it: 'Marca',
|
|
62
|
+
es: 'Marca',
|
|
63
|
+
pl: 'Brandy',
|
|
64
|
+
'zh-cn': '陪审团',
|
|
64
65
|
},
|
|
65
66
|
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const globals = require('globals');
|
|
2
|
+
const js = require('@eslint/js');
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
FlatCompat,
|
|
6
|
+
} = require('@eslint/eslintrc');
|
|
7
|
+
|
|
8
|
+
const compat = new FlatCompat({
|
|
9
|
+
baseDirectory: __dirname,
|
|
10
|
+
recommendedConfig: js.configs.recommended,
|
|
11
|
+
allConfig: js.configs.all
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
module.exports = [...compat.extends('eslint:recommended'), {
|
|
15
|
+
plugins: {},
|
|
16
|
+
|
|
17
|
+
languageOptions: {
|
|
18
|
+
globals: {
|
|
19
|
+
...globals.node,
|
|
20
|
+
...globals.mocha,
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
ecmaVersion: 2020,
|
|
24
|
+
sourceType: 'commonjs',
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
rules: {
|
|
28
|
+
indent: ['error', 2, {
|
|
29
|
+
SwitchCase: 1,
|
|
30
|
+
}],
|
|
31
|
+
|
|
32
|
+
'no-console': 'off',
|
|
33
|
+
|
|
34
|
+
'no-unused-vars': ['error', {
|
|
35
|
+
ignoreRestSiblings: true,
|
|
36
|
+
argsIgnorePattern: '^_',
|
|
37
|
+
}],
|
|
38
|
+
|
|
39
|
+
'no-var': 'error',
|
|
40
|
+
'no-trailing-spaces': 'error',
|
|
41
|
+
'prefer-const': 'error',
|
|
42
|
+
|
|
43
|
+
quotes: ['error', 'single', {
|
|
44
|
+
avoidEscape: true,
|
|
45
|
+
allowTemplateLiterals: true,
|
|
46
|
+
}],
|
|
47
|
+
|
|
48
|
+
semi: ['error', 'always'],
|
|
49
|
+
},
|
|
50
|
+
}];
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "bmw",
|
|
4
|
-
"version": "2.8.
|
|
4
|
+
"version": "2.8.3",
|
|
5
5
|
"news": {
|
|
6
|
+
"2.8.3": {
|
|
7
|
+
"en": "login fixed",
|
|
8
|
+
"de": "Anmeldung gefixt",
|
|
9
|
+
"ru": "фиксированный",
|
|
10
|
+
"pt": "login fixo",
|
|
11
|
+
"nl": "login vast",
|
|
12
|
+
"fr": "login corrigé",
|
|
13
|
+
"it": "login fisso",
|
|
14
|
+
"es": "login fijo",
|
|
15
|
+
"pl": "login stały",
|
|
16
|
+
"uk": "логін",
|
|
17
|
+
"zh-cn": "登录已固定"
|
|
18
|
+
},
|
|
6
19
|
"2.8.2": {
|
|
7
20
|
"en": "fix error getvehicles v2 failed",
|
|
8
21
|
"de": "fehlerbehebung v2 versagt",
|
|
@@ -44,10 +57,6 @@
|
|
|
44
57
|
"2.6.3": {
|
|
45
58
|
"en": "Add start and stop charging remotes",
|
|
46
59
|
"de": "Start und Stop Charging Remotes hinzugefügt"
|
|
47
|
-
},
|
|
48
|
-
"2.6.2": {
|
|
49
|
-
"en": "Fix Charging response parsing",
|
|
50
|
-
"de": "Fix Charging Antwort Verarbeitung"
|
|
51
60
|
}
|
|
52
61
|
},
|
|
53
62
|
"titleLang": {
|
|
@@ -76,12 +85,8 @@
|
|
|
76
85
|
"uk": "Adapter for BMW",
|
|
77
86
|
"zh-cn": "宝马适配器"
|
|
78
87
|
},
|
|
79
|
-
"authors": [
|
|
80
|
-
|
|
81
|
-
],
|
|
82
|
-
"keywords": [
|
|
83
|
-
"BMW"
|
|
84
|
-
],
|
|
88
|
+
"authors": ["TA2k <tombox2020@gmail.com>"],
|
|
89
|
+
"keywords": ["BMW"],
|
|
85
90
|
"license": "MIT",
|
|
86
91
|
"platform": "Javascript/Node.js",
|
|
87
92
|
"main": "main.js",
|
|
@@ -112,18 +117,15 @@
|
|
|
112
117
|
}
|
|
113
118
|
]
|
|
114
119
|
},
|
|
115
|
-
"encryptedNative": [
|
|
116
|
-
|
|
117
|
-
],
|
|
118
|
-
"protectedNative": [
|
|
119
|
-
"password"
|
|
120
|
-
],
|
|
120
|
+
"encryptedNative": ["password"],
|
|
121
|
+
"protectedNative": ["password"],
|
|
121
122
|
"native": {
|
|
122
123
|
"username": "",
|
|
123
124
|
"password": "",
|
|
124
125
|
"interval": 5,
|
|
125
126
|
"brand": "bmw",
|
|
126
|
-
"ignorelist": ""
|
|
127
|
+
"ignorelist": "",
|
|
128
|
+
"captcha": ""
|
|
127
129
|
},
|
|
128
130
|
"objects": [],
|
|
129
131
|
"instanceObjects": [
|
package/lib/extractKeys.js
CHANGED
|
@@ -215,7 +215,9 @@ function extractArray(adapter, element, key, path, write, preferedArrayName, for
|
|
|
215
215
|
function isJsonString(str) {
|
|
216
216
|
try {
|
|
217
217
|
JSON.parse(str);
|
|
218
|
+
// eslint-disable-next-line no-unused-vars
|
|
218
219
|
} catch (e) {
|
|
220
|
+
|
|
219
221
|
return false;
|
|
220
222
|
}
|
|
221
223
|
return true;
|
package/main.js
CHANGED
|
@@ -186,7 +186,20 @@ class Bmw extends utils.Adapter {
|
|
|
186
186
|
this.log.error('Please set username and password');
|
|
187
187
|
return;
|
|
188
188
|
}
|
|
189
|
-
await this.
|
|
189
|
+
const sessionState = await this.getStateAsync('auth.session');
|
|
190
|
+
if (sessionState && sessionState.val) {
|
|
191
|
+
this.session = JSON.parse(sessionState.val);
|
|
192
|
+
this.log.info('Session found. If the login fails please delete bmw.0.auth.session and restart the adapter');
|
|
193
|
+
this.log.debug(JSON.stringify(this.session));
|
|
194
|
+
await this.refreshToken();
|
|
195
|
+
} else {
|
|
196
|
+
if (!this.config.captcha) {
|
|
197
|
+
this.log.error('Please generate a captcha in the instance settings');
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
await this.login();
|
|
202
|
+
}
|
|
190
203
|
|
|
191
204
|
if (this.session.access_token) {
|
|
192
205
|
this.log.info(`Start getting ${this.config.brand} vehicles`);
|
|
@@ -196,29 +209,20 @@ class Bmw extends utils.Adapter {
|
|
|
196
209
|
await this.updateDemands();
|
|
197
210
|
await this.sleep(5000);
|
|
198
211
|
await this.updateTrips();
|
|
199
|
-
this.updateInterval = setInterval(
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
this.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
24 * 60 * 60 * 1000,
|
|
214
|
-
);
|
|
215
|
-
this.refreshTokenInterval = setInterval(
|
|
216
|
-
async () => {
|
|
217
|
-
await this.refreshToken();
|
|
218
|
-
await this.sleep(5000);
|
|
219
|
-
},
|
|
220
|
-
(this.session.expires_in - 123) * 1000,
|
|
221
|
-
);
|
|
212
|
+
this.updateInterval = setInterval(async () => {
|
|
213
|
+
await this.sleep(2000);
|
|
214
|
+
await this.updateDevices();
|
|
215
|
+
}, this.config.interval * 60 * 1000);
|
|
216
|
+
this.demandInterval = setInterval(async () => {
|
|
217
|
+
await this.sleep(2000);
|
|
218
|
+
await this.updateDemands();
|
|
219
|
+
await this.sleep(5000);
|
|
220
|
+
await this.updateTrips();
|
|
221
|
+
}, 24 * 60 * 60 * 1000);
|
|
222
|
+
this.refreshTokenInterval = setInterval(async () => {
|
|
223
|
+
await this.refreshToken();
|
|
224
|
+
await this.sleep(5000);
|
|
225
|
+
}, (this.session.expires_in - 123) * 1000);
|
|
222
226
|
}
|
|
223
227
|
}
|
|
224
228
|
async login() {
|
|
@@ -228,6 +232,7 @@ class Bmw extends utils.Adapter {
|
|
|
228
232
|
'Mozilla/5.0 (iPhone; CPU iPhone OS 12_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Mobile/15E148 Safari/604.1',
|
|
229
233
|
'Accept-Language': 'de-de',
|
|
230
234
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
235
|
+
hcaptchatoken: this.config.captcha,
|
|
231
236
|
};
|
|
232
237
|
const [code_verifier, codeChallenge] = this.getCodeChallenge();
|
|
233
238
|
const data = {
|
|
@@ -251,27 +256,28 @@ class Bmw extends utils.Adapter {
|
|
|
251
256
|
data: qs.stringify(data),
|
|
252
257
|
withCredentials: true,
|
|
253
258
|
})
|
|
254
|
-
.then((res) => {
|
|
259
|
+
.then(async (res) => {
|
|
255
260
|
this.log.debug(JSON.stringify(res.data));
|
|
256
261
|
return res.data;
|
|
257
262
|
})
|
|
258
|
-
.catch((error) => {
|
|
263
|
+
.catch(async (error) => {
|
|
259
264
|
this.log.error('Login failed');
|
|
260
265
|
this.log.error(error);
|
|
261
266
|
if (error.response) {
|
|
262
267
|
this.log.error(JSON.stringify(error.response.data));
|
|
263
268
|
}
|
|
264
269
|
if (error.response && error.response.status === 401) {
|
|
265
|
-
this.log.error('Please check username and password or
|
|
266
|
-
|
|
270
|
+
this.log.error('Please check username and password or generate a new captcha in the instance settings');
|
|
271
|
+
this.log.error('Please wait 5 minutes before trying again');
|
|
267
272
|
this.log.error('Start relogin in 5min');
|
|
273
|
+
|
|
268
274
|
this.reLoginTimeout && clearTimeout(this.reLoginTimeout);
|
|
269
|
-
this.reLoginTimeout = setTimeout(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
);
|
|
275
|
+
this.reLoginTimeout = setTimeout(async () => {
|
|
276
|
+
//get adapter settings and set captcha to null
|
|
277
|
+
const adapterSettings = await this.getForeignObjectAsync('system.adapter.' + this.namespace);
|
|
278
|
+
adapterSettings.native.captcha = null;
|
|
279
|
+
await this.setForeignObjectAsync('system.adapter.' + this.namespace, adapterSettings);
|
|
280
|
+
}, 5000 * 60 * 1);
|
|
275
281
|
}
|
|
276
282
|
if (error.response && error.response.status === 400) {
|
|
277
283
|
this.log.error('Please check username and password');
|
|
@@ -326,9 +332,29 @@ class Bmw extends utils.Adapter {
|
|
|
326
332
|
},
|
|
327
333
|
data: 'code=' + code + '&redirect_uri=com.bmw.connected://oauth&grant_type=authorization_code&code_verifier=' + code_verifier,
|
|
328
334
|
})
|
|
329
|
-
.then((res) => {
|
|
335
|
+
.then(async (res) => {
|
|
330
336
|
this.log.debug(JSON.stringify(res.data));
|
|
331
337
|
this.session = res.data;
|
|
338
|
+
await this.extendObject('auth', {
|
|
339
|
+
type: 'channel',
|
|
340
|
+
common: {
|
|
341
|
+
name: 'Authentification Information',
|
|
342
|
+
},
|
|
343
|
+
native: {},
|
|
344
|
+
});
|
|
345
|
+
await this.extendObject('auth.session', {
|
|
346
|
+
type: 'state',
|
|
347
|
+
common: {
|
|
348
|
+
name: 'Session Token',
|
|
349
|
+
type: 'string',
|
|
350
|
+
role: 'value',
|
|
351
|
+
read: true,
|
|
352
|
+
write: false,
|
|
353
|
+
},
|
|
354
|
+
native: {},
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
this.setState('auth.session', JSON.stringify(this.session), true);
|
|
332
358
|
this.setState('info.connection', true, true);
|
|
333
359
|
return res.data;
|
|
334
360
|
})
|
|
@@ -451,12 +477,9 @@ class Bmw extends utils.Adapter {
|
|
|
451
477
|
}
|
|
452
478
|
this.log.info('Adapter will retry in 3 minutes to get vehicles');
|
|
453
479
|
this.reLoginTimeout && clearTimeout(this.reLoginTimeout);
|
|
454
|
-
this.reLoginTimeout = setTimeout(
|
|
455
|
-
()
|
|
456
|
-
|
|
457
|
-
},
|
|
458
|
-
1000 * 60 * 3,
|
|
459
|
-
);
|
|
480
|
+
this.reLoginTimeout = setTimeout(() => {
|
|
481
|
+
this.getVehiclesv2();
|
|
482
|
+
}, 1000 * 60 * 3);
|
|
460
483
|
});
|
|
461
484
|
await this.sleep(5000);
|
|
462
485
|
}
|
|
@@ -475,8 +498,7 @@ class Bmw extends utils.Adapter {
|
|
|
475
498
|
headers['bmw-vin'] = vin;
|
|
476
499
|
await this.requestClient({
|
|
477
500
|
method: 'get',
|
|
478
|
-
url:
|
|
479
|
-
'https://cocoapi.bmwgroup.com/eadrax-vcs/v4/vehicles/state?apptimezone=120&appDateTime=' + Date.now() + '&tireGuardMode=ENABLED',
|
|
501
|
+
url: 'https://cocoapi.bmwgroup.com/eadrax-vcs/v4/vehicles/state?apptimezone=120&appDateTime=' + Date.now() + '&tireGuardMode=ENABLED',
|
|
480
502
|
headers: headers,
|
|
481
503
|
})
|
|
482
504
|
.then(async (res) => {
|
|
@@ -820,6 +842,8 @@ class Bmw extends utils.Adapter {
|
|
|
820
842
|
.then((res) => {
|
|
821
843
|
this.log.debug(JSON.stringify(res.data));
|
|
822
844
|
this.session = res.data;
|
|
845
|
+
|
|
846
|
+
this.setState('auth.session', JSON.stringify(this.session), true);
|
|
823
847
|
this.setState('info.connection', true, true);
|
|
824
848
|
return res.data;
|
|
825
849
|
})
|
|
@@ -829,12 +853,9 @@ class Bmw extends utils.Adapter {
|
|
|
829
853
|
error.response && this.log.error(JSON.stringify(error.response.data));
|
|
830
854
|
this.log.error('Start relogin in 1min');
|
|
831
855
|
this.reLoginTimeout && clearTimeout(this.reLoginTimeout);
|
|
832
|
-
this.reLoginTimeout = setTimeout(
|
|
833
|
-
()
|
|
834
|
-
|
|
835
|
-
},
|
|
836
|
-
1000 * 60 * 1,
|
|
837
|
-
);
|
|
856
|
+
this.reLoginTimeout = setTimeout(() => {
|
|
857
|
+
this.login();
|
|
858
|
+
}, 1000 * 60 * 1);
|
|
838
859
|
});
|
|
839
860
|
}
|
|
840
861
|
|
|
@@ -842,15 +863,22 @@ class Bmw extends utils.Adapter {
|
|
|
842
863
|
* Is called when adapter shuts down - callback has to be called under any circumstances!
|
|
843
864
|
* @param {() => void} callback
|
|
844
865
|
*/
|
|
845
|
-
onUnload(callback) {
|
|
866
|
+
async onUnload(callback) {
|
|
846
867
|
try {
|
|
847
868
|
clearTimeout(this.refreshTimeout);
|
|
848
869
|
clearTimeout(this.reLoginTimeout);
|
|
849
870
|
clearInterval(this.updateInterval);
|
|
850
871
|
clearInterval(this.refreshTokenInterval);
|
|
851
872
|
this.demandInterval && clearInterval(this.demandInterval);
|
|
873
|
+
//get adapter settings and set captcha to null
|
|
874
|
+
if (this.config.captcha) {
|
|
875
|
+
const adapterSettings = await this.getForeignObjectAsync('system.adapter.' + this.namespace);
|
|
876
|
+
adapterSettings.native.captcha = null;
|
|
877
|
+
await this.setForeignObjectAsync('system.adapter.' + this.namespace, adapterSettings);
|
|
878
|
+
}
|
|
852
879
|
callback();
|
|
853
880
|
} catch (e) {
|
|
881
|
+
this.log.error(e);
|
|
854
882
|
callback();
|
|
855
883
|
}
|
|
856
884
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.bmw",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.3",
|
|
4
4
|
"description": "Adapter for BMW",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "TA2k",
|
|
@@ -16,27 +16,30 @@
|
|
|
16
16
|
"url": "https://github.com/TA2k/ioBroker.bmw"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@iobroker/adapter-core": "^3.2.
|
|
19
|
+
"@iobroker/adapter-core": "^3.2.2",
|
|
20
20
|
"axios": "^1.7.7",
|
|
21
|
-
"http-cookie-agent": "^
|
|
21
|
+
"http-cookie-agent": "^6.0.6",
|
|
22
22
|
"json-bigint": "^1.0.0",
|
|
23
23
|
"json2iob": "^2.6.12",
|
|
24
|
-
"qs": "^6.13.
|
|
25
|
-
"tough-cookie": "^
|
|
24
|
+
"qs": "^6.13.1",
|
|
25
|
+
"tough-cookie": "^5.0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@alcalzone/release-script": "^3.8.0",
|
|
29
29
|
"@alcalzone/release-script-plugin-iobroker": "^3.7.2",
|
|
30
30
|
"@alcalzone/release-script-plugin-license": "^3.7.0",
|
|
31
31
|
"@alcalzone/release-script-plugin-manual-review": "^3.7.0",
|
|
32
|
-
"@
|
|
32
|
+
"@eslint/eslintrc": "^3.2.0",
|
|
33
|
+
"@eslint/js": "^9.15.0",
|
|
34
|
+
"@iobroker/testing": "^5.0.0",
|
|
33
35
|
"@tsconfig/node16": "^16.1.3",
|
|
34
|
-
"@types/node": "^
|
|
35
|
-
"eslint": "^
|
|
36
|
+
"@types/node": "^22.9.0",
|
|
37
|
+
"eslint": "^9.15.0",
|
|
36
38
|
"eslint-config-prettier": "^9.1.0",
|
|
37
39
|
"eslint-plugin-prettier": "^5.2.1",
|
|
40
|
+
"globals": "^15.12.0",
|
|
38
41
|
"prettier": "^3.3.3",
|
|
39
|
-
"typescript": "~5.6.
|
|
42
|
+
"typescript": "~5.6.3"
|
|
40
43
|
},
|
|
41
44
|
"main": "main.js",
|
|
42
45
|
"scripts": {
|