iobroker.toyota 0.1.0 → 0.2.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.
@@ -1,10 +1,8 @@
1
1
  <html>
2
-
3
- <head>
4
-
2
+ <head>
5
3
  <!-- Load ioBroker scripts and styles-->
6
4
  <link rel="stylesheet" type="text/css" href="../../css/adapter.css" />
7
- <link rel="stylesheet" type="text/css" href="../../lib/css/materialize.css">
5
+ <link rel="stylesheet" type="text/css" href="../../lib/css/materialize.css" />
8
6
 
9
7
  <script type="text/javascript" src="../../lib/js/jquery-3.2.1.min.js"></script>
10
8
  <script type="text/javascript" src="../../socket.io/socket.io.js"></script>
@@ -18,84 +16,85 @@
18
16
  <script type="text/javascript" src="words.js"></script>
19
17
 
20
18
  <script type="text/javascript">
21
- // This will be called by the admin adapter when the settings page loads
22
- function load(settings, onChange) {
23
- // example: select elements with id=key and class=value and insert value
24
- if (!settings) return;
25
- $('.value').each(function () {
26
- var $key = $(this);
27
- var id = $key.attr('id');
28
- if ($key.attr('type') === 'checkbox') {
29
- // do not call onChange direct, because onChange could expect some arguments
30
- $key.prop('checked', settings[id])
31
- .on('change', () => onChange())
32
- ;
33
- } else {
34
- // do not call onChange direct, because onChange could expect some arguments
35
- $key.val(settings[id])
36
- .on('change', () => onChange())
37
- .on('keyup', () => onChange())
38
- ;
39
- }
40
- });
41
- onChange(false);
42
- // reinitialize all the Materialize labels on the page if you are dynamically adding inputs:
43
- if (M) M.updateTextFields();
44
- }
45
-
46
- // This will be called by the admin adapter when the user presses the save button
47
- function save(callback) {
48
- // example: select elements with class=value and build settings object
49
- var obj = {};
50
- $('.value').each(function () {
51
- var $this = $(this);
52
- if ($this.attr('type') === 'checkbox') {
53
- obj[$this.attr('id')] = $this.prop('checked');
54
- } else if ($this.attr('type') === 'number') {
55
- obj[$this.attr('id')] = parseFloat($this.val());
56
- } else {
57
- obj[$this.attr('id')] = $this.val();
58
- }
59
- });
60
- callback(obj);
61
- }
19
+ // This will be called by the admin adapter when the settings page loads
20
+ function load(settings, onChange) {
21
+ // example: select elements with id=key and class=value and insert value
22
+ if (!settings) return;
23
+ $(".value").each(function () {
24
+ var $key = $(this);
25
+ var id = $key.attr("id");
26
+ if ($key.attr("type") === "checkbox") {
27
+ // do not call onChange direct, because onChange could expect some arguments
28
+ $key.prop("checked", settings[id]).on("change", () => onChange());
29
+ } else {
30
+ // do not call onChange direct, because onChange could expect some arguments
31
+ $key
32
+ .val(settings[id])
33
+ .on("change", () => onChange())
34
+ .on("keyup", () => onChange());
35
+ }
36
+ });
37
+ onChange(false);
38
+ // reinitialize all the Materialize labels on the page if you are dynamically adding inputs:
39
+ if (M) M.updateTextFields();
40
+ }
41
+
42
+ // This will be called by the admin adapter when the user presses the save button
43
+ function save(callback) {
44
+ // example: select elements with class=value and build settings object
45
+ var obj = {};
46
+ $(".value").each(function () {
47
+ var $this = $(this);
48
+ if ($this.attr("type") === "checkbox") {
49
+ obj[$this.attr("id")] = $this.prop("checked");
50
+ } else if ($this.attr("type") === "number") {
51
+ obj[$this.attr("id")] = parseFloat($this.val());
52
+ } else {
53
+ obj[$this.attr("id")] = $this.val();
54
+ }
55
+ });
56
+ callback(obj);
57
+ }
62
58
  </script>
