iobroker.renault 0.0.21 → 0.0.22
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 +4 -1
- package/main.js +195 -190
- package/package.json +15 -15
package/io-package.json
CHANGED
package/main.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
/*
|
|
4
4
|
* Created with @iobroker/create-adapter v2.0.1
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
// The adapter-core module gives you access to the core ioBroker functions
|
|
8
8
|
// you need to create an adapter
|
|
9
|
-
const utils = require(
|
|
10
|
-
const axios = require(
|
|
11
|
-
const qs = require(
|
|
12
|
-
const Json2iob = require(
|
|
9
|
+
const utils = require('@iobroker/adapter-core');
|
|
10
|
+
const axios = require('axios').default;
|
|
11
|
+
const qs = require('qs');
|
|
12
|
+
const Json2iob = require('json2iob');
|
|
13
13
|
|
|
14
14
|
class Renault extends utils.Adapter {
|
|
15
15
|
/**
|
|
@@ -18,11 +18,11 @@ class Renault extends utils.Adapter {
|
|
|
18
18
|
constructor(options) {
|
|
19
19
|
super({
|
|
20
20
|
...options,
|
|
21
|
-
name:
|
|
21
|
+
name: 'renault',
|
|
22
22
|
});
|
|
23
|
-
this.on(
|
|
24
|
-
this.on(
|
|
25
|
-
this.on(
|
|
23
|
+
this.on('ready', this.onReady.bind(this));
|
|
24
|
+
this.on('stateChange', this.onStateChange.bind(this));
|
|
25
|
+
this.on('unload', this.onUnload.bind(this));
|
|
26
26
|
this.deviceArray = [];
|
|
27
27
|
this.json2iob = new Json2iob(this);
|
|
28
28
|
this.ignoreState = {};
|
|
@@ -35,23 +35,23 @@ class Renault extends utils.Adapter {
|
|
|
35
35
|
*/
|
|
36
36
|
async onReady() {
|
|
37
37
|
// Reset the connection indicator during startup
|
|
38
|
-
this.setState(
|
|
38
|
+
this.setState('info.connection', false, true);
|
|
39
39
|
if (this.config.interval < 0.5) {
|
|
40
|
-
this.log.info(
|
|
40
|
+
this.log.info('Set interval to minimum 0.5');
|
|
41
41
|
this.config.interval = 0.5;
|
|
42
42
|
}
|
|
43
43
|
this.updateInterval = null;
|
|
44
44
|
this.reLoginTimeout = null;
|
|
45
45
|
this.refreshTokenTimeout = null;
|
|
46
|
-
this.country = this.config.country ||
|
|
46
|
+
this.country = this.config.country || 'de';
|
|
47
47
|
this.session = {};
|
|
48
48
|
//DE API Key
|
|
49
|
-
this.apiKey =
|
|
50
|
-
this.apiKeyUpdate =
|
|
49
|
+
this.apiKey = '3_7PLksOyBRkHv126x5WhHb-5pqC1qFR8pQjxSeLB6nhAnPERTUlwnYoznHSxwX668';
|
|
50
|
+
this.apiKeyUpdate = 'YjkKtHmGfaceeuExUDKGxrLZGGvtVS0J';
|
|
51
51
|
try {
|
|
52
52
|
await this.requestClient({
|
|
53
|
-
method:
|
|
54
|
-
url:
|
|
53
|
+
method: 'get',
|
|
54
|
+
url: 'https://raw.githubusercontent.com/hacf-fr/renault-api/main/src/renault_api/const.py',
|
|
55
55
|
})
|
|
56
56
|
|
|
57
57
|
.then((res) => {
|
|
@@ -71,7 +71,7 @@ class Renault extends utils.Adapter {
|
|
|
71
71
|
this.apiKeyUpdate = this.config.apiKeyUpdate;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
this.subscribeStates(
|
|
74
|
+
this.subscribeStates('*');
|
|
75
75
|
|
|
76
76
|
await this.login();
|
|
77
77
|
|
|
@@ -88,25 +88,29 @@ class Renault extends utils.Adapter {
|
|
|
88
88
|
}
|
|
89
89
|
async login() {
|
|
90
90
|
this.session_data = await this.requestClient({
|
|
91
|
-
method:
|
|
92
|
-
url:
|
|
91
|
+
method: 'post',
|
|
92
|
+
url: 'https://accounts.eu1.gigya.com/accounts.login',
|
|
93
93
|
headers: {
|
|
94
|
-
|
|
95
|
-
Accept:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
'User-Agent': 'MYRenault/39 CFNetwork/1312 Darwin/21.0.0',
|
|
95
|
+
Accept: '*/*',
|
|
96
|
+
'Accept-Language': 'de-de',
|
|
97
|
+
'Cache-Control': 'no-cache',
|
|
98
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
99
99
|
},
|
|
100
100
|
data: qs.stringify({
|
|
101
101
|
apikey: this.apiKey,
|
|
102
|
-
format:
|
|
103
|
-
httpStatusCodes:
|
|
102
|
+
format: 'json',
|
|
103
|
+
httpStatusCodes: 'false',
|
|
104
104
|
loginID: this.config.username,
|
|
105
105
|
password: this.config.password,
|
|
106
106
|
}),
|
|
107
107
|
})
|
|
108
108
|
.then((res) => {
|
|
109
109
|
this.log.debug(JSON.stringify(res.data));
|
|
110
|
+
if (res.data.errorMessage) {
|
|
111
|
+
this.log.error(JSON.stringify(res.data));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
110
114
|
return res.data.sessionInfo;
|
|
111
115
|
})
|
|
112
116
|
.catch((error) => {
|
|
@@ -116,32 +120,32 @@ class Renault extends utils.Adapter {
|
|
|
116
120
|
}
|
|
117
121
|
});
|
|
118
122
|
if (!this.session_data) {
|
|
119
|
-
this.log.error(
|
|
123
|
+
this.log.error('No session found for this account');
|
|
120
124
|
return;
|
|
121
125
|
}
|
|
122
126
|
await this.requestClient({
|
|
123
|
-
method:
|
|
124
|
-
url:
|
|
127
|
+
method: 'post',
|
|
128
|
+
url: 'https://accounts.eu1.gigya.com/accounts.getJWT',
|
|
125
129
|
headers: {
|
|
126
|
-
|
|
127
|
-
Accept:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
'User-Agent': 'MYRenault/39 CFNetwork/1312 Darwin/21.0.0',
|
|
131
|
+
Accept: '*/*',
|
|
132
|
+
'Accept-Language': 'de-de',
|
|
133
|
+
'Cache-Control': 'no-cache',
|
|
134
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
131
135
|
},
|
|
132
136
|
data: qs.stringify({
|
|
133
|
-
format:
|
|
137
|
+
format: 'json',
|
|
134
138
|
login_token: this.session_data.cookieValue,
|
|
135
|
-
sdk:
|
|
136
|
-
fields:
|
|
139
|
+
sdk: 'js_latest',
|
|
140
|
+
fields: 'data.personId,data.gigyaDataCenter',
|
|
137
141
|
apikey: this.apiKey,
|
|
138
|
-
expiration:
|
|
142
|
+
expiration: '3600',
|
|
139
143
|
}),
|
|
140
144
|
})
|
|
141
145
|
.then((res) => {
|
|
142
146
|
this.log.debug(JSON.stringify(res.data));
|
|
143
147
|
this.session = res.data;
|
|
144
|
-
this.setState(
|
|
148
|
+
this.setState('info.connection', true, true);
|
|
145
149
|
})
|
|
146
150
|
.catch((error) => {
|
|
147
151
|
this.log.error(error);
|
|
@@ -150,59 +154,59 @@ class Renault extends utils.Adapter {
|
|
|
150
154
|
}
|
|
151
155
|
});
|
|
152
156
|
await this.requestClient({
|
|
153
|
-
method:
|
|
154
|
-
url:
|
|
157
|
+
method: 'post',
|
|
158
|
+
url: 'https://apis.renault.com/myr/api/v1/connection?&country=DE&product=MYRENAULT&locale=de-DE&displayAccounts=MYRENAULT',
|
|
155
159
|
headers: {
|
|
156
|
-
|
|
157
|
-
Accept:
|
|
158
|
-
|
|
160
|
+
'Content-Type': 'application/json',
|
|
161
|
+
Accept: '*/*',
|
|
162
|
+
'User-Agent': 'MYRenault/39 CFNetwork/1312 Darwin/21.0.0',
|
|
159
163
|
apiKey: this.apiKeyUpdate,
|
|
160
|
-
|
|
161
|
-
|
|
164
|
+
'Accept-Language': 'de-de',
|
|
165
|
+
'x-gigya-id_token': this.session.id_token,
|
|
162
166
|
},
|
|
163
167
|
})
|
|
164
168
|
.then((res) => {
|
|
165
169
|
this.log.debug(JSON.stringify(res.data));
|
|
166
170
|
|
|
167
171
|
const filteredAccounts = res.data.currentUser.accounts.filter(function (el) {
|
|
168
|
-
return (el.accountType ===
|
|
172
|
+
return (el.accountType === 'MYRENAULT' || el.accountType === 'MYDACIA') && el.accountStatus === 'ACTIVE';
|
|
169
173
|
});
|
|
170
174
|
if (filteredAccounts.length === 0) {
|
|
171
|
-
this.log.error(
|
|
172
|
-
this.log.error(
|
|
173
|
-
this.log.error(
|
|
175
|
+
this.log.error('No Account found');
|
|
176
|
+
this.log.error('All accounts: ' + res.data.currentUser.accounts);
|
|
177
|
+
this.log.error('Filtered accounts: ' + filteredAccounts);
|
|
174
178
|
return;
|
|
175
179
|
}
|
|
176
180
|
|
|
177
181
|
this.account = filteredAccounts[0];
|
|
178
182
|
})
|
|
179
183
|
.catch((error) => {
|
|
180
|
-
this.log.error(
|
|
184
|
+
this.log.error('Error while getting account');
|
|
181
185
|
this.log.error(error);
|
|
182
186
|
if (error.response) {
|
|
183
187
|
this.log.error(JSON.stringify(error.response.data));
|
|
184
|
-
if (error.response.data && JSON.stringify(error.response.data).indexOf(
|
|
185
|
-
this.log.error(
|
|
188
|
+
if (error.response.data && JSON.stringify(error.response.data).indexOf('apikey') !== -1) {
|
|
189
|
+
this.log.error('Wrong API Key. Please update API Key in adapter settings');
|
|
186
190
|
}
|
|
187
191
|
}
|
|
188
192
|
});
|
|
189
193
|
}
|
|
190
194
|
async getDeviceList() {
|
|
191
195
|
await this.requestClient({
|
|
192
|
-
method:
|
|
196
|
+
method: 'get',
|
|
193
197
|
url:
|
|
194
|
-
|
|
198
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
195
199
|
this.account.accountId +
|
|
196
|
-
|
|
200
|
+
'/vehicles?country=' +
|
|
197
201
|
this.country +
|
|
198
|
-
|
|
202
|
+
'&oms=false',
|
|
199
203
|
headers: {
|
|
200
204
|
apikey: this.apiKeyUpdate,
|
|
201
|
-
|
|
202
|
-
accept:
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
205
|
+
'content-type': 'application/json',
|
|
206
|
+
accept: '*/*',
|
|
207
|
+
'user-agent': 'MYRenault/39 CFNetwork/1312 Darwin/21.0.0',
|
|
208
|
+
'accept-language': 'de-de',
|
|
209
|
+
'x-gigya-id_token': this.session.id_token,
|
|
206
210
|
},
|
|
207
211
|
})
|
|
208
212
|
.then(async (res) => {
|
|
@@ -217,53 +221,54 @@ class Renault extends utils.Adapter {
|
|
|
217
221
|
|
|
218
222
|
this.ignoreState[device.vin] = [];
|
|
219
223
|
await this.setObjectNotExistsAsync(device.vin, {
|
|
220
|
-
type:
|
|
224
|
+
type: 'device',
|
|
221
225
|
common: {
|
|
222
226
|
name: name,
|
|
223
227
|
},
|
|
224
228
|
native: {},
|
|
225
229
|
});
|
|
226
|
-
await this.setObjectNotExistsAsync(device.vin +
|
|
227
|
-
type:
|
|
230
|
+
await this.setObjectNotExistsAsync(device.vin + '.remote', {
|
|
231
|
+
type: 'channel',
|
|
228
232
|
common: {
|
|
229
|
-
name:
|
|
233
|
+
name: 'Remote Controls',
|
|
230
234
|
},
|
|
231
235
|
native: {},
|
|
232
236
|
});
|
|
233
|
-
await this.setObjectNotExistsAsync(device.vin +
|
|
234
|
-
type:
|
|
237
|
+
await this.setObjectNotExistsAsync(device.vin + '.general', {
|
|
238
|
+
type: 'channel',
|
|
235
239
|
common: {
|
|
236
|
-
name:
|
|
240
|
+
name: 'WIRD NICHT AKTUALISIERT',
|
|
237
241
|
},
|
|
238
242
|
native: {},
|
|
239
243
|
});
|
|
240
244
|
|
|
241
245
|
const remoteArray = [
|
|
242
|
-
{ command:
|
|
243
|
-
{ command:
|
|
244
|
-
{ command:
|
|
245
|
-
{ command:
|
|
246
|
-
{ command:
|
|
247
|
-
{ command:
|
|
246
|
+
{ command: 'actions/hvac-start', name: 'True = Start, False = Stop' },
|
|
247
|
+
{ command: 'hvac-temperature', name: 'HVAC Temperature', type: 'number', role: 'value' },
|
|
248
|
+
{ command: 'actions/charging-start', name: 'True = Start, False = Stop' },
|
|
249
|
+
{ command: 'charge/pause-resume', name: 'True = Start, False = Stop' },
|
|
250
|
+
{ command: 'charge/start', name: 'True = Start, False = Stop' },
|
|
251
|
+
{ command: 'refresh', name: 'True = Refresh Data' },
|
|
248
252
|
];
|
|
249
253
|
remoteArray.forEach((remote) => {
|
|
250
|
-
this.setObjectNotExists(device.vin +
|
|
251
|
-
type:
|
|
254
|
+
this.setObjectNotExists(device.vin + '.remote.' + remote.command, {
|
|
255
|
+
type: 'state',
|
|
252
256
|
common: {
|
|
253
|
-
name: remote.name ||
|
|
254
|
-
type: remote.type ||
|
|
255
|
-
role: remote.role ||
|
|
257
|
+
name: remote.name || '',
|
|
258
|
+
type: remote.type || 'boolean',
|
|
259
|
+
role: remote.role || 'button',
|
|
256
260
|
write: true,
|
|
257
261
|
read: true,
|
|
258
262
|
},
|
|
259
263
|
native: {},
|
|
260
264
|
});
|
|
261
265
|
});
|
|
262
|
-
|
|
266
|
+
delete device.mileage;
|
|
267
|
+
this.json2iob.parse(device.vin + '.general', device);
|
|
263
268
|
}
|
|
264
269
|
})
|
|
265
270
|
.catch((error) => {
|
|
266
|
-
this.log.error(
|
|
271
|
+
this.log.error('Error while getting vehicle list');
|
|
267
272
|
this.log.error(error);
|
|
268
273
|
error.response && this.log.error(JSON.stringify(error.response.data));
|
|
269
274
|
});
|
|
@@ -271,152 +276,152 @@ class Renault extends utils.Adapter {
|
|
|
271
276
|
|
|
272
277
|
async updateDevices() {
|
|
273
278
|
if (!this.account.accountId) {
|
|
274
|
-
this.log.error(
|
|
279
|
+
this.log.error('No accountId found');
|
|
275
280
|
return;
|
|
276
281
|
}
|
|
277
|
-
const curDate = new Date().toISOString().split(
|
|
282
|
+
const curDate = new Date().toISOString().split('T')[0];
|
|
278
283
|
|
|
279
284
|
const statusArray = [
|
|
280
285
|
{
|
|
281
|
-
path:
|
|
286
|
+
path: 'battery-status',
|
|
282
287
|
url:
|
|
283
|
-
|
|
288
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
284
289
|
this.account.accountId +
|
|
285
|
-
|
|
290
|
+
'/kamereon/kca/car-adapter/v2/cars/$vin/battery-status?country=' +
|
|
286
291
|
this.country,
|
|
287
|
-
desc:
|
|
292
|
+
desc: 'Battery status of the car',
|
|
288
293
|
},
|
|
289
294
|
{
|
|
290
|
-
path:
|
|
295
|
+
path: 'battery-inhibition-status',
|
|
291
296
|
url:
|
|
292
|
-
|
|
297
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
293
298
|
this.account.accountId +
|
|
294
|
-
|
|
299
|
+
'/kamereon/kca/car-adapter/v1/cars/$vin/battery-inhibition-status?country=' +
|
|
295
300
|
this.country,
|
|
296
|
-
desc:
|
|
301
|
+
desc: 'Battery inhibition status of the car',
|
|
297
302
|
},
|
|
298
303
|
{
|
|
299
|
-
path:
|
|
304
|
+
path: 'cockpit',
|
|
300
305
|
url:
|
|
301
|
-
|
|
306
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
302
307
|
this.account.accountId +
|
|
303
|
-
|
|
308
|
+
'/kamereon/kca/car-adapter/v1/cars/$vin/cockpit?country=' +
|
|
304
309
|
this.country,
|
|
305
|
-
desc:
|
|
310
|
+
desc: 'Status of the car',
|
|
306
311
|
},
|
|
307
312
|
{
|
|
308
|
-
path:
|
|
313
|
+
path: 'cockpitv2',
|
|
309
314
|
url:
|
|
310
|
-
|
|
315
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
311
316
|
this.account.accountId +
|
|
312
|
-
|
|
317
|
+
'/kamereon/kca/car-adapter/v2/cars/$vin/cockpit?country=' +
|
|
313
318
|
this.country,
|
|
314
|
-
desc:
|
|
319
|
+
desc: 'Statusv2 of the car',
|
|
315
320
|
},
|
|
316
321
|
{
|
|
317
|
-
path:
|
|
322
|
+
path: 'charge-mode',
|
|
318
323
|
url:
|
|
319
|
-
|
|
324
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
320
325
|
this.account.accountId +
|
|
321
|
-
|
|
326
|
+
'/kamereon/kca/car-adapter/v1/cars/$vin/charge-mode?country=' +
|
|
322
327
|
this.country,
|
|
323
|
-
desc:
|
|
328
|
+
desc: 'Charge mode of the car',
|
|
324
329
|
},
|
|
325
330
|
{
|
|
326
|
-
path:
|
|
331
|
+
path: 'hvac-status',
|
|
327
332
|
url:
|
|
328
|
-
|
|
333
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
329
334
|
this.account.accountId +
|
|
330
|
-
|
|
335
|
+
'/kamereon/kca/car-adapter/v1/cars/$vin/hvac-status?country=' +
|
|
331
336
|
this.country,
|
|
332
|
-
desc:
|
|
337
|
+
desc: 'HVAC status of the car',
|
|
333
338
|
},
|
|
334
339
|
{
|
|
335
|
-
path:
|
|
340
|
+
path: 'hvac-settings',
|
|
336
341
|
url:
|
|
337
|
-
|
|
342
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
338
343
|
this.account.accountId +
|
|
339
|
-
|
|
344
|
+
'/kamereon/kca/car-adapter/v1/cars/$vin/hvac-settings?country=' +
|
|
340
345
|
this.country,
|
|
341
|
-
desc:
|
|
346
|
+
desc: 'HVAC settings of the car',
|
|
342
347
|
},
|
|
343
348
|
{
|
|
344
|
-
path:
|
|
349
|
+
path: 'charging-settings',
|
|
345
350
|
url:
|
|
346
|
-
|
|
351
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
347
352
|
this.account.accountId +
|
|
348
|
-
|
|
353
|
+
'/kamereon/kca/car-adapter/v1/cars/$vin/charging-settings?country=' +
|
|
349
354
|
this.country,
|
|
350
|
-
desc:
|
|
355
|
+
desc: 'Charging settings of the car',
|
|
351
356
|
},
|
|
352
357
|
{
|
|
353
|
-
path:
|
|
358
|
+
path: 'charge-history',
|
|
354
359
|
url:
|
|
355
|
-
|
|
360
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
356
361
|
this.account.accountId +
|
|
357
|
-
|
|
362
|
+
'/kamereon/kca/car-adapter/v1/cars/$vin/charge-history?type=day&start=1970-01-01&end=' +
|
|
358
363
|
curDate +
|
|
359
|
-
|
|
364
|
+
'&country=' +
|
|
360
365
|
this.country,
|
|
361
|
-
desc:
|
|
366
|
+
desc: 'Charging history of the car',
|
|
362
367
|
},
|
|
363
368
|
{
|
|
364
|
-
path:
|
|
369
|
+
path: 'charges',
|
|
365
370
|
url:
|
|
366
|
-
|
|
371
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
367
372
|
this.account.accountId +
|
|
368
|
-
|
|
373
|
+
'/kamereon/kca/car-adapter/v1/cars/$vin/charges?start=1970-01-01&end=' +
|
|
369
374
|
curDate +
|
|
370
|
-
|
|
375
|
+
'&country=' +
|
|
371
376
|
this.country,
|
|
372
|
-
desc:
|
|
377
|
+
desc: 'Charges of the car',
|
|
373
378
|
},
|
|
374
379
|
{
|
|
375
|
-
path:
|
|
380
|
+
path: 'lock-status',
|
|
376
381
|
url:
|
|
377
|
-
|
|
382
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
378
383
|
this.account.accountId +
|
|
379
|
-
|
|
384
|
+
'/kamereon/kca/car-adapter/v1/cars/$vin/lock-status?country=' +
|
|
380
385
|
this.country,
|
|
381
|
-
desc:
|
|
386
|
+
desc: 'Lock status of the car',
|
|
382
387
|
},
|
|
383
388
|
{
|
|
384
|
-
path:
|
|
389
|
+
path: 'res-state',
|
|
385
390
|
url:
|
|
386
|
-
|
|
391
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
387
392
|
this.account.accountId +
|
|
388
|
-
|
|
393
|
+
'/kamereon/kca/car-adapter/v1/cars/$vin/res-state?country=' +
|
|
389
394
|
this.country,
|
|
390
|
-
desc:
|
|
395
|
+
desc: 'Res status of the car',
|
|
391
396
|
},
|
|
392
397
|
{
|
|
393
|
-
path:
|
|
398
|
+
path: 'location',
|
|
394
399
|
url:
|
|
395
|
-
|
|
400
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
396
401
|
this.account.accountId +
|
|
397
|
-
|
|
402
|
+
'/kamereon/kca/car-adapter/v1/cars/$vin/location?country=' +
|
|
398
403
|
this.country,
|
|
399
|
-
desc:
|
|
404
|
+
desc: 'Location of the car',
|
|
400
405
|
},
|
|
401
406
|
];
|
|
402
407
|
|
|
403
408
|
const headers = {
|
|
404
409
|
apikey: this.apiKeyUpdate,
|
|
405
|
-
|
|
406
|
-
accept:
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
+
'content-type': 'application/json',
|
|
411
|
+
accept: '*/*',
|
|
412
|
+
'user-agent': 'MYRenault/39 CFNetwork/1312 Darwin/21.0.0',
|
|
413
|
+
'accept-language': 'de-de',
|
|
414
|
+
'x-gigya-id_token': this.session.id_token,
|
|
410
415
|
};
|
|
411
416
|
for (const vin of this.deviceArray) {
|
|
412
417
|
for (const element of statusArray) {
|
|
413
418
|
if (this.ignoreState[vin] && this.ignoreState[vin].includes(element.path)) {
|
|
414
419
|
continue;
|
|
415
420
|
}
|
|
416
|
-
const url = element.url.replace(
|
|
421
|
+
const url = element.url.replace('$vin', vin);
|
|
417
422
|
|
|
418
423
|
await this.requestClient({
|
|
419
|
-
method:
|
|
424
|
+
method: 'get',
|
|
420
425
|
url: url,
|
|
421
426
|
headers: headers,
|
|
422
427
|
})
|
|
@@ -433,7 +438,7 @@ class Renault extends utils.Adapter {
|
|
|
433
438
|
const forceIndex = null;
|
|
434
439
|
const preferedArrayName = null;
|
|
435
440
|
|
|
436
|
-
this.json2iob.parse(vin +
|
|
441
|
+
this.json2iob.parse(vin + '.' + element.path, data, {
|
|
437
442
|
forceIndex: forceIndex,
|
|
438
443
|
preferedArrayName: preferedArrayName,
|
|
439
444
|
channelName: element.desc,
|
|
@@ -443,7 +448,7 @@ class Renault extends utils.Adapter {
|
|
|
443
448
|
if (error.response) {
|
|
444
449
|
if (error.response.status === 401) {
|
|
445
450
|
error.response && this.log.debug(JSON.stringify(error.response.data));
|
|
446
|
-
this.log.info(element.path +
|
|
451
|
+
this.log.info(element.path + ' receive 401 error. Refresh Token in 60 seconds');
|
|
447
452
|
this.refreshTokenTimeout && clearTimeout(this.refreshTokenTimeout);
|
|
448
453
|
this.refreshTokenTimeout = setTimeout(() => {
|
|
449
454
|
this.refreshToken();
|
|
@@ -464,7 +469,7 @@ class Renault extends utils.Adapter {
|
|
|
464
469
|
this.ignoreState[vin] = [];
|
|
465
470
|
}
|
|
466
471
|
this.ignoreState[vin].push(element.path);
|
|
467
|
-
this.log.info(
|
|
472
|
+
this.log.info('Feature not found for ' + vin + '. Ignore ' + element.path + ' for updates.');
|
|
468
473
|
this.log.debug(error);
|
|
469
474
|
error.response && this.log.debug(JSON.stringify(error.response.data));
|
|
470
475
|
return;
|
|
@@ -485,39 +490,39 @@ class Renault extends utils.Adapter {
|
|
|
485
490
|
}
|
|
486
491
|
async refreshToken() {
|
|
487
492
|
if (!this.session_data) {
|
|
488
|
-
this.log.error(
|
|
493
|
+
this.log.error('No session found relogin');
|
|
489
494
|
await this.login();
|
|
490
495
|
return;
|
|
491
496
|
}
|
|
492
497
|
await this.requestClient({
|
|
493
|
-
method:
|
|
494
|
-
url:
|
|
498
|
+
method: 'post',
|
|
499
|
+
url: 'https://accounts.eu1.gigya.com/accounts.getJWT',
|
|
495
500
|
headers: {
|
|
496
|
-
|
|
497
|
-
Accept:
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
+
'User-Agent': 'MYRenault/39 CFNetwork/1312 Darwin/21.0.0',
|
|
502
|
+
Accept: '*/*',
|
|
503
|
+
'Accept-Language': 'de-de',
|
|
504
|
+
'Cache-Control': 'no-cache',
|
|
505
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
501
506
|
},
|
|
502
507
|
data: qs.stringify({
|
|
503
|
-
format:
|
|
508
|
+
format: 'json',
|
|
504
509
|
login_token: this.session_data.cookieValue,
|
|
505
|
-
sdk:
|
|
506
|
-
fields:
|
|
510
|
+
sdk: 'js_latest',
|
|
511
|
+
fields: 'data.personId,data.gigyaDataCenter',
|
|
507
512
|
apikey: this.apiKey,
|
|
508
|
-
expiration:
|
|
513
|
+
expiration: '3600',
|
|
509
514
|
}),
|
|
510
515
|
})
|
|
511
516
|
.then((res) => {
|
|
512
517
|
this.log.debug(JSON.stringify(res.data));
|
|
513
518
|
this.session = res.data;
|
|
514
|
-
this.setState(
|
|
519
|
+
this.setState('info.connection', true, true);
|
|
515
520
|
})
|
|
516
521
|
.catch((error) => {
|
|
517
|
-
this.log.error(
|
|
522
|
+
this.log.error('refresh token failed');
|
|
518
523
|
this.log.error(error);
|
|
519
524
|
error.response && this.log.error(JSON.stringify(error.response.data));
|
|
520
|
-
this.log.error(
|
|
525
|
+
this.log.error('Start relogin in 1min');
|
|
521
526
|
this.reLoginTimeout = setTimeout(() => {
|
|
522
527
|
this.login();
|
|
523
528
|
}, 1000 * 60 * 1);
|
|
@@ -530,8 +535,8 @@ class Renault extends utils.Adapter {
|
|
|
530
535
|
if (!string) {
|
|
531
536
|
return;
|
|
532
537
|
}
|
|
533
|
-
string = string.replace(
|
|
534
|
-
string = string.replace(
|
|
538
|
+
string = string.replace('actions/', '');
|
|
539
|
+
string = string.replace('/', '-');
|
|
535
540
|
const camelC = string.replace(/-([a-z])/g, function (g) {
|
|
536
541
|
return g[1].toUpperCase();
|
|
537
542
|
});
|
|
@@ -543,7 +548,7 @@ class Renault extends utils.Adapter {
|
|
|
543
548
|
*/
|
|
544
549
|
onUnload(callback) {
|
|
545
550
|
try {
|
|
546
|
-
this.setState(
|
|
551
|
+
this.setState('info.connection', false, true);
|
|
547
552
|
clearTimeout(this.refreshTimeout);
|
|
548
553
|
this.reLoginTimeout && clearTimeout(this.reLoginTimeout);
|
|
549
554
|
this.refreshTokenTimeout && clearTimeout(this.refreshTokenTimeout);
|
|
@@ -563,30 +568,30 @@ class Renault extends utils.Adapter {
|
|
|
563
568
|
async onStateChange(id, state) {
|
|
564
569
|
if (state) {
|
|
565
570
|
if (!state.ack) {
|
|
566
|
-
const deviceId = id.split(
|
|
567
|
-
const path = id.split(
|
|
568
|
-
if (path ===
|
|
571
|
+
const deviceId = id.split('.')[2];
|
|
572
|
+
const path = id.split('.')[4];
|
|
573
|
+
if (path === 'hvac-temperature') {
|
|
569
574
|
return;
|
|
570
575
|
}
|
|
571
|
-
if (path ===
|
|
572
|
-
this.log.info(
|
|
576
|
+
if (path === 'refresh') {
|
|
577
|
+
this.log.info('Force refresh');
|
|
573
578
|
this.updateDevices();
|
|
574
579
|
return;
|
|
575
580
|
}
|
|
576
581
|
if (!this.account) {
|
|
577
|
-
this.log.error(
|
|
582
|
+
this.log.error('No account found');
|
|
578
583
|
return;
|
|
579
584
|
}
|
|
580
|
-
const command = path.split(
|
|
581
|
-
let action = state.val ?
|
|
582
|
-
let midPart =
|
|
583
|
-
if (path ===
|
|
584
|
-
action = state.val ?
|
|
585
|
-
midPart =
|
|
585
|
+
const command = path.split('/')[1];
|
|
586
|
+
let action = state.val ? 'start' : 'cancel';
|
|
587
|
+
let midPart = 'kca/car-adapter/v1/cars/';
|
|
588
|
+
if (path === 'charge/pause-resume') {
|
|
589
|
+
action = state.val ? 'resume' : 'pause';
|
|
590
|
+
midPart = 'kcm/v1/vehicles/';
|
|
586
591
|
}
|
|
587
592
|
const data = { data: { type: this.toCamelCase(path), attributes: { action: action } } };
|
|
588
|
-
if (command ===
|
|
589
|
-
const temperatureState = await this.getStateAsync(deviceId +
|
|
593
|
+
if (command === 'hvac-start') {
|
|
594
|
+
const temperatureState = await this.getStateAsync(deviceId + '.remote.hvac-temperature');
|
|
590
595
|
if (temperatureState) {
|
|
591
596
|
data.data.attributes.targetTemperature = temperatureState.val ? temperatureState.val : 21;
|
|
592
597
|
} else {
|
|
@@ -594,27 +599,27 @@ class Renault extends utils.Adapter {
|
|
|
594
599
|
}
|
|
595
600
|
}
|
|
596
601
|
const url =
|
|
597
|
-
|
|
602
|
+
'https://api-wired-prod-1-euw1.wrd-aws.com/commerce/v1/accounts/' +
|
|
598
603
|
this.account.accountId +
|
|
599
|
-
|
|
604
|
+
'/kamereon/' +
|
|
600
605
|
midPart +
|
|
601
606
|
deviceId +
|
|
602
|
-
|
|
607
|
+
'/' +
|
|
603
608
|
path +
|
|
604
|
-
|
|
609
|
+
'?country=' +
|
|
605
610
|
this.country;
|
|
606
611
|
this.log.debug(JSON.stringify(data));
|
|
607
612
|
this.log.debug(url);
|
|
608
613
|
await this.requestClient({
|
|
609
|
-
method:
|
|
614
|
+
method: 'post',
|
|
610
615
|
url: url,
|
|
611
616
|
headers: {
|
|
612
617
|
apikey: this.apiKeyUpdate,
|
|
613
|
-
|
|
614
|
-
accept:
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
+
'content-type': 'application/vnd.api+json',
|
|
619
|
+
accept: '*/*',
|
|
620
|
+
'user-agent': 'MYRenault/39 CFNetwork/1312 Darwin/21.0.0',
|
|
621
|
+
'accept-language': 'de-de',
|
|
622
|
+
'x-gigya-id_token': this.session.id_token,
|
|
618
623
|
},
|
|
619
624
|
data: data,
|
|
620
625
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.renault",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"description": "Adapter for Renault and Renault",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "TA2k",
|
|
@@ -24,29 +24,29 @@
|
|
|
24
24
|
"url": "https://github.com/TA2k/ioBroker.renault"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@iobroker/adapter-core": "^
|
|
28
|
-
"axios": "^1.
|
|
27
|
+
"@iobroker/adapter-core": "^3.0.4",
|
|
28
|
+
"axios": "^1.6.2",
|
|
29
29
|
"json-bigint": "^1.0.0",
|
|
30
|
-
"json2iob": "^2.
|
|
30
|
+
"json2iob": "^2.5.1",
|
|
31
31
|
"qs": "^6.11.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@iobroker/testing": "^4.1.0",
|
|
35
|
-
"@types/chai": "^4.3.
|
|
36
|
-
"@types/chai-as-promised": "^7.1.
|
|
37
|
-
"@types/mocha": "^10.0.
|
|
38
|
-
"@types/node": "^
|
|
39
|
-
"@types/proxyquire": "^1.3.
|
|
40
|
-
"@types/sinon": "^
|
|
41
|
-
"@types/sinon-chai": "^3.2.
|
|
42
|
-
"chai": "^4.3.
|
|
35
|
+
"@types/chai": "^4.3.11",
|
|
36
|
+
"@types/chai-as-promised": "^7.1.8",
|
|
37
|
+
"@types/mocha": "^10.0.6",
|
|
38
|
+
"@types/node": "^20.10.5",
|
|
39
|
+
"@types/proxyquire": "^1.3.31",
|
|
40
|
+
"@types/sinon": "^17.0.2",
|
|
41
|
+
"@types/sinon-chai": "^3.2.12",
|
|
42
|
+
"chai": "^4.3.10",
|
|
43
43
|
"chai-as-promised": "^7.1.1",
|
|
44
|
-
"eslint": "^8.
|
|
44
|
+
"eslint": "^8.56.0",
|
|
45
45
|
"mocha": "^10.2.0",
|
|
46
46
|
"proxyquire": "^2.1.3",
|
|
47
|
-
"sinon": "^
|
|
47
|
+
"sinon": "^17.0.1",
|
|
48
48
|
"sinon-chai": "^3.7.0",
|
|
49
|
-
"typescript": "^5.
|
|
49
|
+
"typescript": "^5.3.3"
|
|
50
50
|
},
|
|
51
51
|
"main": "main.js",
|
|
52
52
|
"files": [
|