iobroker.bmw 2.5.5 → 2.5.7
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 +3 -0
- package/admin/index_m.html +12 -3
- package/admin/words.js +60 -36
- package/io-package.json +10 -2
- package/main.js +95 -100
- package/package.json +15 -15
package/README.md
CHANGED
package/admin/index_m.html
CHANGED
|
@@ -71,20 +71,29 @@
|
|
|
71
71
|
<div class="row">
|
|
72
72
|
<div class="col s6 input-field">
|
|
73
73
|
<input type="text" class="value" id="username" />
|
|
74
|
-
<label for="username" class="translate">
|
|
74
|
+
<label for="username" class="translate">App Email</label>
|
|
75
75
|
</div>
|
|
76
76
|
</div>
|
|
77
77
|
<div class="row">
|
|
78
78
|
<div class="col s6 input-field">
|
|
79
79
|
<input type="password" class="value" id="password" />
|
|
80
|
-
<label for="password" class="translate">
|
|
80
|
+
<label for="password" class="translate">App Password</label>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
<div class="row">
|
|
84
|
+
<div class="col s2 input-field">
|
|
85
|
+
<select id="brand" class="value">
|
|
86
|
+
<option value="bmw">BMW</option>
|
|
87
|
+
<option value="mini">Mini</option>
|
|
88
|
+
</select>
|
|
89
|
+
<label for="brand" class="translate">Brand</label>
|
|
81
90
|
</div>
|
|
82
91
|
</div>
|
|
83
92
|
|
|
84
93
|
<div class="row">
|
|
85
94
|
<div class="col s2 input-field">
|
|
86
95
|
<input type="number" class="value" id="interval" />
|
|
87
|
-
<label for="interval" class="translate">Update interval in minutes</label>
|
|
96
|
+
<label for="interval" class="translate">Update interval (in minutes)"</label>
|
|
88
97
|
</div>
|
|
89
98
|
</div>
|
|
90
99
|
</div>
|
package/admin/words.js
CHANGED
|
@@ -2,40 +2,64 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
systemDictionary = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
5
|
+
"bmw adapter settings": {
|
|
6
|
+
en: "Adapter settings for bmw",
|
|
7
|
+
de: "Adaptereinstellungen für bmw",
|
|
8
|
+
ru: "Настройки адаптера для bmw",
|
|
9
|
+
pt: "Configurações do adaptador para bmw",
|
|
10
|
+
nl: "Adapterinstellingen voor bmw",
|
|
11
|
+
fr: "Paramètres d'adaptateur pour bmw",
|
|
12
|
+
it: "Impostazioni dell'adattatore per bmw",
|
|
13
|
+
es: "Ajustes del adaptador para bmw",
|
|
14
|
+
pl: "Ustawienia adaptera dla bmw",
|
|
15
|
+
"zh-cn": "bmw2的适配器设置",
|
|
16
|
+
},
|
|
17
|
+
"App Email": {
|
|
18
|
+
en: "App Email",
|
|
19
|
+
de: "App-E-Mail",
|
|
20
|
+
ru: "Электронная почта приложения",
|
|
21
|
+
pt: "Email do aplicativo",
|
|
22
|
+
nl: "App-e-mail",
|
|
23
|
+
fr: "Courriel de l'application",
|
|
24
|
+
it: "E-mail dell'app",
|
|
25
|
+
es: "Correo electrónico de la aplicación",
|
|
26
|
+
pl: "E-mail aplikacji",
|
|
27
|
+
"zh-cn": "应用电子邮件",
|
|
28
|
+
},
|
|
29
|
+
"App Password": {
|
|
30
|
+
en: "App Password",
|
|
31
|
+
de: "App-Passwort",
|
|
32
|
+
ru: "Пароль приложения",
|
|
33
|
+
pt: "Senha de app",
|
|
34
|
+
nl: "App-wachtwoord",
|
|
35
|
+
fr: "Mot de passe de l'application",
|
|
36
|
+
it: "Password dell'app",
|
|
37
|
+
es: "Contraseña de la aplicación",
|
|
38
|
+
pl: "Hasło do aplikacji",
|
|
39
|
+
"zh-cn": "应用密码",
|
|
40
|
+
},
|
|
41
|
+
"Update interval (in minutes)": {
|
|
42
|
+
en: "Update interval (in minutes)",
|
|
43
|
+
de: "Aktualisierungsintervall (in Minuten)",
|
|
44
|
+
ru: "Интервал обновления (в минутах)",
|
|
45
|
+
pt: "Intervalo de atualização (em minutos)",
|
|
46
|
+
nl: "Update-interval (in minuten)",
|
|
47
|
+
fr: "Intervalle de mise à jour (en minutes)",
|
|
48
|
+
it: "Intervallo di aggiornamento (in minuti)",
|
|
49
|
+
es: "Intervalo de actualización (en minutos)",
|
|
50
|
+
pl: "Interwał aktualizacji (w minutach)",
|
|
51
|
+
"zh-cn": "更新间隔(分钟)",
|
|
52
|
+
},
|
|
53
|
+
Brand: {
|
|
54
|
+
en: "Brand",
|
|
55
|
+
de: "Marke",
|
|
56
|
+
ru: "Марка",
|
|
57
|
+
pt: "Marca",
|
|
58
|
+
nl: "Brand",
|
|
59
|
+
fr: "Marque",
|
|
60
|
+
it: "Marca",
|
|
61
|
+
es: "Marca",
|
|
62
|
+
pl: "Brandy",
|
|
63
|
+
"zh-cn": "陪审团",
|
|
64
|
+
},
|
|
41
65
|
};
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "bmw",
|
|
4
|
-
"version": "2.5.
|
|
4
|
+
"version": "2.5.7",
|
|
5
5
|
"news": {
|
|
6
|
+
"2.5.7": {
|
|
7
|
+
"en": "Fix Quota problem",
|
|
8
|
+
"de": "Quota Problem es muss jetzt explizit die Marke BMW oder Mini in den Optionen gewählt werden."
|
|
9
|
+
},
|
|
10
|
+
"2.5.6": {
|
|
11
|
+
"en": "Fix charging message"
|
|
12
|
+
},
|
|
6
13
|
"2.5.5": {
|
|
7
14
|
"en": "Fix login"
|
|
8
15
|
},
|
|
@@ -109,7 +116,8 @@
|
|
|
109
116
|
"native": {
|
|
110
117
|
"username": "",
|
|
111
118
|
"password": "",
|
|
112
|
-
"interval": 5
|
|
119
|
+
"interval": 5,
|
|
120
|
+
"brand": "bmw"
|
|
113
121
|
},
|
|
114
122
|
"objects": [],
|
|
115
123
|
"instanceObjects": [
|
package/main.js
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
// The adapter-core module gives you access to the core ioBroker functions
|
|
8
8
|
// you need to create an adapter
|
|
9
9
|
const utils = require("@iobroker/adapter-core");
|
|
10
|
-
const axios = require("axios");
|
|
10
|
+
const axios = require("axios").default;
|
|
11
11
|
|
|
12
|
-
const { HttpsCookieAgent } = require("http-cookie-agent");
|
|
12
|
+
const { HttpsCookieAgent } = require("http-cookie-agent/http");
|
|
13
13
|
const crypto = require("crypto");
|
|
14
14
|
const qs = require("qs");
|
|
15
15
|
const { extractKeys } = require("./lib/extractKeys");
|
|
@@ -29,6 +29,20 @@ class Bmw extends utils.Adapter {
|
|
|
29
29
|
this.userAgent = "My%20BMW/8932 CFNetwork/978.0.7 Darwin/18.7.0";
|
|
30
30
|
this.userAgentDart = "Dart/2.14 (dart:io)";
|
|
31
31
|
this.xuserAgent = "android(SP1A.210812.016.C1);brand;99.0.0(99999);row";
|
|
32
|
+
this.updateInterval;
|
|
33
|
+
this.reLoginTimeout;
|
|
34
|
+
this.refreshTokenInterval;
|
|
35
|
+
this.extractKeys = extractKeys;
|
|
36
|
+
this.vinArray = [];
|
|
37
|
+
this.session = {};
|
|
38
|
+
this.statusBlock = {};
|
|
39
|
+
this.nonChargingHistory = {};
|
|
40
|
+
this.cookieJar = new tough.CookieJar(null, { ignoreError: true });
|
|
41
|
+
|
|
42
|
+
this.requestClient = axios.create({
|
|
43
|
+
withCredentials: true,
|
|
44
|
+
httpsAgent: new HttpsCookieAgent({ cookies: { jar: this.cookieJar } }),
|
|
45
|
+
});
|
|
32
46
|
}
|
|
33
47
|
|
|
34
48
|
/**
|
|
@@ -41,23 +55,7 @@ class Bmw extends utils.Adapter {
|
|
|
41
55
|
this.log.info("Set interval to minimum 0.5");
|
|
42
56
|
this.config.interval = 0.5;
|
|
43
57
|
}
|
|
44
|
-
this.cookieJar = new tough.CookieJar(null, { ignoreError: true });
|
|
45
58
|
|
|
46
|
-
this.requestClient = axios.create({
|
|
47
|
-
jar: this.cookieJar,
|
|
48
|
-
withCredentials: true,
|
|
49
|
-
httpsAgent: new HttpsCookieAgent({
|
|
50
|
-
jar: this.cookieJar,
|
|
51
|
-
}),
|
|
52
|
-
});
|
|
53
|
-
this.updateInterval = null;
|
|
54
|
-
this.reLoginTimeout = null;
|
|
55
|
-
this.refreshTokenTimeout = null;
|
|
56
|
-
this.extractKeys = extractKeys;
|
|
57
|
-
this.vinArray = [];
|
|
58
|
-
this.session = {};
|
|
59
|
-
this.statusBlock = {};
|
|
60
|
-
this.nonChargingHistory = {};
|
|
61
59
|
this.subscribeStates("*");
|
|
62
60
|
if (!this.config.username || !this.config.password) {
|
|
63
61
|
this.log.error("Please set username and password");
|
|
@@ -67,6 +65,8 @@ class Bmw extends utils.Adapter {
|
|
|
67
65
|
if (this.session.access_token) {
|
|
68
66
|
// await this.getVehicles(); //old depracted api
|
|
69
67
|
await this.cleanObjects();
|
|
68
|
+
|
|
69
|
+
this.log.info(`Start getting ${this.config.brand} vehicles`);
|
|
70
70
|
await this.getVehiclesv2();
|
|
71
71
|
this.updateInterval = setInterval(async () => {
|
|
72
72
|
await this.getVehiclesv2();
|
|
@@ -104,7 +104,6 @@ class Bmw extends utils.Adapter {
|
|
|
104
104
|
url: "https://customer.bmwgroup.com/gcdm/oauth/authenticate",
|
|
105
105
|
headers: headers,
|
|
106
106
|
data: qs.stringify(data),
|
|
107
|
-
jar: this.cookieJar,
|
|
108
107
|
withCredentials: true,
|
|
109
108
|
})
|
|
110
109
|
.then((res) => {
|
|
@@ -144,7 +143,6 @@ class Bmw extends utils.Adapter {
|
|
|
144
143
|
url: "https://customer.bmwgroup.com/gcdm/oauth/authenticate",
|
|
145
144
|
headers: headers,
|
|
146
145
|
data: qs.stringify(data),
|
|
147
|
-
jar: this.cookieJar,
|
|
148
146
|
withCredentials: true,
|
|
149
147
|
maxRedirects: 0,
|
|
150
148
|
})
|
|
@@ -170,8 +168,6 @@ class Bmw extends utils.Adapter {
|
|
|
170
168
|
await this.requestClient({
|
|
171
169
|
method: "post",
|
|
172
170
|
url: "https://customer.bmwgroup.com/gcdm/oauth/token",
|
|
173
|
-
|
|
174
|
-
jar: this.cookieJar,
|
|
175
171
|
withCredentials: true,
|
|
176
172
|
headers: {
|
|
177
173
|
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
@@ -255,85 +251,86 @@ class Bmw extends utils.Adapter {
|
|
|
255
251
|
});
|
|
256
252
|
}
|
|
257
253
|
async getVehiclesv2() {
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
this.
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
"24-hour-format": "true",
|
|
268
|
-
};
|
|
254
|
+
const brand = this.config.brand;
|
|
255
|
+
const headers = {
|
|
256
|
+
"user-agent": this.userAgentDart,
|
|
257
|
+
"x-user-agent": this.xuserAgent.replace(";brand;", `;${brand};`),
|
|
258
|
+
authorization: "Bearer " + this.session.access_token,
|
|
259
|
+
"accept-language": "de-DE",
|
|
260
|
+
host: "cocoapi.bmwgroup.com",
|
|
261
|
+
"24-hour-format": "true",
|
|
262
|
+
};
|
|
269
263
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
264
|
+
await this.requestClient({
|
|
265
|
+
method: "get",
|
|
266
|
+
url: "https://cocoapi.bmwgroup.com/eadrax-vcs/v1/vehicles?apptimezone=120&appDateTime=" + Date.now() + "&tireGuardMode=ENABLED",
|
|
267
|
+
headers: headers,
|
|
268
|
+
})
|
|
269
|
+
.then(async (res) => {
|
|
270
|
+
this.log.debug(JSON.stringify(res.data));
|
|
271
|
+
this.log.info(`Found ${res.data.length} ${brand} vehicles`);
|
|
272
|
+
if (res.data.length === 0) {
|
|
273
|
+
this.log.info(`No ${brand} vehicles found please check brand in instance settings`);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
for (const vehicle of res.data) {
|
|
277
|
+
await this.setObjectNotExistsAsync(vehicle.vin, {
|
|
278
|
+
type: "device",
|
|
279
|
+
common: {
|
|
280
|
+
name: vehicle.model,
|
|
281
|
+
},
|
|
282
|
+
native: {},
|
|
283
|
+
});
|
|
277
284
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
285
|
+
await this.setObjectNotExistsAsync(vehicle.vin + ".properties", {
|
|
286
|
+
type: "channel",
|
|
287
|
+
common: {
|
|
288
|
+
name: "Current status of the car v2",
|
|
289
|
+
},
|
|
290
|
+
native: {},
|
|
291
|
+
});
|
|
292
|
+
await this.setObjectNotExistsAsync(vehicle.vin + ".remotev2", {
|
|
293
|
+
type: "channel",
|
|
294
|
+
common: {
|
|
295
|
+
name: "Remote Controls",
|
|
296
|
+
},
|
|
297
|
+
native: {},
|
|
298
|
+
});
|
|
286
299
|
|
|
287
|
-
|
|
288
|
-
|
|
300
|
+
const remoteArray = [
|
|
301
|
+
{ command: "door-lock" },
|
|
302
|
+
{ command: "door-unlock" },
|
|
303
|
+
{ command: "horn-blow" },
|
|
304
|
+
{ command: "light-flash" },
|
|
305
|
+
{ command: "vehicle-finder" },
|
|
306
|
+
{ command: "climate-now_START" },
|
|
307
|
+
{ command: "climate-now_STOP" },
|
|
308
|
+
{ command: "force-refresh", name: "Force Refresh" },
|
|
309
|
+
];
|
|
310
|
+
remoteArray.forEach((remote) => {
|
|
311
|
+
this.setObjectNotExists(vehicle.vin + ".remotev2." + remote.command, {
|
|
312
|
+
type: "state",
|
|
289
313
|
common: {
|
|
290
|
-
name:
|
|
314
|
+
name: remote.name || "",
|
|
315
|
+
type: remote.type || "boolean",
|
|
316
|
+
role: remote.role || "boolean",
|
|
317
|
+
write: true,
|
|
318
|
+
read: true,
|
|
291
319
|
},
|
|
292
320
|
native: {},
|
|
293
321
|
});
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
{ command: "light-flash" },
|
|
307
|
-
{ command: "vehicle-finder" },
|
|
308
|
-
{ command: "climate-now_START" },
|
|
309
|
-
{ command: "climate-now_STOP" },
|
|
310
|
-
{ command: "force-refresh", name: "Force Refresh" },
|
|
311
|
-
];
|
|
312
|
-
remoteArray.forEach((remote) => {
|
|
313
|
-
this.setObjectNotExists(vehicle.vin + ".remotev2." + remote.command, {
|
|
314
|
-
type: "state",
|
|
315
|
-
common: {
|
|
316
|
-
name: remote.name || "",
|
|
317
|
-
type: remote.type || "boolean",
|
|
318
|
-
role: remote.role || "boolean",
|
|
319
|
-
write: true,
|
|
320
|
-
read: true,
|
|
321
|
-
},
|
|
322
|
-
native: {},
|
|
323
|
-
});
|
|
324
|
-
});
|
|
325
|
-
this.extractKeys(this, vehicle.vin, vehicle, null, true);
|
|
326
|
-
await this.sleep(5000);
|
|
327
|
-
this.updateChargingSessionv2(vehicle.vin);
|
|
328
|
-
}
|
|
329
|
-
})
|
|
330
|
-
.catch((error) => {
|
|
331
|
-
this.log.error("getvehicles v2 failed");
|
|
332
|
-
this.log.error(error);
|
|
333
|
-
error.response && this.log.error(JSON.stringify(error.response.data));
|
|
334
|
-
});
|
|
335
|
-
await this.sleep(5000);
|
|
336
|
-
}
|
|
322
|
+
});
|
|
323
|
+
this.extractKeys(this, vehicle.vin, vehicle, null, true);
|
|
324
|
+
await this.sleep(5000);
|
|
325
|
+
this.updateChargingSessionv2(vehicle.vin);
|
|
326
|
+
}
|
|
327
|
+
})
|
|
328
|
+
.catch((error) => {
|
|
329
|
+
this.log.error("getvehicles v2 failed");
|
|
330
|
+
this.log.error(error);
|
|
331
|
+
error.response && this.log.error(JSON.stringify(error.response.data));
|
|
332
|
+
});
|
|
333
|
+
await this.sleep(5000);
|
|
337
334
|
}
|
|
338
335
|
sleep(ms) {
|
|
339
336
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -344,7 +341,7 @@ class Bmw extends utils.Adapter {
|
|
|
344
341
|
}
|
|
345
342
|
const headers = {
|
|
346
343
|
"user-agent": this.userAgentDart,
|
|
347
|
-
"x-user-agent": this.xuserAgent.replace(";brand;",
|
|
344
|
+
"x-user-agent": this.xuserAgent.replace(";brand;", `;${this.config.brand};`),
|
|
348
345
|
authorization: "Bearer " + this.session.access_token,
|
|
349
346
|
"accept-language": "de-DE",
|
|
350
347
|
"24-hour-format": "true",
|
|
@@ -397,8 +394,8 @@ class Bmw extends utils.Adapter {
|
|
|
397
394
|
this.extractKeys(this, vin + element.path + dateFormatted, data);
|
|
398
395
|
})
|
|
399
396
|
.catch((error) => {
|
|
400
|
-
if (error.response
|
|
401
|
-
this.log.info("No charging session available. Ignore " + vin);
|
|
397
|
+
if (error.response) {
|
|
398
|
+
this.log.info("No charging session available. Ignore " + vin + "until restart");
|
|
402
399
|
this.nonChargingHistory[vin] = true;
|
|
403
400
|
return;
|
|
404
401
|
}
|
|
@@ -451,7 +448,6 @@ class Bmw extends utils.Adapter {
|
|
|
451
448
|
await this.requestClient({
|
|
452
449
|
method: "post",
|
|
453
450
|
url: "https://customer.bmwgroup.com/gcdm/oauth/token",
|
|
454
|
-
jar: this.cookieJar,
|
|
455
451
|
withCredentials: true,
|
|
456
452
|
headers: {
|
|
457
453
|
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
@@ -486,7 +482,6 @@ class Bmw extends utils.Adapter {
|
|
|
486
482
|
try {
|
|
487
483
|
clearTimeout(this.refreshTimeout);
|
|
488
484
|
clearTimeout(this.reLoginTimeout);
|
|
489
|
-
clearTimeout(this.refreshTokenTimeout);
|
|
490
485
|
clearInterval(this.updateInterval);
|
|
491
486
|
clearInterval(this.refreshTokenInterval);
|
|
492
487
|
callback();
|
|
@@ -521,7 +516,7 @@ class Bmw extends utils.Adapter {
|
|
|
521
516
|
|
|
522
517
|
const headers = {
|
|
523
518
|
"user-agent": this.userAgentDart,
|
|
524
|
-
"x-user-agent": this.xuserAgent.replace(";brand;",
|
|
519
|
+
"x-user-agent": this.xuserAgent.replace(";brand;", `;${this.config.brand};`),
|
|
525
520
|
authorization: "Bearer " + this.session.access_token,
|
|
526
521
|
"accept-language": "de-DE",
|
|
527
522
|
host: "cocoapi.bmwgroup.com",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.bmw",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.7",
|
|
4
4
|
"description": "Adapter for BMW",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "TA2k",
|
|
@@ -16,30 +16,30 @@
|
|
|
16
16
|
"url": "https://github.com/TA2k/ioBroker.bmw"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@iobroker/adapter-core": "^2.6.
|
|
20
|
-
"axios": "^0.
|
|
21
|
-
"http-cookie-agent": "^
|
|
19
|
+
"@iobroker/adapter-core": "^2.6.6",
|
|
20
|
+
"axios": "^0.27.2",
|
|
21
|
+
"http-cookie-agent": "^4.0.2",
|
|
22
22
|
"json-bigint": "^1.0.0",
|
|
23
|
-
"qs": "^6.
|
|
24
|
-
"tough-cookie": "^4.
|
|
23
|
+
"qs": "^6.11.0",
|
|
24
|
+
"tough-cookie": "^4.1.2"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@iobroker/testing": "^
|
|
28
|
-
"@types/chai": "^4.3.
|
|
27
|
+
"@iobroker/testing": "^4.1.0",
|
|
28
|
+
"@types/chai": "^4.3.3",
|
|
29
29
|
"@types/chai-as-promised": "^7.1.5",
|
|
30
|
-
"@types/mocha": "^9.1.
|
|
31
|
-
"@types/node": "^
|
|
30
|
+
"@types/mocha": "^9.1.1",
|
|
31
|
+
"@types/node": "^18.7.18",
|
|
32
32
|
"@types/proxyquire": "^1.3.28",
|
|
33
|
-
"@types/sinon": "^10.0.
|
|
33
|
+
"@types/sinon": "^10.0.13",
|
|
34
34
|
"@types/sinon-chai": "^3.2.8",
|
|
35
35
|
"chai": "^4.3.6",
|
|
36
36
|
"chai-as-promised": "^7.1.1",
|
|
37
|
-
"eslint": "^8.
|
|
38
|
-
"mocha": "^
|
|
37
|
+
"eslint": "^8.23.1",
|
|
38
|
+
"mocha": "^10.0.0",
|
|
39
39
|
"proxyquire": "^2.1.3",
|
|
40
|
-
"sinon": "^
|
|
40
|
+
"sinon": "^14.0.0",
|
|
41
41
|
"sinon-chai": "^3.7.0",
|
|
42
|
-
"typescript": "^4.
|
|
42
|
+
"typescript": "^4.8.3"
|
|
43
43
|
},
|
|
44
44
|
"main": "main.js",
|
|
45
45
|
"scripts": {
|