59
+ </head>
63
60
 
64
- </head>
65
-
66
- <body>
67
-
61
+ <body>
68
62
  <div class="m adapter-container">
69
-
70
- <div class="row">
71
- <div class="col s12 m4 l2">
72
- <img src="toyota.png" class="logo">
73
- </div>
63
+ <div class="row">
64
+ <div class="col s12 m4 l2">
65
+ <img src="toyota.png" class="logo" />
74
66
  </div>
67
+ </div>
75
68
 
76
- <!-- Put your content here -->
69
+ <!-- Put your content here -->
77
70
 
78
- <div class="row">
79
- <div class="col s6 input-field">
80
- <input type="text" class="value" id="username" />
81
- <label for="username" class="translate">App Email</label>
82
- </div>
71
+ <div class="row">
72
+ <div class="col s6 input-field">
73
+ <input type="text" class="value" id="username" />
74
+ <label for="username" class="translate">App Email</label>
83
75
  </div>
84
- <div class="row">
85
- <div class="col s6 input-field">
86
- <input type="password" class="value" id="password" />
87
- <label for="password" class="translate">App Password</label>
88
- </div>
76
+ </div>
77
+ <div class="row">
78
+ <div class="col s6 input-field">
79
+ <input type="password" class="value" id="password" />
80
+ <label for="password" class="translate">App Password</label>
89
81
  </div>
90
-
91
- <div class="row">
92
- <div class="col s2 input-field">
93
- <input type="number" class="value" id="interval" />
94
- <label for="interval" class="translate">Update interval in minutes</label>
95
- </div>
82
+ </div>
83
+ <div class="row">
84
+ <div class="col s2 input-field">
85
+ <select id="type" class="value">
86
+ <option value="toyota">Toyota</option>
87
+ <option value="lexus">Lexus</option>
88
+ </select>
89
+ <label for="type" class="translate">App Toyota or Lexus</label>
90
+ </div>
91
+ </div>
92
+ <div class="row">
93
+ <div class="col s2 input-field">
94
+ <input type="number" class="value" id="interval" />
95
+ <label for="interval" class="translate">Update interval in minutes</label>
96
96
  </div>
97
+ </div>
97
98
  </div>
98
-
99
- </body>
100
-
101
- </html>
99
+ </body>
100
+ </html>
package/io-package.json CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "toyota",
4
- "version": "0.1.0",
4
+ "version": "0.2.0",
5
5
  "news": {
6
- "1.0.0": {
6
+ "0.2.0": {
7
+ "en": "added Lexus support",
8
+ "de": "Lexus Unterstützung hinzugefügt"
9
+ },
10
+ "0.1.0": {
7
11
  "en": "added new Charging API endpoints and AC Remote Control",
8
12
  "de": "hinzugefügt neue API-Endpunkte für das Laden und starten der Klimaanlage Remote Control"
9
13
  },
@@ -24,33 +28,33 @@
24
28
  "zh-cn": "首次出版"
25
29
  }
26
30
  },
27
- "title": "MyT Toyota",
31
+ "title": "myT Toyota/Lexus",
28
32
  "titleLang": {
29
- "en": "MyT Toyota",
30
- "de": "MyT Toyota",
31
- "ru": "MyT Toyota",
32
- "pt": "MyT Toyota",
33
+ "en": "myT Toyota/Lexus",
34
+ "de": "myT Toyota/Lexus",
35
+ "ru": "myT Toyota/Lexus",
36
+ "pt": "myT Toyota/Lexus",
33
37
  "nl": "MijnT Toyota",
34
- "fr": "MyT Toyota",
35
- "it": "MyT Toyota",
36
- "es": "MyT Toyota",
37
- "pl": "MyT Toyota",
38
+ "fr": "myT Toyota/Lexus",
39
+ "it": "myT Toyota/Lexus",
40
+ "es": "myT Toyota/Lexus",
41
+ "pl": "myT Toyota/Lexus",
38
42
  "zh-cn": "丰田"
39
43
  },
