iobroker.toyota 0.3.0 → 0.4.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/io-package.json +8 -4
- package/main.js +85 -225
- package/package.json +11 -12
package/io-package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "toyota",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"news": {
|
|
6
|
-
"0.
|
|
7
|
-
"en": "
|
|
8
|
-
"de": "
|
|
6
|
+
"0.4.0": {
|
|
7
|
+
"en": "Align with MyToyota APK 2.25.2: fix climate command (start/stop), update electric status endpoint, update headers",
|
|
8
|
+
"de": "Angleichung an MyToyota APK 2.25.2: Klimasteuerung (start/stop) korrigiert, Electric-Status-Endpunkt und Header aktualisiert"
|
|
9
|
+
},
|
|
10
|
+
"0.2.7": {
|
|
11
|
+
"en": "Align with MyToyota APK 2.25.2: fix climate command (start/stop), update electric status endpoint, update headers",
|
|
12
|
+
"de": "Angleichung an MyToyota APK 2.25.2: Klimasteuerung (start/stop) korrigiert, Electric-Status-Endpunkt und Header aktualisiert"
|
|
9
13
|
},
|
|
10
14
|
"0.2.6": {
|
|
11
15
|
"en": "Skip endpoints that are not available",
|
package/main.js
CHANGED
|
@@ -47,8 +47,8 @@ class Toyota extends utils.Adapter {
|
|
|
47
47
|
this.reLoginTimeout = null;
|
|
48
48
|
this.refreshTokenTimeout = null;
|
|
49
49
|
this.brand = 'T';
|
|
50
|
-
// Aligned with MyToyota APK 2.
|
|
51
|
-
this.CLIENT_VERSION = '2.
|
|
50
|
+
// Aligned with MyToyota APK 2.25.2
|
|
51
|
+
this.CLIENT_VERSION = '2.25.2';
|
|
52
52
|
this.API_VERSION = 'resource=2.1, protocol=1.0';
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -104,20 +104,7 @@ class Toyota extends utils.Adapter {
|
|
|
104
104
|
maxBodyLength: Infinity,
|
|
105
105
|
url: 'https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp',
|
|
106
106
|
headers: {
|
|
107
|
-
'
|
|
108
|
-
'x-brand': this.brand,
|
|
109
|
-
accept: 'application/json',
|
|
110
|
-
'x-channel': 'ONEAPP',
|
|
111
|
-
brand: this.brand,
|
|
112
|
-
'x-region': 'EU',
|
|
113
|
-
'x-appbrand': this.brand,
|
|
114
|
-
'x-correlationid': 'B10AD742-22D0-4211-8B25-B213BE9A8A00',
|
|
115
|
-
'x-osversion': '16.7.2',
|
|
116
|
-
'accept-language': 'de-DE,de;q=0.9',
|
|
117
|
-
region: 'EU',
|
|
118
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
119
|
-
'accept-api-version': this.API_VERSION,
|
|
120
|
-
'x-appversion': this.CLIENT_VERSION,
|
|
107
|
+
...this.buildLoginHeaders('B10AD742-22D0-4211-8B25-B213BE9A8A00'),
|
|
121
108
|
Cookie: 'route=e8e8b55de08efd3c4b34265c0069d319',
|
|
122
109
|
},
|
|
123
110
|
})
|
|
@@ -138,21 +125,8 @@ class Toyota extends utils.Adapter {
|
|
|
138
125
|
maxBodyLength: Infinity,
|
|
139
126
|
url: 'https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp',
|
|
140
127
|
headers: {
|
|
141
|
-
'
|
|
142
|
-
'x-osname': 'iOS',
|
|
143
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
144
|
-
'x-region': 'EU',
|
|
145
|
-
region: 'EU',
|
|
146
|
-
brand: this.brand,
|
|
147
|
-
'x-channel': 'ONEAPP',
|
|
148
|
-
'x-osversion': '16.7.2',
|
|
149
|
-
'x-brand': this.brand,
|
|
150
|
-
'accept-language': 'de-DE,de;q=0.9',
|
|
151
|
-
'x-correlationid': 'BDD02A22-CD76-4877-90A9-196EDA5DC695',
|
|
152
|
-
'x-appversion': this.CLIENT_VERSION,
|
|
153
|
-
accept: 'application/json',
|
|
128
|
+
...this.buildLoginHeaders('BDD02A22-CD76-4877-90A9-196EDA5DC695'),
|
|
154
129
|
'content-type': 'application/json',
|
|
155
|
-
'accept-api-version': this.API_VERSION,
|
|
156
130
|
},
|
|
157
131
|
data: firstResponse,
|
|
158
132
|
})
|
|
@@ -179,21 +153,8 @@ class Toyota extends utils.Adapter {
|
|
|
179
153
|
maxBodyLength: Infinity,
|
|
180
154
|
url: 'https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp',
|
|
181
155
|
headers: {
|
|
182
|
-
'
|
|
183
|
-
'x-osname': 'iOS',
|
|
184
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
185
|
-
'x-region': 'EU',
|
|
186
|
-
region: 'EU',
|
|
187
|
-
brand: this.brand,
|
|
188
|
-
'x-channel': 'ONEAPP',
|
|
189
|
-
'x-osversion': '16.7.2',
|
|
190
|
-
'x-brand': this.brand,
|
|
191
|
-
'accept-language': 'de-DE,de;q=0.9',
|
|
192
|
-
'x-correlationid': 'BDD02A22-CD76-4877-90A9-196EDA5DC695',
|
|
193
|
-
'x-appversion': this.CLIENT_VERSION,
|
|
194
|
-
accept: 'application/json',
|
|
156
|
+
...this.buildLoginHeaders('BDD02A22-CD76-4877-90A9-196EDA5DC695'),
|
|
195
157
|
'content-type': 'application/json',
|
|
196
|
-
'accept-api-version': this.API_VERSION,
|
|
197
158
|
},
|
|
198
159
|
data: secondResponse,
|
|
199
160
|
})
|
|
@@ -221,21 +182,8 @@ class Toyota extends utils.Adapter {
|
|
|
221
182
|
maxBodyLength: Infinity,
|
|
222
183
|
url: 'https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp',
|
|
223
184
|
headers: {
|
|
224
|
-
'
|
|
225
|
-
'x-osname': 'iOS',
|
|
226
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
227
|
-
'x-region': 'EU',
|
|
228
|
-
region: 'EU',
|
|
229
|
-
brand: this.brand,
|
|
230
|
-
'x-channel': 'ONEAPP',
|
|
231
|
-
'x-osversion': '16.7.2',
|
|
232
|
-
'x-brand': this.brand,
|
|
233
|
-
'accept-language': 'de-DE,de;q=0.9',
|
|
234
|
-
'x-correlationid': 'BDD02A22-CD76-4877-90A9-196EDA5DC695',
|
|
235
|
-
'x-appversion': this.CLIENT_VERSION,
|
|
236
|
-
accept: 'application/json',
|
|
185
|
+
...this.buildLoginHeaders('BDD02A22-CD76-4877-90A9-196EDA5DC695'),
|
|
237
186
|
'content-type': 'application/json',
|
|
238
|
-
'accept-api-version': this.API_VERSION,
|
|
239
187
|
},
|
|
240
188
|
data: thirdResponse,
|
|
241
189
|
})
|
|
@@ -251,7 +199,7 @@ class Toyota extends utils.Adapter {
|
|
|
251
199
|
}
|
|
252
200
|
});
|
|
253
201
|
|
|
254
|
-
// PKCE S256: random 64-byte verifier, base64url(SHA-256(verifier)) as challenge
|
|
202
|
+
// PKCE S256: random 64-byte verifier, base64url(SHA-256(verifier)) as challenge
|
|
255
203
|
// Keep verifier local so concurrent login() calls do not overwrite each other.
|
|
256
204
|
const codeVerifier = crypto.randomBytes(64).toString('base64url');
|
|
257
205
|
const codeChallenge = crypto.createHash('sha256').update(codeVerifier).digest('base64url');
|
|
@@ -267,20 +215,8 @@ class Toyota extends utils.Adapter {
|
|
|
267
215
|
maxBodyLength: Infinity,
|
|
268
216
|
url: authorizeUrl,
|
|
269
217
|
headers: {
|
|
270
|
-
'
|
|
271
|
-
'x-brand': this.brand,
|
|
218
|
+
...this.buildLoginHeaders('0F34C246-11F3-4584-AB13-0EA5DA96CB41'),
|
|
272
219
|
accept: '*/*',
|
|
273
|
-
'x-channel': 'ONEAPP',
|
|
274
|
-
brand: this.brand,
|
|
275
|
-
'x-correlationid': '0F34C246-11F3-4584-AB13-0EA5DA96CB41',
|
|
276
|
-
'x-region': 'EU',
|
|
277
|
-
'x-appbrand': this.brand,
|
|
278
|
-
'x-osversion': '16.7.2',
|
|
279
|
-
'accept-language': 'de-DE,de;q=0.9',
|
|
280
|
-
region: 'EU',
|
|
281
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
282
|
-
'accept-api-version': this.API_VERSION,
|
|
283
|
-
'x-appversion': this.CLIENT_VERSION,
|
|
284
220
|
},
|
|
285
221
|
})
|
|
286
222
|
.then((res) => {
|
|
@@ -307,22 +243,10 @@ class Toyota extends utils.Adapter {
|
|
|
307
243
|
maxBodyLength: Infinity,
|
|
308
244
|
url: 'https://b2c-login.toyota-europe.com/oauth2/realms/root/realms/tme/access_token',
|
|
309
245
|
headers: {
|
|
310
|
-
'
|
|
311
|
-
'x-osname': 'iOS',
|
|
312
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
313
|
-
'x-region': 'EU',
|
|
314
|
-
region: 'EU',
|
|
315
|
-
brand: this.brand,
|
|
316
|
-
'x-channel': 'ONEAPP',
|
|
317
|
-
'x-osversion': '16.7.2',
|
|
318
|
-
'x-brand': this.brand,
|
|
319
|
-
authorization: 'Basic b25lYXBwOm9uZWFwcA==',
|
|
320
|
-
'accept-language': 'de-DE,de;q=0.9',
|
|
321
|
-
'x-correlationid': 'E422A08C-1A04-415E-BB08-2386EE06CF90',
|
|
322
|
-
'x-appversion': this.CLIENT_VERSION,
|
|
246
|
+
...this.buildLoginHeaders('E422A08C-1A04-415E-BB08-2386EE06CF90'),
|
|
323
247
|
accept: '*/*',
|
|
324
248
|
'content-type': 'application/x-www-form-urlencoded',
|
|
325
|
-
'
|
|
249
|
+
authorization: 'Basic b25lYXBwOm9uZWFwcA==',
|
|
326
250
|
},
|
|
327
251
|
data: {
|
|
328
252
|
grant_type: 'authorization_code',
|
|
@@ -358,22 +282,10 @@ class Toyota extends utils.Adapter {
|
|
|
358
282
|
maxBodyLength: Infinity,
|
|
359
283
|
url: 'https://b2c-login.toyota-europe.com/oauth2/realms/root/realms/tme/access_token',
|
|
360
284
|
headers: {
|
|
361
|
-
'
|
|
362
|
-
'x-osname': 'iOS',
|
|
363
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
364
|
-
'x-region': 'EU',
|
|
365
|
-
region: 'EU',
|
|
366
|
-
brand: this.brand,
|
|
367
|
-
'x-channel': 'ONEAPP',
|
|
368
|
-
'x-osversion': '16.7.2',
|
|
369
|
-
'x-brand': this.brand,
|
|
370
|
-
authorization: 'Basic b25lYXBwOm9uZWFwcA==',
|
|
371
|
-
'accept-language': 'de-DE,de;q=0.9',
|
|
372
|
-
'x-correlationid': 'E422A08C-1A04-415E-BB08-2386EE06CF90',
|
|
373
|
-
'x-appversion': this.CLIENT_VERSION,
|
|
285
|
+
...this.buildLoginHeaders('E422A08C-1A04-415E-BB08-2386EE06CF90'),
|
|
374
286
|
accept: '*/*',
|
|
375
287
|
'content-type': 'application/x-www-form-urlencoded',
|
|
376
|
-
'
|
|
288
|
+
authorization: 'Basic b25lYXBwOm9uZWFwcA==',
|
|
377
289
|
},
|
|
378
290
|
data: {
|
|
379
291
|
grant_type: 'refresh_token',
|
|
@@ -400,35 +312,72 @@ class Toyota extends utils.Adapter {
|
|
|
400
312
|
}
|
|
401
313
|
|
|
402
314
|
/**
|
|
403
|
-
*
|
|
404
|
-
*
|
|
315
|
+
* Headers for the ForgeRock authentication flow (login / token exchange).
|
|
316
|
+
* Mirrors the Android APK interceptors (b.smali + auth flow).
|
|
317
|
+
* @param {string} [correlationId] optional fixed correlation ID for login steps
|
|
405
318
|
*/
|
|
406
|
-
|
|
407
|
-
|
|
319
|
+
buildLoginHeaders(correlationId) {
|
|
320
|
+
return {
|
|
321
|
+
'x-osname': 'Android',
|
|
322
|
+
'x-osversion': '14',
|
|
323
|
+
'x-brand': this.brand,
|
|
408
324
|
'x-appbrand': this.brand,
|
|
409
|
-
'x-device-timezone': 'CEST',
|
|
410
|
-
'x-osname': 'iOS',
|
|
411
|
-
guid: this.uuid,
|
|
412
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
413
|
-
'x-guid': this.uuid,
|
|
414
|
-
region: 'EU',
|
|
415
325
|
brand: this.brand,
|
|
416
326
|
'x-channel': 'ONEAPP',
|
|
417
|
-
'x-
|
|
418
|
-
|
|
419
|
-
'x-
|
|
420
|
-
|
|
327
|
+
'x-region': 'EU',
|
|
328
|
+
region: 'EU',
|
|
329
|
+
'x-appversion': this.CLIENT_VERSION,
|
|
330
|
+
'x-correlationid': correlationId || uuidv4(),
|
|
421
331
|
'accept-language': 'de-DE,de;q=0.9',
|
|
422
|
-
accept: '
|
|
423
|
-
'
|
|
332
|
+
accept: 'application/json',
|
|
333
|
+
'user-agent': 'okhttp/4.10.0',
|
|
334
|
+
'accept-api-version': this.API_VERSION,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Returns true if an axios error response signals that the requested endpoint
|
|
340
|
+
* is not applicable for the current VIN (e.g. /electric/status on a non-EV car).
|
|
341
|
+
* Toyota answers with HTTP 4xx and responseCode ONE-GLOBAL-RC-10004.
|
|
342
|
+
* @param {{status: number, data?: any} | undefined} response
|
|
343
|
+
*/
|
|
344
|
+
isCapabilityNotPresent(response) {
|
|
345
|
+
if (!response || typeof response.status !== 'number' || response.status < 400 || response.status >= 500) {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
const messages = response.data && response.data.status && response.data.status.messages;
|
|
349
|
+
if (!Array.isArray(messages)) {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
return messages.some((m) => m && m.responseCode === 'ONE-GLOBAL-RC-10004');
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Build the standard set of headers used for all ctpa-oneapi calls.
|
|
357
|
+
* Aligned with pytoyoda controller._prepare_headers.
|
|
358
|
+
* @param {string} [vin] optional vin header for vehicle-scoped endpoints
|
|
359
|
+
*/
|
|
360
|
+
buildApiHeaders(vin) {
|
|
361
|
+
const headers = {
|
|
424
362
|
'x-api-key': 'tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF',
|
|
425
363
|
API_KEY: 'tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF',
|
|
426
|
-
|
|
364
|
+
'x-guid': this.uuid,
|
|
365
|
+
guid: this.uuid,
|
|
427
366
|
'x-client-ref': this.generate_hmac_sha256(this.CLIENT_VERSION, this.uuid),
|
|
428
367
|
'x-correlationid': uuidv4(),
|
|
429
368
|
'x-appversion': this.CLIENT_VERSION,
|
|
369
|
+
'x-channel': 'ONEAPP',
|
|
370
|
+
'x-brand': this.brand,
|
|
430
371
|
'x-region': 'EU',
|
|
372
|
+
'x-user-region': 'EU',
|
|
373
|
+
authorization: 'Bearer ' + this.session.access_token,
|
|
374
|
+
'user-agent': 'okhttp/4.10.0',
|
|
431
375
|
};
|
|
376
|
+
// x-appbrand and brand are only set for Lexus (L); Toyota (T) omits them
|
|
377
|
+
if (this.brand !== 'T') {
|
|
378
|
+
headers['x-appbrand'] = this.brand;
|
|
379
|
+
headers.brand = this.brand;
|
|
380
|
+
}
|
|
432
381
|
if (vin) {
|
|
433
382
|
headers.vin = vin;
|
|
434
383
|
}
|
|
@@ -449,7 +398,7 @@ class Toyota extends utils.Adapter {
|
|
|
449
398
|
},
|
|
450
399
|
{
|
|
451
400
|
name: 'electric',
|
|
452
|
-
url: 'https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/
|
|
401
|
+
url: 'https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v2/remote/electric/realtime-status',
|
|
453
402
|
},
|
|
454
403
|
];
|
|
455
404
|
for (const ep of refreshEndpoints) {
|
|
@@ -487,31 +436,7 @@ class Toyota extends utils.Adapter {
|
|
|
487
436
|
method: 'get',
|
|
488
437
|
maxBodyLength: Infinity,
|
|
489
438
|
url: 'https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v2/vehicle/guid',
|
|
490
|
-
headers:
|
|
491
|
-
'x-appbrand': this.brand,
|
|
492
|
-
'x-device-timezone': 'CEST',
|
|
493
|
-
'x-osname': 'iOS',
|
|
494
|
-
guid: this.uuid,
|
|
495
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
496
|
-
'x-guid': this.uuid,
|
|
497
|
-
region: 'EU',
|
|
498
|
-
brand: this.brand,
|
|
499
|
-
'x-channel': 'ONEAPP',
|
|
500
|
-
'x-osversion': '16.7.2',
|
|
501
|
-
'x-locale': 'de-DE',
|
|
502
|
-
'x-brand': this.brand,
|
|
503
|
-
authorization: 'Bearer ' + this.session.access_token,
|
|
504
|
-
'accept-language': 'de-DE,de;q=0.9',
|
|
505
|
-
accept: '*/*',
|
|
506
|
-
'x-user-region': 'DE',
|
|
507
|
-
'x-api-key': 'tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF',
|
|
508
|
-
API_KEY: 'tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF',
|
|
509
|
-
// x-client-ref: HMAC-SHA256 with the app version as key over the user GUID (APK 2.23.0)
|
|
510
|
-
'x-client-ref': this.generate_hmac_sha256(this.CLIENT_VERSION, this.uuid),
|
|
511
|
-
'x-correlationid': uuidv4(),
|
|
512
|
-
'x-appversion': this.CLIENT_VERSION,
|
|
513
|
-
'x-region': 'EU',
|
|
514
|
-
},
|
|
439
|
+
headers: this.buildApiHeaders(),
|
|
515
440
|
})
|
|
516
441
|
.then(async (res) => {
|
|
517
442
|
this.log.debug(JSON.stringify(res.data));
|
|
@@ -609,7 +534,7 @@ class Toyota extends utils.Adapter {
|
|
|
609
534
|
},
|
|
610
535
|
{
|
|
611
536
|
path: 'electric',
|
|
612
|
-
url: 'https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v1/
|
|
537
|
+
url: 'https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v1/vehicle/electric/status',
|
|
613
538
|
desc: 'Electric/PHEV status (battery, charging, range)',
|
|
614
539
|
},
|
|
615
540
|
{
|
|
@@ -624,43 +549,17 @@ class Toyota extends utils.Adapter {
|
|
|
624
549
|
},
|
|
625
550
|
];
|
|
626
551
|
|
|
627
|
-
const headers = {
|
|
628
|
-
'x-appbrand': this.brand,
|
|
629
|
-
'x-device-timezone': 'CEST',
|
|
630
|
-
'x-osname': 'iOS',
|
|
631
|
-
guid: this.uuid,
|
|
632
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
633
|
-
'x-guid': this.uuid,
|
|
634
|
-
region: 'EU',
|
|
635
|
-
brand: this.brand,
|
|
636
|
-
'x-channel': 'ONEAPP',
|
|
637
|
-
'x-osversion': '16.7.2',
|
|
638
|
-
'x-locale': 'de-DE',
|
|
639
|
-
'x-brand': this.brand,
|
|
640
|
-
authorization: 'Bearer ' + this.session.access_token,
|
|
641
|
-
'accept-language': 'de-DE,de;q=0.9',
|
|
642
|
-
accept: '*/*',
|
|
643
|
-
'x-user-region': 'DE',
|
|
644
|
-
'x-api-key': 'tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF',
|
|
645
|
-
API_KEY: 'tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF',
|
|
646
|
-
// Updated client-ref generation using new key
|
|
647
|
-
'x-client-ref': this.generate_hmac_sha256(this.CLIENT_VERSION, this.uuid),
|
|
648
|
-
'x-correlationid': uuidv4(),
|
|
649
|
-
'x-appversion': this.CLIENT_VERSION,
|
|
650
|
-
'x-region': 'EU',
|
|
651
|
-
};
|
|
652
552
|
for (const vin of this.deviceArray) {
|
|
653
553
|
for (const element of statusArray) {
|
|
654
554
|
if (this.blockedEndpoints[vin] && this.blockedEndpoints[vin].includes(element.path)) {
|
|
655
555
|
continue;
|
|
656
556
|
}
|
|
657
557
|
const url = element.url.replace('$vin', vin);
|
|
658
|
-
headers.vin = vin;
|
|
659
558
|
|
|
660
559
|
await this.requestClient({
|
|
661
560
|
method: 'get',
|
|
662
561
|
url: url,
|
|
663
|
-
headers:
|
|
562
|
+
headers: this.buildApiHeaders(vin),
|
|
664
563
|
})
|
|
665
564
|
.then((res) => {
|
|
666
565
|
this.log.debug(JSON.stringify(res.data));
|
|
@@ -697,6 +596,14 @@ class Toyota extends utils.Adapter {
|
|
|
697
596
|
this.blockedEndpoints[vin].push(element.path);
|
|
698
597
|
return;
|
|
699
598
|
}
|
|
599
|
+
// Endpoint not applicable for this VIN (e.g. /electric/status on a non-EV/PHEV car):
|
|
600
|
+
// Toyota answers HTTP 4xx with responseCode ONE-GLOBAL-RC-10004 every poll. Block it once.
|
|
601
|
+
if (this.isCapabilityNotPresent(error.response)) {
|
|
602
|
+
this.log.info(`${element.path} not available for ${vin}. Skip until restart`);
|
|
603
|
+
this.blockedEndpoints[vin] = this.blockedEndpoints[vin] || [];
|
|
604
|
+
this.blockedEndpoints[vin].push(element.path);
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
700
607
|
}
|
|
701
608
|
this.log.error(url);
|
|
702
609
|
this.log.error(error);
|
|
@@ -717,40 +624,14 @@ class Toyota extends utils.Adapter {
|
|
|
717
624
|
},
|
|
718
625
|
];
|
|
719
626
|
|
|
720
|
-
const headers = {
|
|
721
|
-
'x-appbrand': this.brand,
|
|
722
|
-
'x-device-timezone': 'CEST',
|
|
723
|
-
'x-osname': 'iOS',
|
|
724
|
-
guid: this.uuid,
|
|
725
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
726
|
-
'x-guid': this.uuid,
|
|
727
|
-
region: 'EU',
|
|
728
|
-
brand: this.brand,
|
|
729
|
-
'x-channel': 'ONEAPP',
|
|
730
|
-
'x-osversion': '16.7.2',
|
|
731
|
-
'x-locale': 'de-DE',
|
|
732
|
-
'x-brand': this.brand,
|
|
733
|
-
authorization: 'Bearer ' + this.session.access_token,
|
|
734
|
-
'accept-language': 'de-DE,de;q=0.9',
|
|
735
|
-
accept: '*/*',
|
|
736
|
-
'x-user-region': 'DE',
|
|
737
|
-
'x-api-key': 'tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF',
|
|
738
|
-
API_KEY: 'tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF',
|
|
739
|
-
// Updated client-ref generation using new key
|
|
740
|
-
'x-client-ref': this.generate_hmac_sha256(this.CLIENT_VERSION, this.uuid),
|
|
741
|
-
'x-correlationid': uuidv4(),
|
|
742
|
-
'x-appversion': this.CLIENT_VERSION,
|
|
743
|
-
'x-region': 'EU',
|
|
744
|
-
};
|
|
745
627
|
for (const vin of this.deviceArray) {
|
|
746
628
|
statusArray.forEach(async (element) => {
|
|
747
629
|
const url = element.url.replace('$vin', vin);
|
|
748
|
-
headers.vin = vin;
|
|
749
630
|
|
|
750
631
|
await this.requestClient({
|
|
751
632
|
method: 'get',
|
|
752
633
|
url: url,
|
|
753
|
-
headers:
|
|
634
|
+
headers: this.buildApiHeaders(vin),
|
|
754
635
|
})
|
|
755
636
|
.then((res) => {
|
|
756
637
|
this.log.debug(JSON.stringify(res.data));
|
|
@@ -833,7 +714,8 @@ class Toyota extends utils.Adapter {
|
|
|
833
714
|
let url = 'https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v1/global/remote/command';
|
|
834
715
|
if (path === 'climate-control') {
|
|
835
716
|
url = 'https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v2/remote/climate-control';
|
|
836
|
-
|
|
717
|
+
// V2 climate-control expects command "start"/"stop" (not the old v1 engine-start/engine-stop)
|
|
718
|
+
data.command = state.val ? 'start' : 'stop';
|
|
837
719
|
}
|
|
838
720
|
if (path === 'door') {
|
|
839
721
|
data.command = state.val ? 'door-lock' : 'door-unlock';
|
|
@@ -844,36 +726,14 @@ class Toyota extends utils.Adapter {
|
|
|
844
726
|
await this.requestClient({
|
|
845
727
|
method: 'post',
|
|
846
728
|
url: url,
|
|
847
|
-
headers:
|
|
848
|
-
'x-appbrand': this.brand,
|
|
849
|
-
'x-device-timezone': 'CEST',
|
|
850
|
-
'x-osname': 'iOS',
|
|
851
|
-
guid: this.uuid,
|
|
852
|
-
'user-agent': 'Toyota/134 CFNetwork/1410.0.3 Darwin/22.6.0',
|
|
853
|
-
'x-guid': this.uuid,
|
|
854
|
-
region: 'EU',
|
|
855
|
-
brand: this.brand,
|
|
856
|
-
'x-channel': 'ONEAPP',
|
|
857
|
-
vin: deviceId,
|
|
858
|
-
'x-osversion': '16.7.2',
|
|
859
|
-
'x-locale': 'de-DE',
|
|
860
|
-
'x-brand': this.brand,
|
|
861
|
-
authorization: 'Bearer ' + this.session.access_token,
|
|
862
|
-
'accept-language': 'de-DE,de;q=0.9',
|
|
863
|
-
accept: '*/*',
|
|
864
|
-
'x-user-region': 'DE',
|
|
865
|
-
'x-api-key': 'tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF',
|
|
866
|
-
API_KEY: 'tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF',
|
|
867
|
-
// Updated client-ref generation using new key
|
|
868
|
-
'x-client-ref': this.generate_hmac_sha256(this.CLIENT_VERSION, this.uuid),
|
|
869
|
-
'x-correlationid': uuidv4(),
|
|
870
|
-
'x-appversion': this.CLIENT_VERSION,
|
|
871
|
-
'x-region': 'EU',
|
|
872
|
-
},
|
|
729
|
+
headers: this.buildApiHeaders(deviceId),
|
|
873
730
|
data: data,
|
|
874
731
|
})
|
|
875
732
|
.then((res) => {
|
|
876
733
|
this.log.debug(JSON.stringify(res.data));
|
|
734
|
+
if (path === 'climate-control' && res.data?.payload?.returnCode !== '000000') {
|
|
735
|
+
this.log.error('climate-control command rejected: ' + JSON.stringify(res.data));
|
|
736
|
+
}
|
|
877
737
|
return res.data;
|
|
878
738
|
})
|
|
879
739
|
.catch((error) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.toyota",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Adapter for myT Toyota/Lexus App",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "TA2k",
|
|
@@ -23,21 +23,21 @@
|
|
|
23
23
|
"url": "https://github.com/TA2k/ioBroker.toyota"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@iobroker/adapter-core": "^3.4.
|
|
27
|
-
"axios": "^1.
|
|
26
|
+
"@iobroker/adapter-core": "^3.4.3",
|
|
27
|
+
"axios": "^1.20.0",
|
|
28
28
|
"http-cookie-agent": "^8.0.0",
|
|
29
|
-
"json2iob": "^2.6.
|
|
29
|
+
"json2iob": "^2.6.28",
|
|
30
30
|
"jsonwebtoken": "^9.0.3",
|
|
31
|
-
"qs": "^6.
|
|
32
|
-
"tough-cookie": "^6.0.
|
|
33
|
-
"uuid": "^14.0.
|
|
31
|
+
"qs": "^6.16.0",
|
|
32
|
+
"tough-cookie": "^6.0.2",
|
|
33
|
+
"uuid": "^14.0.2"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@eslint/js": "^10.0.1",
|
|
37
|
-
"@iobroker/testing": "^5.
|
|
38
|
-
"@types/node": "^26.
|
|
39
|
-
"eslint": "^10.
|
|
40
|
-
"globals": "^17.
|
|
37
|
+
"@iobroker/testing": "^5.3.0",
|
|
38
|
+
"@types/node": "^26.6.4",
|
|
39
|
+
"eslint": "^10.12.0",
|
|
40
|
+
"globals": "^17.13.0",
|
|
41
41
|
"typescript": "~6.0.3"
|
|
42
42
|
},
|
|
43
43
|
"main": "main.js",
|
|
@@ -66,5 +66,4 @@
|
|
|
66
66
|
"url": "https://github.com/TA2k/ioBroker.toyota/issues"
|
|
67
67
|
},
|
|
68
68
|
"readmeFilename": "README.md"
|
|
69
|
-
|
|
70
69
|
}
|