iobroker.toyota 0.0.3 → 0.0.4
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 +107 -112
- package/main.js +290 -246
- package/package.json +16 -17
package/io-package.json
CHANGED
|
@@ -1,116 +1,111 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
"de": "MyT Toyota",
|
|
23
|
-
"ru": "MyT Toyota",
|
|
24
|
-
"pt": "MyT Toyota",
|
|
25
|
-
"nl": "MijnT Toyota",
|
|
26
|
-
"fr": "MyT Toyota",
|
|
27
|
-
"it": "MyT Toyota",
|
|
28
|
-
"es": "MyT Toyota",
|
|
29
|
-
"pl": "MyT Toyota",
|
|
30
|
-
"zh-cn": "丰田"
|
|
31
|
-
},
|
|
32
|
-
"desc": {
|
|
33
|
-
"en": "Adapter for myT Toyota App",
|
|
34
|
-
"de": "Adapter für myT Toyota App",
|
|
35
|
-
"ru": "Адаптер для приложения myT Toyota",
|
|
36
|
-
"pt": "Adaptador para myT Toyota App",
|
|
37
|
-
"nl": "Adapter voor myT Toyota-app",
|
|
38
|
-
"fr": "Adaptateur pour l'application myT Toyota",
|
|
39
|
-
"it": "Adattatore per app myT Toyota",
|
|
40
|
-
"es": "Adaptador para la aplicación myT Toyota",
|
|
41
|
-
"pl": "Adapter do aplikacji myT Toyota",
|
|
42
|
-
"zh-cn": "适用于 myT Toyota App 的适配器"
|
|
43
|
-
},
|
|
44
|
-
"authors": [
|
|
45
|
-
"TA2k <tombox2020@gmail.com>"
|
|
46
|
-
],
|
|
47
|
-
"keywords": [
|
|
48
|
-
"toyota",
|
|
49
|
-
"myt"
|
|
50
|
-
],
|
|
51
|
-
"license": "MIT",
|
|
52
|
-
"platform": "Javascript/Node.js",
|
|
53
|
-
"main": "main.js",
|
|
54
|
-
"icon": "toyota.png",
|
|
55
|
-
"enabled": true,
|
|
56
|
-
"extIcon": "https://raw.githubusercontent.com/TA2k/ioBroker.toyota/master/admin/toyota.png",
|
|
57
|
-
"readme": "https://github.com/TA2k/ioBroker.toyota/blob/master/README.md",
|
|
58
|
-
"loglevel": "info",
|
|
59
|
-
"mode": "daemon",
|
|
60
|
-
"type": "vehicle",
|
|
61
|
-
"compact": true,
|
|
62
|
-
"connectionType": "cloud",
|
|
63
|
-
"dataSource": "poll",
|
|
64
|
-
"materialize": true,
|
|
65
|
-
"plugins": {
|
|
66
|
-
"sentry": {
|
|
67
|
-
"dsn": "https://c9bd6c851b1246da95e6e982aa9b88f3@sentry.iobroker.net/152"
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
"dependencies": [
|
|
71
|
-
{
|
|
72
|
-
"js-controller": ">=3.0.0"
|
|
73
|
-
}
|
|
74
|
-
],
|
|
75
|
-
"globalDependencies": [
|
|
76
|
-
{
|
|
77
|
-
"admin": ">=4.0.9"
|
|
78
|
-
}
|
|
79
|
-
]
|
|
2
|
+
"common": {
|
|
3
|
+
"name": "toyota",
|
|
4
|
+
"version": "0.0.4",
|
|
5
|
+
"news": {
|
|
6
|
+
"0.0.4": {
|
|
7
|
+
"en": "updated new API endpoints",
|
|
8
|
+
"de": "aktualisierte neue API-Endpunkte"
|
|
9
|
+
},
|
|
10
|
+
"0.0.3": {
|
|
11
|
+
"en": "initial release",
|
|
12
|
+
"de": "Erstveröffentlichung",
|
|
13
|
+
"ru": "Начальная версия",
|
|
14
|
+
"pt": "lançamento inicial",
|
|
15
|
+
"nl": "Eerste uitgave",
|
|
16
|
+
"fr": "Première version",
|
|
17
|
+
"it": "Versione iniziale",
|
|
18
|
+
"es": "Versión inicial",
|
|
19
|
+
"pl": "Pierwsze wydanie",
|
|
20
|
+
"zh-cn": "首次出版"
|
|
21
|
+
}
|
|
80
22
|
},
|
|
81
|
-
"
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
23
|
+
"title": "MyT Toyota",
|
|
24
|
+
"titleLang": {
|
|
25
|
+
"en": "MyT Toyota",
|
|
26
|
+
"de": "MyT Toyota",
|
|
27
|
+
"ru": "MyT Toyota",
|
|
28
|
+
"pt": "MyT Toyota",
|
|
29
|
+
"nl": "MijnT Toyota",
|
|
30
|
+
"fr": "MyT Toyota",
|
|
31
|
+
"it": "MyT Toyota",
|
|
32
|
+
"es": "MyT Toyota",
|
|
33
|
+
"pl": "MyT Toyota",
|
|
34
|
+
"zh-cn": "丰田"
|
|
35
|
+
},
|
|
36
|
+
"desc": {
|
|
37
|
+
"en": "Adapter for myT Toyota App",
|
|
38
|
+
"de": "Adapter für myT Toyota App",
|
|
39
|
+
"ru": "Адаптер для приложения myT Toyota",
|
|
40
|
+
"pt": "Adaptador para myT Toyota App",
|
|
41
|
+
"nl": "Adapter voor myT Toyota-app",
|
|
42
|
+
"fr": "Adaptateur pour l'application myT Toyota",
|
|
43
|
+
"it": "Adattatore per app myT Toyota",
|
|
44
|
+
"es": "Adaptador para la aplicación myT Toyota",
|
|
45
|
+
"pl": "Adapter do aplikacji myT Toyota",
|
|
46
|
+
"zh-cn": "适用于 myT Toyota App 的适配器"
|
|
91
47
|
},
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
48
|
+
"authors": ["TA2k <tombox2020@gmail.com>"],
|
|
49
|
+
"keywords": ["toyota", "myt"],
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"platform": "Javascript/Node.js",
|
|
52
|
+
"main": "main.js",
|
|
53
|
+
"icon": "toyota.png",
|
|
54
|
+
"enabled": true,
|
|
55
|
+
"extIcon": "https://raw.githubusercontent.com/TA2k/ioBroker.toyota/master/admin/toyota.png",
|
|
56
|
+
"readme": "https://github.com/TA2k/ioBroker.toyota/blob/master/README.md",
|
|
57
|
+
"loglevel": "info",
|
|
58
|
+
"mode": "daemon",
|
|
59
|
+
"type": "vehicle",
|
|
60
|
+
"compact": true,
|
|
61
|
+
"connectionType": "cloud",
|
|
62
|
+
"dataSource": "poll",
|
|
63
|
+
"materialize": true,
|
|
64
|
+
"plugins": {
|
|
65
|
+
"sentry": {
|
|
66
|
+
"dsn": "https://c9bd6c851b1246da95e6e982aa9b88f3@sentry.iobroker.net/152"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"dependencies": [
|
|
70
|
+
{
|
|
71
|
+
"js-controller": ">=3.0.0"
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
"globalDependencies": [
|
|
75
|
+
{
|
|
76
|
+
"admin": ">=4.0.9"
|
|
77
|
+
}
|
|
115
78
|
]
|
|
116
|
-
}
|
|
79
|
+
},
|
|
80
|
+
"encryptedNative": ["password"],
|
|
81
|
+
"protectedNative": ["password"],
|
|
82
|
+
"native": {
|
|
83
|
+
"username": "",
|
|
84
|
+
"password": "",
|
|
85
|
+
"interval": 10
|
|
86
|
+
},
|
|
87
|
+
"objects": [],
|
|
88
|
+
"instanceObjects": [
|
|
89
|
+
{
|
|
90
|
+
"_id": "info",
|
|
91
|
+
"type": "channel",
|
|
92
|
+
"common": {
|
|
93
|
+
"name": "Information"
|
|
94
|
+
},
|
|
95
|
+
"native": {}
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"_id": "info.connection",
|
|
99
|
+
"type": "state",
|
|
100
|
+
"common": {
|
|
101
|
+
"role": "indicator.connected",
|
|
102
|
+
"name": "Device or service connected",
|
|
103
|
+
"type": "boolean",
|
|
104
|
+
"read": true,
|
|
105
|
+
"write": false,
|
|
106
|
+
"def": false
|
|
107
|
+
},
|
|
108
|
+
"native": {}
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
package/main.js
CHANGED
|
@@ -11,274 +11,318 @@ const axios = require("axios");
|
|
|
11
11
|
const Json2iob = require("./lib/json2iob");
|
|
12
12
|
|
|
13
13
|
class Toyota extends utils.Adapter {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
14
|
+
/**
|
|
15
|
+
* @param {Partial<utils.AdapterOptions>} [options={}]
|
|
16
|
+
*/
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super({
|
|
19
|
+
...options,
|
|
20
|
+
name: "toyota",
|
|
21
|
+
});
|
|
22
|
+
this.on("ready", this.onReady.bind(this));
|
|
23
|
+
this.on("stateChange", this.onStateChange.bind(this));
|
|
24
|
+
this.on("unload", this.onUnload.bind(this));
|
|
25
|
+
this.deviceArray = [];
|
|
26
|
+
this.json2iob = new Json2iob(this);
|
|
27
|
+
this.token = null;
|
|
28
|
+
this.uuid = null;
|
|
29
|
+
this.requestClient = axios.create();
|
|
30
|
+
this.updateInterval = null;
|
|
31
|
+
this.reLoginTimeout = null;
|
|
32
|
+
this.refreshTokenTimeout = null;
|
|
33
|
+
}
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Is called when databases are connected and adapter received configuration.
|
|
37
|
+
*/
|
|
38
|
+
async onReady() {
|
|
39
|
+
// Reset the connection indicator during startup
|
|
40
|
+
this.setState("info.connection", false, true);
|
|
41
|
+
if (this.config.interval < 0.5) {
|
|
42
|
+
this.log.info("Set interval to minimum 0.5");
|
|
43
|
+
this.config.interval = 0.5;
|
|
44
|
+
}
|
|
45
|
+
this.subscribeStates("*");
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
await this.login();
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
49
|
+
if (this.token && this.uuid) {
|
|
50
|
+
await this.getDeviceList();
|
|
51
|
+
await this.updateDevices();
|
|
52
|
+
this.updateInterval = setInterval(async () => {
|
|
53
|
+
await this.updateDevices();
|
|
54
|
+
}, this.config.interval * 60 * 1000);
|
|
55
|
+
this.refreshTokenInterval = setInterval(() => {
|
|
56
|
+
this.login();
|
|
57
|
+
}, 3500 * 1000);
|
|
59
58
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
59
|
+
}
|
|
60
|
+
async login() {
|
|
61
|
+
this.session_data = await this.requestClient({
|
|
62
|
+
method: "post",
|
|
63
|
+
url: "https://myt-agg.toyota-europe.com/cma/api/user/login",
|
|
64
|
+
headers: {
|
|
65
|
+
accept: "*/*",
|
|
66
|
+
"content-type": "application/json",
|
|
67
|
+
"x-tme-locale": "en-gb",
|
|
68
|
+
"x-tme-brand": "TOYOTA",
|
|
69
|
+
"x-tme-app-version": "4.10.0",
|
|
70
|
+
"user-agent": "MyT/4.10.0 iPhone10,5 iOS/14.8 CFNetwork/1240.0.4 Darwin/20.6.0",
|
|
71
|
+
"accept-language": "de-DE",
|
|
72
|
+
},
|
|
73
|
+
data: JSON.stringify({
|
|
74
|
+
password: this.config.password,
|
|
75
|
+
username: this.config.username,
|
|
76
|
+
}),
|
|
77
|
+
})
|
|
78
|
+
.then((res) => {
|
|
79
|
+
this.log.debug(JSON.stringify(res.data));
|
|
80
|
+
this.token = res.data.token;
|
|
81
|
+
if (res.data.customerProfile) {
|
|
82
|
+
this.uuid = res.data.customerProfile.uuid;
|
|
83
|
+
} else {
|
|
84
|
+
this.log.error("No uuid found");
|
|
85
|
+
}
|
|
86
|
+
this.setState("info.connection", true, true);
|
|
87
|
+
})
|
|
88
|
+
.catch((error) => {
|
|
89
|
+
this.log.error(error);
|
|
90
|
+
if (error.response) {
|
|
91
|
+
this.log.error(JSON.stringify(error.response.data));
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async getDeviceList() {
|
|
96
|
+
await this.requestClient({
|
|
97
|
+
method: "get",
|
|
98
|
+
url: "https://myt-agg.toyota-europe.com/cma/api/user/" + this.uuid + "/vehicle/details",
|
|
99
|
+
headers: {
|
|
100
|
+
cookie: "iPlanetDirectoryPro=" + this.token,
|
|
101
|
+
accept: "*/*",
|
|
102
|
+
"x-tme-locale": "de-de",
|
|
103
|
+
"x-tme-app-version": "4.10.0",
|
|
104
|
+
"user-agent": "MyT/4.10.0 iPhone10,5 iOS/14.8 CFNetwork/1240.0.4 Darwin/20.6.0",
|
|
105
|
+
"accept-language": "de-DE",
|
|
106
|
+
"x-tme-brand": "TOYOTA",
|
|
107
|
+
},
|
|
108
|
+
})
|
|
109
|
+
.then(async (res) => {
|
|
110
|
+
this.log.debug(JSON.stringify(res.data));
|
|
111
|
+
this.log.info(`Found ${res.data.length} vehicles`);
|
|
112
|
+
for (const device of res.data) {
|
|
113
|
+
if (!device.vin) {
|
|
114
|
+
this.log.info(`No VIN found for ${device.deviceTypeName} (${device.alias})`);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
this.deviceArray.push(device.vin);
|
|
118
|
+
const name = device.alias;
|
|
119
|
+
await this.setObjectNotExistsAsync(device.vin, {
|
|
120
|
+
type: "device",
|
|
121
|
+
common: {
|
|
122
|
+
name: name,
|
|
72
123
|
},
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
this.log.debug(JSON.stringify(res.data));
|
|
80
|
-
this.token = res.data.token;
|
|
81
|
-
if (res.data.customerProfile) {
|
|
82
|
-
this.uuid = res.data.customerProfile.uuid;
|
|
83
|
-
} else {
|
|
84
|
-
this.log.error("No uuid found");
|
|
85
|
-
}
|
|
86
|
-
this.setState("info.connection", true, true);
|
|
87
|
-
})
|
|
88
|
-
.catch((error) => {
|
|
89
|
-
this.log.error(error);
|
|
90
|
-
if (error.response) {
|
|
91
|
-
this.log.error(JSON.stringify(error.response.data));
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
async getDeviceList() {
|
|
96
|
-
await this.requestClient({
|
|
97
|
-
method: "get",
|
|
98
|
-
url: "https://myt-agg.toyota-europe.com/cma/api/user/" + this.uuid + "/vehicle/details",
|
|
99
|
-
headers: {
|
|
100
|
-
cookie: "iPlanetDirectoryPro=" + this.token,
|
|
101
|
-
accept: "*/*",
|
|
102
|
-
"x-tme-locale": "de-de",
|
|
103
|
-
"x-tme-app-version": "4.5.0",
|
|
104
|
-
"user-agent": "MyT/4.5.0 iPhone10,5 iOS/14.8 CFNetwork/1240.0.4 Darwin/20.6.0",
|
|
105
|
-
"accept-language": "de-DE",
|
|
106
|
-
"x-tme-brand": "TOYOTA",
|
|
124
|
+
native: {},
|
|
125
|
+
});
|
|
126
|
+
await this.setObjectNotExistsAsync(device.vin + ".remote", {
|
|
127
|
+
type: "channel",
|
|
128
|
+
common: {
|
|
129
|
+
name: "Remote Controls",
|
|
107
130
|
},
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
common: {
|
|
118
|
-
name: name,
|
|
119
|
-
},
|
|
120
|
-
native: {},
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
await this.setObjectNotExistsAsync(device.vin + ".general", {
|
|
124
|
-
type: "channel",
|
|
125
|
-
common: {
|
|
126
|
-
name: "General Information",
|
|
127
|
-
},
|
|
128
|
-
native: {},
|
|
129
|
-
});
|
|
131
|
+
native: {},
|
|
132
|
+
});
|
|
133
|
+
await this.setObjectNotExistsAsync(device.vin + ".general", {
|
|
134
|
+
type: "channel",
|
|
135
|
+
common: {
|
|
136
|
+
name: "General Information",
|
|
137
|
+
},
|
|
138
|
+
native: {},
|
|
139
|
+
});
|
|
130
140
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
141
|
+
const remoteArray = [
|
|
142
|
+
{ command: "hvac", name: "True = Start, False = Stop" },
|
|
143
|
+
{ command: "hvac-temperature", name: "HVAC Temperature", type: "number", role: "value" },
|
|
144
|
+
];
|
|
145
|
+
remoteArray.forEach((remote) => {
|
|
146
|
+
this.setObjectNotExists(device.vin + ".remote." + remote.command, {
|
|
147
|
+
type: "state",
|
|
148
|
+
common: {
|
|
149
|
+
name: remote.name || "",
|
|
150
|
+
type: remote.type || "boolean",
|
|
151
|
+
role: remote.role || "boolean",
|
|
152
|
+
write: true,
|
|
153
|
+
read: true,
|
|
154
|
+
},
|
|
155
|
+
native: {},
|
|
137
156
|
});
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
157
|
+
});
|
|
158
|
+
this.json2iob.parse(device.vin + ".general", device);
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
.catch((error) => {
|
|
162
|
+
this.log.error(error);
|
|
163
|
+
error.response && this.log.error(JSON.stringify(error.response.data));
|
|
164
|
+
});
|
|
165
|
+
}
|
|
144
166
|
|
|
145
|
-
|
|
146
|
-
|
|
167
|
+
async updateDevices() {
|
|
168
|
+
const statusArray = [
|
|
169
|
+
{
|
|
170
|
+
path: "status",
|
|
171
|
+
url: "https://myt-agg.toyota-europe.com/cma/api/users/" + this.uuid + "/vehicles/$vin/vehicleStatus",
|
|
172
|
+
desc: "Status of the car",
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
path: "addtionalInfo",
|
|
176
|
+
url: "https://myt-agg.toyota-europe.com/cma/api/vehicle/$vin/addtionalInfo",
|
|
177
|
+
desc: "AddtionalInfo of the car",
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
path: "location",
|
|
181
|
+
url: "https://myt-agg.toyota-europe.com/cma/api/users/" + this.uuid + "/vehicle/location",
|
|
182
|
+
desc: "Location of the car",
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
path: "parking",
|
|
186
|
+
url: "https://myt-agg.toyota-europe.com/cma/api/users/" + this.uuid + "/vehicles/$vin/parking",
|
|
187
|
+
desc: "Parking of the car",
|
|
188
|
+
},
|
|
189
|
+
];
|
|
147
190
|
|
|
148
|
-
|
|
149
|
-
|
|
191
|
+
const headers = {
|
|
192
|
+
cookie: "iPlanetDirectoryPro=" + this.token,
|
|
193
|
+
uuid: this.uuid,
|
|
194
|
+
accept: "*/*",
|
|
195
|
+
"x-tme-locale": "de-de",
|
|
196
|
+
"x-tme-app-version": "4.15.0",
|
|
197
|
+
"user-agent": "MyT/4.15.0 iPhone10,5 iOS/14.8 CFNetwork/1240.0.4 Darwin/20.6.0",
|
|
198
|
+
"accept-language": "de-DE",
|
|
199
|
+
"x-tme-brand": "TOYOTA",
|
|
200
|
+
};
|
|
201
|
+
this.deviceArray.forEach(async (vin) => {
|
|
202
|
+
statusArray.forEach(async (element) => {
|
|
203
|
+
const url = element.url.replace("$vin", vin);
|
|
204
|
+
headers.vin = vin;
|
|
150
205
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
{
|
|
163
|
-
path: "remoteControlStatus",
|
|
164
|
-
url: "https://myt-agg.toyota-europe.com/cma/api/vehicles/$vin/remoteControl/status",
|
|
165
|
-
desc: "remoteControlStatus of the car",
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
path: "location",
|
|
169
|
-
url: "https://myt-agg.toyota-europe.com/cma/api/users/" + this.uuid + "/vehicle/location",
|
|
170
|
-
desc: "Location of the car",
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
path: "monthly trips",
|
|
174
|
-
url: "https://myt-agg.toyota-europe.com/cma/api/v2/trips/summarize?from=" + startDateMonthFormatted + "&to=" + date + "&calendarInterval=month",
|
|
175
|
-
desc: "monthly trips of the car",
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
path: "daily trips",
|
|
179
|
-
url: "https://myt-agg.toyota-europe.com/cma/api/v2/trips/summarize?from=" + startDateFormattedday + "&calendarInterval=day",
|
|
180
|
-
desc: "daily trips of the car",
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
path: "yearly trips",
|
|
184
|
-
url: "https://myt-agg.toyota-europe.com/cma/api/v2/trips/summarize?from=" + year + "-01-01&to=" + year + "-12-31",
|
|
185
|
-
desc: "yearly trips of the car",
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
path: "trips",
|
|
189
|
-
url: "https://myt-agg.toyota-europe.com/cma/api/v2/trips/",
|
|
190
|
-
desc: "trips of the car",
|
|
191
|
-
},
|
|
192
|
-
];
|
|
206
|
+
await this.requestClient({
|
|
207
|
+
method: "get",
|
|
208
|
+
url: url,
|
|
209
|
+
headers: headers,
|
|
210
|
+
})
|
|
211
|
+
.then((res) => {
|
|
212
|
+
this.log.debug(JSON.stringify(res.data));
|
|
213
|
+
if (!res.data) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const data = res.data;
|
|
193
217
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const url = element.url.replace("$vin", vin);
|
|
197
|
-
const headers = {
|
|
198
|
-
cookie: "iPlanetDirectoryPro=" + this.token,
|
|
199
|
-
accept: "*/*",
|
|
200
|
-
"x-tme-locale": "de-de",
|
|
201
|
-
vin: vin,
|
|
202
|
-
uuid: this.uuid,
|
|
203
|
-
"x-tme-app-version": "4.5.0",
|
|
204
|
-
"user-agent": "MyT/4.5.0 iPhone10,5 iOS/14.8 CFNetwork/1240.0.4 Darwin/20.6.0",
|
|
205
|
-
"accept-language": "de-DE",
|
|
206
|
-
"x-tme-brand": "TOYOTA",
|
|
207
|
-
};
|
|
208
|
-
await this.requestClient({
|
|
209
|
-
method: "get",
|
|
210
|
-
url: url,
|
|
211
|
-
headers: headers,
|
|
212
|
-
})
|
|
213
|
-
.then((res) => {
|
|
214
|
-
this.log.debug(JSON.stringify(res.data));
|
|
215
|
-
if (!res.data) {
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
const data = res.data;
|
|
218
|
+
const forceIndex = null;
|
|
219
|
+
const preferedArrayName = null;
|
|
219
220
|
|
|
220
|
-
|
|
221
|
-
|
|
221
|
+
this.json2iob.parse(vin + "." + element.path, data, {
|
|
222
|
+
forceIndex: forceIndex,
|
|
223
|
+
preferedArrayName: preferedArrayName,
|
|
224
|
+
channelName: element.desc,
|
|
225
|
+
});
|
|
226
|
+
})
|
|
227
|
+
.catch((error) => {
|
|
228
|
+
if (error.response) {
|
|
229
|
+
if (error.response.status === 401 || error.response.status === 403) {
|
|
230
|
+
error.response && this.log.debug(JSON.stringify(error.response.data));
|
|
231
|
+
this.log.info(element.path + " receive 401/403 error. Relogin in 5 minutes");
|
|
232
|
+
this.refreshTokenTimeout && clearTimeout(this.refreshTokenTimeout);
|
|
233
|
+
this.refreshTokenTimeout = setTimeout(() => {
|
|
234
|
+
this.login();
|
|
235
|
+
}, 1000 * 60 * 5);
|
|
222
236
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}, 1000 * 60 * 5);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
this.log.error(url);
|
|
241
|
+
this.log.error(error);
|
|
242
|
+
error.response && this.log.error(JSON.stringify(error.response.data));
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
}
|
|
234
247
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
248
|
+
/**
|
|
249
|
+
* Is called when adapter shuts down - callback has to be called under any circumstances!
|
|
250
|
+
* @param {() => void} callback
|
|
251
|
+
*/
|
|
252
|
+
onUnload(callback) {
|
|
253
|
+
try {
|
|
254
|
+
this.setState("info.connection", false, true);
|
|
255
|
+
this.refreshTimeout && clearTimeout(this.refreshTimeout);
|
|
256
|
+
this.reLoginTimeout && clearTimeout(this.reLoginTimeout);
|
|
257
|
+
this.refreshTokenTimeout && clearTimeout(this.refreshTokenTimeout);
|
|
258
|
+
this.updateInterval && clearInterval(this.updateInterval);
|
|
259
|
+
this.refreshTokenInterval && clearInterval(this.refreshTokenInterval);
|
|
260
|
+
callback();
|
|
261
|
+
} catch (e) {
|
|
262
|
+
callback();
|
|
244
263
|
}
|
|
264
|
+
}
|
|
245
265
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
this.updateInterval && clearInterval(this.updateInterval);
|
|
257
|
-
this.refreshTokenInterval && clearInterval(this.refreshTokenInterval);
|
|
258
|
-
callback();
|
|
259
|
-
} catch (e) {
|
|
260
|
-
callback();
|
|
266
|
+
/**
|
|
267
|
+
* Is called if a subscribed state changes
|
|
268
|
+
* @param {string} id
|
|
269
|
+
* @param {ioBroker.State | null | undefined} state
|
|
270
|
+
*/
|
|
271
|
+
async onStateChange(id, state) {
|
|
272
|
+
if (state) {
|
|
273
|
+
if (!state.ack) {
|
|
274
|
+
if (id.split(".")[3] !== "remote") {
|
|
275
|
+
return;
|
|
261
276
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
* @param {string} id
|
|
267
|
-
* @param {ioBroker.State | null | undefined} state
|
|
268
|
-
*/
|
|
269
|
-
async onStateChange(id, state) {
|
|
270
|
-
if (state) {
|
|
277
|
+
const deviceId = id.split(".")[2];
|
|
278
|
+
const path = id.split(".")[4];
|
|
279
|
+
if (path === "hvac-temperature") {
|
|
280
|
+
return;
|
|
271
281
|
}
|
|
282
|
+
const data = {};
|
|
283
|
+
const url = "https://myt-agg.toyota-europe.com/cma/api/user/" + this.uuid + "/vehicle/" + deviceId + "/remoteControl";
|
|
284
|
+
this.log.debug(JSON.stringify(data));
|
|
285
|
+
this.log.debug(url);
|
|
286
|
+
await this.requestClient({
|
|
287
|
+
method: "post",
|
|
288
|
+
url: url,
|
|
289
|
+
headers: {
|
|
290
|
+
cookie: "iPlanetDirectoryPro=" + this.token,
|
|
291
|
+
accept: "*/*",
|
|
292
|
+
"x-tme-locale": "de-de",
|
|
293
|
+
"x-tme-app-version": "4.10.0",
|
|
294
|
+
"user-agent": "MyT/4.10.0 iPhone10,5 iOS/14.8 CFNetwork/1240.0.4 Darwin/20.6.0",
|
|
295
|
+
"accept-language": "de-DE",
|
|
296
|
+
"x-tme-brand": "TOYOTA",
|
|
297
|
+
},
|
|
298
|
+
data: data,
|
|
299
|
+
})
|
|
300
|
+
.then((res) => {
|
|
301
|
+
this.log.debug(JSON.stringify(res.data));
|
|
302
|
+
return res.data;
|
|
303
|
+
})
|
|
304
|
+
.catch((error) => {
|
|
305
|
+
this.log.error(error);
|
|
306
|
+
if (error.response) {
|
|
307
|
+
this.log.error(JSON.stringify(error.response.data));
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
this.refreshTimeout && clearTimeout(this.refreshTimeout);
|
|
311
|
+
this.refreshTimeout = setTimeout(async () => {
|
|
312
|
+
await this.updateDevices();
|
|
313
|
+
}, 10 * 1000);
|
|
314
|
+
}
|
|
272
315
|
}
|
|
316
|
+
}
|
|
273
317
|
}
|
|
274
318
|
|
|
275
319
|
if (require.main !== module) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
320
|
+
// Export the constructor in compact mode
|
|
321
|
+
/**
|
|
322
|
+
* @param {Partial<utils.AdapterOptions>} [options={}]
|
|
323
|
+
*/
|
|
324
|
+
module.exports = (options) => new Toyota(options);
|
|
281
325
|
} else {
|
|
282
|
-
|
|
283
|
-
|
|
326
|
+
// otherwise start the instance directly
|
|
327
|
+
new Toyota();
|
|
284
328
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.toyota",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Adapter for myT Toyota App",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "TA2k",
|
|
@@ -22,29 +22,28 @@
|
|
|
22
22
|
"url": "https://github.com/TA2k/ioBroker.toyota"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@iobroker/adapter-core": "^2.
|
|
26
|
-
"axios": "^
|
|
25
|
+
"@iobroker/adapter-core": "^2.6.7",
|
|
26
|
+
"axios": "^1.3.4",
|
|
27
27
|
"json-bigint": "^1.0.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@iobroker/testing": "^
|
|
31
|
-
"@types/chai": "^4.
|
|
32
|
-
"@types/chai-as-promised": "^7.1.
|
|
33
|
-
"@types/gulp": "^4.0.
|
|
34
|
-
"@types/mocha": "^
|
|
35
|
-
"@types/node": "^
|
|
30
|
+
"@iobroker/testing": "^4.1.0",
|
|
31
|
+
"@types/chai": "^4.3.4",
|
|
32
|
+
"@types/chai-as-promised": "^7.1.5",
|
|
33
|
+
"@types/gulp": "^4.0.10",
|
|
34
|
+
"@types/mocha": "^10.0.1",
|
|
35
|
+
"@types/node": "^18.15.5",
|
|
36
36
|
"@types/proxyquire": "^1.3.28",
|
|
37
|
-
"@types/sinon": "^10.0.
|
|
38
|
-
"@types/sinon-chai": "^3.2.
|
|
39
|
-
"chai": "^4.3.
|
|
37
|
+
"@types/sinon": "^10.0.13",
|
|
38
|
+
"@types/sinon-chai": "^3.2.9",
|
|
39
|
+
"chai": "^4.3.7",
|
|
40
40
|
"chai-as-promised": "^7.1.1",
|
|
41
|
-
"eslint": "^8.
|
|
42
|
-
"
|
|
43
|
-
"mocha": "^9.1.3",
|
|
41
|
+
"eslint": "^8.36.0",
|
|
42
|
+
"mocha": "^10.2.0",
|
|
44
43
|
"proxyquire": "^2.1.3",
|
|
45
|
-
"sinon": "^
|
|
44
|
+
"sinon": "^15.0.2",
|
|
46
45
|
"sinon-chai": "^3.7.0",
|
|
47
|
-
"typescript": "~
|
|
46
|
+
"typescript": "~5.0.2"
|
|
48
47
|
},
|
|
49
48
|
"main": "main.js",
|
|
50
49
|
"files": [
|