40
44
  "desc": {
41
- "en": "Adapter for myT Toyota App",
42
- "de": "Adapter für myT Toyota App",
43
- "ru": "Адаптер для приложения myT Toyota",
44
- "pt": "Adaptador para myT Toyota App",
45
- "nl": "Adapter voor myT Toyota-app",
46
- "fr": "Adaptateur pour l'application myT Toyota",
47
- "it": "Adattatore per app myT Toyota",
48
- "es": "Adaptador para la aplicación myT Toyota",
49
- "pl": "Adapter do aplikacji myT Toyota",
50
- "zh-cn": "适用于 myT Toyota App 的适配器"
45
+ "en": "Adapter for myT Toyota/Lexus App",
46
+ "de": "Adapter für myT Toyota/Lexus App",
47
+ "ru": "Адаптер для приложения myT Toyota/Lexus",
48
+ "pt": "Adaptador para myT Toyota/Lexus App",
49
+ "nl": "Adapter voor myT Toyota/Lexus-app",
50
+ "fr": "Adaptateur pour l'application myT Toyota/Lexus",
51
+ "it": "Adattatore per app myT Toyota/Lexus",
52
+ "es": "Adaptador para la aplicación myT Toyota/Lexus",
53
+ "pl": "Adapter do aplikacji myT Toyota/Lexus",
54
+ "zh-cn": "适用于 myT Toyota/Lexus App 的适配器"
51
55
  },
52
56
  "authors": ["TA2k <tombox2020@gmail.com>"],
53
- "keywords": ["toyota", "myt"],
57
+ "keywords": ["toyota", "myt", "lexus"],
54
58
  "license": "MIT",
55
59
  "platform": "Javascript/Node.js",
56
60
  "main": "main.js",
@@ -86,6 +90,7 @@
86
90
  "native": {
87
91
  "username": "",
88
92
  "password": "",
93
+ "type": "toyota",
89
94
  "interval": 10
90
95
  },
91
96
  "objects": [],
package/main.js CHANGED
@@ -30,6 +30,8 @@ class Toyota extends utils.Adapter {
30
30
  this.updateInterval = null;
31
31
  this.reLoginTimeout = null;
32
32
  this.refreshTokenTimeout = null;
33
+ this.hostName = "" + this.hostName + "";
34
+ this.brand = "TOYOTA";
33
35
  }
34
36
 
35
37
  /**
@@ -43,7 +45,11 @@ class Toyota extends utils.Adapter {
43
45
  this.config.interval = 0.5;
44
46
  }
45
47
  this.subscribeStates("*");
46
-
48
+ if (this.config.type === "lexus") {
49
+ this.log.info("Login to Lexus");
50
+ this.brand = "LEXUS";
51
+ this.hostName = "lexuslink-agg.toyota-europe.com";
52
+ }
47
53
  await this.login();
48
54
 
49
55
  if (this.token && this.uuid) {
@@ -60,12 +66,12 @@ class Toyota extends utils.Adapter {
60
66
  async login() {
61
67
  this.session_data = await this.requestClient({
62
68
  method: "post",
63
- url: "https://myt-agg.toyota-europe.com/cma/api/user/login",
69
+ url: "https://" + this.hostName + "/cma/api/user/login",
64
70
  headers: {
65
71
  accept: "*/*",
66
72
  "content-type": "application/json",
67
73
  "x-tme-locale": "en-gb",
68
- "x-tme-brand": "TOYOTA",
74
+ "x-tme-brand": this.brand,
69
75
  "x-tme-app-version": "4.18.1",
70
76
  "user-agent": "MyT/4.18.1 iPhone10,5 iOS/14.8 CFNetwork/1240.0.4 Darwin/20.6.0",
