iobroker.toyota 0.2.0 → 0.2.5
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/admin/index_m.html +18 -12
- package/admin/toyota.png +0 -0
- package/admin/words.js +63 -50
- package/io-package.json +12 -3
- package/lib/adapter-config.d.ts +6 -6
- package/lib/tools.js +51 -49
- package/main.js +519 -139
- package/package.json +10 -19
- package/lib/json2iob.js +0 -252
package/admin/index_m.html
CHANGED
|
@@ -20,18 +20,18 @@
|
|
|
20
20
|
function load(settings, onChange) {
|
|
21
21
|
// example: select elements with id=key and class=value and insert value
|
|
22
22
|
if (!settings) return;
|
|
23
|
-
$(
|
|
23
|
+
$('.value').each(function () {
|
|
24
24
|
var $key = $(this);
|
|
25
|
-
var id = $key.attr(
|
|
26
|
-
if ($key.attr(
|
|
25
|
+
var id = $key.attr('id');
|
|
26
|
+
if ($key.attr('type') === 'checkbox') {
|
|
27
27
|
// do not call onChange direct, because onChange could expect some arguments
|
|
28
|
-
$key.prop(
|
|
28
|
+
$key.prop('checked', settings[id]).on('change', () => onChange());
|
|
29
29
|
} else {
|
|
30
30
|
// do not call onChange direct, because onChange could expect some arguments
|
|
31
31
|
$key
|
|
32
32
|
.val(settings[id])
|
|
33
|
-
.on(
|
|
34
|
-
.on(
|
|
33
|
+
.on('change', () => onChange())
|
|
34
|
+
.on('keyup', () => onChange());
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
37
|
onChange(false);
|
|
@@ -43,14 +43,14 @@
|
|
|
43
43
|
function save(callback) {
|
|
44
44
|
// example: select elements with class=value and build settings object
|
|
45
45
|
var obj = {};
|
|
46
|
-
$(
|
|
46
|
+
$('.value').each(function () {
|
|
47
47
|
var $this = $(this);
|
|
48
|
-
if ($this.attr(
|
|
49
|
-
obj[$this.attr(
|
|
50
|
-
} else if ($this.attr(
|
|
51
|
-
obj[$this.attr(
|
|
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
52
|
} else {
|
|
53
|
-
obj[$this.attr(
|
|
53
|
+
obj[$this.attr('id')] = $this.val();
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
callback(obj);
|
|
@@ -95,6 +95,12 @@
|
|
|
95
95
|
<label for="interval" class="translate">Update interval in minutes</label>
|
|
96
96
|
</div>
|
|
97
97
|
</div>
|
|
98
|
+
<div class="row">
|
|
99
|
+
<div class="col s6 input-field">
|
|
100
|
+
<input type="checkbox" class="value" id="fetchTrips" />
|
|
101
|
+
<label for="fetchTrips" class="translate">Fetch Trip Data</label>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
98
104
|
</div>
|
|
99
105
|
</body>
|
|
100
106
|
</html>
|
package/admin/toyota.png
CHANGED
|
Binary file
|
package/admin/words.js
CHANGED
|
@@ -1,53 +1,66 @@
|
|
|
1
1
|
/*global systemDictionary:true */
|
|
2
|
-
|
|
2
|
+
'use strict';
|
|
3
3
|
|
|
4
4
|
systemDictionary = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
5
|
+
'toyota adapter settings': {
|
|
6
|
+
en: 'Adapter settings for toyota',
|
|
7
|
+
de: 'Adaptereinstellungen für toyota',
|
|
8
|
+
ru: 'Настройки адаптера для toyota',
|
|
9
|
+
pt: 'Configurações do adaptador para toyota',
|
|
10
|
+
nl: 'Adapterinstellingen voor toyota',
|
|
11
|
+
fr: "Paramètres d'adaptateur pour toyota",
|
|
12
|
+
it: "Impostazioni dell'adattatore per toyota",
|
|
13
|
+
es: 'Ajustes del adaptador para toyota',
|
|
14
|
+
pl: 'Ustawienia adaptera dla toyota',
|
|
15
|
+
'zh-cn': 'toyota的适配器设置',
|
|
16
|
+
},
|
|
17
|
+
'App Email': {
|
|
18
|
+
en: 'App Email',
|
|
19
|
+
de: 'App-E-Mail',
|
|
20
|
+
ru: 'Электронная почта приложения',
|
|
21
|
+
pt: 'Email do aplicativo',
|
|
22
|
+
nl: 'App-e-mail',
|
|
23
|
+
fr: "Courriel de l'application",
|
|
24
|
+
it: "E-mail dell'app",
|
|
25
|
+
es: 'Correo electrónico de la aplicación',
|
|
26
|
+
pl: 'E-mail aplikacji',
|
|
27
|
+
'zh-cn': '应用电子邮件',
|
|
28
|
+
},
|
|
29
|
+
'App Password': {
|
|
30
|
+
en: 'App Password',
|
|
31
|
+
de: 'App-Passwort',
|
|
32
|
+
ru: 'Пароль приложения',
|
|
33
|
+
pt: 'Senha de app',
|
|
34
|
+
nl: 'App-wachtwoord',
|
|
35
|
+
fr: "Mot de passe de l'application",
|
|
36
|
+
it: "Password dell'app",
|
|
37
|
+
es: 'Contraseña de la aplicación',
|
|
38
|
+
pl: 'Hasło do aplikacji',
|
|
39
|
+
'zh-cn': '应用密码',
|
|
40
|
+
},
|
|
41
|
+
'Update interval (in minutes)': {
|
|
42
|
+
en: 'Update interval (in minutes)',
|
|
43
|
+
de: 'Aktualisierungsintervall (in Minuten)',
|
|
44
|
+
ru: 'Интервал обновления (в минутах)',
|
|
45
|
+
pt: 'Intervalo de atualização (em minutos)',
|
|
46
|
+
nl: 'Update-interval (in minuten)',
|
|
47
|
+
fr: 'Intervalle de mise à jour (en minutes)',
|
|
48
|
+
it: 'Intervallo di aggiornamento (in minuti)',
|
|
49
|
+
es: 'Intervalo de actualización (en minutos)',
|
|
50
|
+
pl: 'Interwał aktualizacji (w minutach)',
|
|
51
|
+
'zh-cn': '更新间隔(分钟)',
|
|
52
|
+
},
|
|
53
|
+
'Fetch Trips': {
|
|
54
|
+
en: 'Fetch Trip Data',
|
|
55
|
+
de: 'Trip Daten abrufen',
|
|
56
|
+
ru: 'Получить данные Trip',
|
|
57
|
+
pt: 'Dados de viagem',
|
|
58
|
+
nl: 'Reisgegevens ophalen',
|
|
59
|
+
fr: 'Récupération des données de voyage',
|
|
60
|
+
it: 'Dati di viaggio a pagamento',
|
|
61
|
+
es: 'Datos de viaje',
|
|
62
|
+
pl: 'Pobierz dane dotyczące podróży',
|
|
63
|
+
uk: 'Fetch Trip Дані',
|
|
64
|
+
'zh-cn': '获取 Trip 数据',
|
|
65
|
+
},
|
|
66
|
+
};
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "toyota",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.5",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.2.5": {
|
|
7
|
+
"en": "Add option to disable trip fetching",
|
|
8
|
+
"de": "Option zum Deaktivieren des Abrufs von Trips hinzugefügt"
|
|
9
|
+
},
|
|
10
|
+
"0.2.1": {
|
|
11
|
+
"en": "Fix toyota endpoint",
|
|
12
|
+
"de": "Fix toyota Endpunkt"
|
|
13
|
+
},
|
|
6
14
|
"0.2.0": {
|
|
7
15
|
"en": "added Lexus support",
|
|
8
16
|
"de": "Lexus Unterstützung hinzugefügt"
|
|
@@ -71,7 +79,7 @@
|
|
|
71
79
|
"materialize": true,
|
|
72
80
|
"plugins": {
|
|
73
81
|
"sentry": {
|
|
74
|
-
"dsn": "https://
|
|
82
|
+
"dsn": "https://3b9187d0bc8b4eb7974c1558bf68acdd@sentry.iobroker.net/167"
|
|
75
83
|
}
|
|
76
84
|
},
|
|
77
85
|
"dependencies": [
|
|
@@ -91,7 +99,8 @@
|
|
|
91
99
|
"username": "",
|
|
92
100
|
"password": "",
|
|
93
101
|
"type": "toyota",
|
|
94
|
-
"interval": 10
|
|
102
|
+
"interval": 10,
|
|
103
|
+
"fetchTrips": false
|
|
95
104
|
},
|
|
96
105
|
"objects": [],
|
|
97
106
|
"instanceObjects": [
|
package/lib/adapter-config.d.ts
CHANGED
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
// using the actual properties present in io-package.json
|
|
3
3
|
// in order to provide typings for adapter.config properties
|
|
4
4
|
|
|
5
|
-
import { native } from
|
|
5
|
+
import { native } from '../io-package.json';
|
|
6
6
|
|
|
7
7
|
type _AdapterConfig = typeof native;
|
|
8
8
|
|
|
9
9
|
// Augment the globally declared type ioBroker.AdapterConfig
|
|
10
10
|
declare global {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
11
|
+
namespace ioBroker {
|
|
12
|
+
interface AdapterConfig extends _AdapterConfig {
|
|
13
|
+
// Do not enter anything here!
|
|
15
14
|
}
|
|
15
|
+
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
// this is required so the above AdapterConfig is found by TypeScript / type checking
|
|
19
|
-
export {};
|
|
19
|
+
export {};
|
package/lib/tools.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const axios = require(
|
|
1
|
+
const axios = require('axios').default;
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Tests whether the given variable is a real object and not an Array
|
|
@@ -6,11 +6,11 @@ const axios = require("axios").default;
|
|
|
6
6
|
* @returns {it is Record<string, any>}
|
|
7
7
|
*/
|
|
8
8
|
function isObject(it) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
// This is necessary because:
|
|
10
|
+
// typeof null === 'object'
|
|
11
|
+
// typeof [] === 'object'
|
|
12
|
+
// [] instanceof Object === true
|
|
13
|
+
return Object.prototype.toString.call(it) === '[object Object]';
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -19,8 +19,8 @@ function isObject(it) {
|
|
|
19
19
|
* @returns {it is any[]}
|
|
20
20
|
*/
|
|
21
21
|
function isArray(it) {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
if (typeof Array.isArray === 'function') return Array.isArray(it);
|
|
23
|
+
return Object.prototype.toString.call(it) === '[object Array]';
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -31,16 +31,16 @@ function isArray(it) {
|
|
|
31
31
|
* @returns {Promise<string>}
|
|
32
32
|
*/
|
|
33
33
|
async function translateText(text, targetLang, yandexApiKey) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
if (targetLang === 'en') {
|
|
35
|
+
return text;
|
|
36
|
+
} else if (!text) {
|
|
37
|
+
return '';
|
|
38
|
+
}
|
|
39
|
+
if (yandexApiKey) {
|
|
40
|
+
return translateYandex(text, targetLang, yandexApiKey);
|
|
41
|
+
} else {
|
|
42
|
+
return translateGoogle(text, targetLang);
|
|
43
|
+
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
@@ -51,19 +51,21 @@ async function translateText(text, targetLang, yandexApiKey) {
|
|
|
51
51
|
* @returns {Promise<string>}
|
|
52
52
|
*/
|
|
53
53
|
async function translateYandex(text, targetLang, apiKey) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
} catch (e) {
|
|
65
|
-
throw new Error(`Could not translate to "${targetLang}": ${e}`);
|
|
54
|
+
if (targetLang === 'zh-cn') {
|
|
55
|
+
targetLang = 'zh';
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(
|
|
59
|
+
text,
|
|
60
|
+
)}&lang=en-${targetLang}`;
|
|
61
|
+
const response = await axios({ url, timeout: 15000 });
|
|
62
|
+
if (response.data && response.data.text && isArray(response.data.text)) {
|
|
63
|
+
return response.data.text[0];
|
|
66
64
|
}
|
|
65
|
+
throw new Error('Invalid response for translate request');
|
|
66
|
+
} catch (e) {
|
|
67
|
+
throw new Error(`Could not translate to "${targetLang}": ${e}`);
|
|
68
|
+
}
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
/**
|
|
@@ -73,27 +75,27 @@ async function translateYandex(text, targetLang, apiKey) {
|
|
|
73
75
|
* @returns {Promise<string>}
|
|
74
76
|
*/
|
|
75
77
|
async function translateGoogle(text, targetLang) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
78
|
+
try {
|
|
79
|
+
const url = `http://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodeURIComponent(
|
|
80
|
+
text,
|
|
81
|
+
)}&ie=UTF-8&oe=UTF-8`;
|
|
82
|
+
const response = await axios({ url, timeout: 15000 });
|
|
83
|
+
if (isArray(response.data)) {
|
|
84
|
+
// we got a valid response
|
|
85
|
+
return response.data[0][0][0];
|
|
86
|
+
}
|
|
87
|
+
throw new Error('Invalid response for translate request');
|
|
88
|
+
} catch (e) {
|
|
89
|
+
if (e.response && e.response.status === 429) {
|
|
90
|
+
throw new Error(`Could not translate to "${targetLang}": Rate-limited by Google Translate`);
|
|
91
|
+
} else {
|
|
92
|
+
throw new Error(`Could not translate to "${targetLang}": ${e}`);
|
|
92
93
|
}
|
|
94
|
+
}
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
module.exports = {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
isArray,
|
|
99
|
+
isObject,
|
|
100
|
+
translateText,
|
|
99
101
|
};
|