71
77
  "accept-language": "de-DE",
@@ -95,7 +101,7 @@ class Toyota extends utils.Adapter {
95
101
  async getDeviceList() {
96
102
  await this.requestClient({
97
103
  method: "get",
98
- url: "https://myt-agg.toyota-europe.com/cma/api/user/" + this.uuid + "/vehicle/details?allServices=true",
104
+ url: "https://" + this.hostName + "/cma/api/user/" + this.uuid + "/vehicle/details?allServices=true",
99
105
  headers: {
100
106
  cookie: "iPlanetDirectoryPro=" + this.token,
101
107
  accept: "*/*",
@@ -103,7 +109,7 @@ class Toyota extends utils.Adapter {
103
109
  "x-tme-app-version": "4.18.1",
104
110
  "user-agent": "MyT/4.18.1 iPhone10,5 iOS/14.8 CFNetwork/1240.0.4 Darwin/20.6.0",
105
111
  "accept-language": "de-DE",
106
- "x-tme-brand": "TOYOTA",
112
+ "x-tme-brand": this.brand,
107
113
  },
108
114
  })
109
115
  .then(async (res) => {
@@ -116,6 +122,7 @@ class Toyota extends utils.Adapter {
116
122
  }
117
123
  this.deviceArray.push(device.vin);
118
124
  const name = device.alias;
125
+ this.log.info("Create vehicle " + device.vin + " " + name);
119
126
  await this.setObjectNotExistsAsync(device.vin, {
120
127
  type: "device",
121
128
  common: {
@@ -168,27 +175,27 @@ class Toyota extends utils.Adapter {
168
175
  const statusArray = [
169
176
  {
170
177
  path: "status",
171
- url: "https://myt-agg.toyota-europe.com/cma/api/users/" + this.uuid + "/vehicles/$vin/vehicleStatus",
178
+ url: "https://" + this.hostName + "/cma/api/users/" + this.uuid + "/vehicles/$vin/vehicleStatus",
172
179
  desc: "Status of the car",
173
180
  },
174
181
  {
175
182
  path: "addtionalInfo",
176
- url: "https://myt-agg.toyota-europe.com/cma/api/vehicle/$vin/addtionalInfo",
183
+ url: "https://" + this.hostName + "/cma/api/vehicle/$vin/addtionalInfo",
177
184
  desc: "AddtionalInfo of the car",
178
185
  },
179
186
  {
180
187
  path: "location",
181
- url: "https://myt-agg.toyota-europe.com/cma/api/users/" + this.uuid + "/vehicle/location",
188
+ url: "https://" + this.hostName + "/cma/api/users/" + this.uuid + "/vehicle/location",
182
189
  desc: "Location of the car",
183
190
  },
184
191
  {
185
192
  path: "parking",
186
- url: "https://myt-agg.toyota-europe.com/cma/api/users/" + this.uuid + "/vehicles/$vin/parking",
193
+ url: "https://" + this.hostName + "/cma/api/users/" + this.uuid + "/vehicles/$vin/parking",
187
194
  desc: "Parking of the car",
188
195
  },
189
196
  {
190
197
  path: "statusV2",
191
- url: "https://myt-agg.toyota-europe.com/cma/api/vehicles/$vin/remoteControl/status",
198
+ url: "https://" + this.hostName + "/cma/api/vehicles/$vin/remoteControl/status",
192
199
  desc: "Additional Status Information",
193
200
  },
194
201
  ];
@@ -201,7 +208,7 @@ class Toyota extends utils.Adapter {
201
208
  "x-tme-app-version": "4.15.0",
202
209
  "user-agent": "MyT/4.15.0 iPhone10,5 iOS/14.8 CFNetwork/1240.0.4 Darwin/20.6.0",
203
210
  "accept-language": "de-DE",
204
- "x-tme-brand": "TOYOTA",
211
+ "x-tme-brand": this.brand,
205
212
  };
206
213
  this.deviceArray.forEach(async (vin) => {
207
214
  statusArray.forEach(async (element) => {
@@ -304,7 +311,7 @@ class Toyota extends utils.Adapter {
304
311
  },
305
312
  },
306
313
  };
307
- const url = "https://myt-agg.toyota-europe.com/cma/api/user/" + this.uuid + "/vehicle/" + deviceId + "/remoteControl";
314
+ const url = "https://" + this.hostName + "/cma/api/user/" + this.uuid + "/vehicle/" + deviceId + "/remoteControl";
308
315
  this.log.debug(JSON.stringify(data));
309
316
  this.log.debug(url);
310
317
  await this.requestClient({
@@ -317,7 +324,7 @@ class Toyota extends utils.Adapter {
317
324
  "x-tme-app-version": "4.18.1",
318
325
  "user-agent": "MyT/4.18.1 iPhone10,5 iOS/14.8 CFNetwork/1240.0.4 Darwin/20.6.0",
319
326
  "accept-language": "de-DE",
320
- "x-tme-brand": "TOYOTA",
327
+ "x-tme-brand": this.brand,
321
328
  },
322
329
  data: data,
323
330
  })
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "iobroker.toyota",
3
- "version": "0.1.0",
4
- "description": "Adapter for myT Toyota App",
3
+ "version": "0.2.0",
4
+ "description": "Adapter for myT Toyota/Lexus App",
5
5
  "author": {
6
6
  "name": "TA2k",
7
7
  "email": "tombox2020@gmail.com"
@@ -15,6 +15,7 @@
15
15
  "license": "MIT",
16
16
  "keywords": [
17
17
  "toyota",
18
+ "lexus",
18
19
  "myt"
19
20
  ],
20
21
  "repository": {
@@ -22,28 +23,28 @@
22
23
  "url": "https://github.com/TA2k/ioBroker.toyota"
23
24
  },
24
25
  "dependencies": {
25
- "@iobroker/adapter-core": "^3.0.3",
26
- "axios": "^1.4.0",
27
- "json2iob": "^2.4.6"
26
+ "@iobroker/adapter-core": "^3.0.4",
27
+ "axios": "^1.5.1",
28
+ "json2iob": "^2.4.8"
28
29
  },
29
30
  "devDependencies": {
30
31
  "@iobroker/testing": "^4.1.0",
31
- "@types/chai": "^4.3.5",
32
- "@types/chai-as-promised": "^7.1.5",
33
- "@types/gulp": "^4.0.13",
34
- "@types/mocha": "^10.0.1",
35
- "@types/node": "^20.5.1",
36
- "@types/proxyquire": "^1.3.28",
37
- "@types/sinon": "^10.0.16",
38
- "@types/sinon-chai": "^3.2.9",
39
- "chai": "^4.3.7",
32
+ "@types/chai": "^4.3.9",
33
+ "@types/chai-as-promised": "^7.1.7",
34
+ "@types/gulp": "^4.0.16",
35
+ "@types/mocha": "^10.0.2",
36
+ "@types/node": "^20.8.6",
37
+ "@types/proxyquire": "^1.3.29",
38
+ "@types/sinon": "^10.0.19",
39
+ "@types/sinon-chai": "^3.2.10",
40
+ "chai": "^4.3.10",
40
41
  "chai-as-promised": "^7.1.1",
41
- "eslint": "^8.47.0",
42
+ "eslint": "^8.51.0",
42
43
  "mocha": "^10.2.0",
43
44
  "proxyquire": "^2.1.3",
44
45
  "sinon": "^15.2.0",
45
46
  "sinon-chai": "^3.7.0",
46
- "typescript": "~5.1.6"
47
+ "typescript": "~5.2.2"
47
48
  },
48
49
  "main": "main.js",
49
50
  "files": [