iobroker.easee 2.0.0-alpha.1 → 2.0.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/README.md +7 -4
- package/admin/i18n/de/translations.json +11 -0
- package/admin/i18n/en/translations.json +11 -0
- package/admin/i18n/es/translations.json +11 -0
- package/admin/i18n/fr/translations.json +11 -0
- package/admin/i18n/it/translations.json +11 -0
- package/admin/i18n/nl/translations.json +11 -0
- package/admin/i18n/pl/translations.json +11 -0
- package/admin/i18n/pt/translations.json +11 -0
- package/admin/i18n/ru/translations.json +11 -0
- package/admin/i18n/uk/translations.json +11 -0
- package/admin/i18n/zh-cn/translations.json +11 -0
- package/admin/jsonConfig.json +73 -0
- package/admin/words.js +23 -12
- package/io-package.json +54 -1
- package/lib/enum.js +4 -4
- package/lib/observations.js +89 -0
- package/lib/signalr-http-client.js +83 -0
- package/main.js +1027 -186
- package/package.json +4 -3
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const CHARGER_STATE_OBSERVATION_IDS = [
|
|
4
|
+
46, 48, 68, 80, 96, 102, 103, 109, 111, 112, 113, 114, 120, 122, 124, 132,
|
|
5
|
+
182, 183, 184, 185, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 250,
|
|
6
|
+
];
|
|
7
|
+
|
|
8
|
+
const STATE_FIELDS_BY_OBSERVATION_ID = {
|
|
9
|
+
46: "ledMode",
|
|
10
|
+
48: "dynamicChargerCurrent",
|
|
11
|
+
68: "wiFiAPEnabled",
|
|
12
|
+
80: "chargerFirmware",
|
|
13
|
+
96: "reasonForNoCurrent",
|
|
14
|
+
102: "smartCharging",
|
|
15
|
+
103: "cableLocked",
|
|
16
|
+
109: "chargerOpMode",
|
|
17
|
+
111: "dynamicCircuitCurrentP1",
|
|
18
|
+
112: "dynamicCircuitCurrentP2",
|
|
19
|
+
113: "dynamicCircuitCurrentP3",
|
|
20
|
+
114: "outputCurrent",
|
|
21
|
+
120: "totalPower",
|
|
22
|
+
122: "energyPerHour",
|
|
23
|
+
124: "lifetimeEnergy",
|
|
24
|
+
132: "wiFiRSSI",
|
|
25
|
+
182: "inCurrentT2",
|
|
26
|
+
183: "inCurrentT3",
|
|
27
|
+
184: "inCurrentT4",
|
|
28
|
+
185: "inCurrentT5",
|
|
29
|
+
190: "inVoltageT1T2",
|
|
30
|
+
191: "inVoltageT1T3",
|
|
31
|
+
192: "inVoltageT1T4",
|
|
32
|
+
193: "inVoltageT1T5",
|
|
33
|
+
194: "inVoltageT2T3",
|
|
34
|
+
195: "inVoltageT2T4",
|
|
35
|
+
196: "inVoltageT2T5",
|
|
36
|
+
197: "inVoltageT3T4",
|
|
37
|
+
198: "inVoltageT3T5",
|
|
38
|
+
199: "inVoltageT4T5",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const SUPPLY_VOLTAGE_FIELDS = [
|
|
42
|
+
"inVoltageT2T3",
|
|
43
|
+
"inVoltageT1T3",
|
|
44
|
+
"inVoltageT1T4",
|
|
45
|
+
"inVoltageT1T5",
|
|
46
|
+
"inVoltageT2T4",
|
|
47
|
+
"inVoltageT2T5",
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
function observationsToChargerState(responseData) {
|
|
51
|
+
const observations = Array.isArray(responseData?.observations)
|
|
52
|
+
? responseData.observations
|
|
53
|
+
: [];
|
|
54
|
+
/** @type {Record<string, any>} */
|
|
55
|
+
const chargerState = Object.fromEntries(
|
|
56
|
+
Object.values(STATE_FIELDS_BY_OBSERVATION_ID).map((field) => [field, null]),
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
for (const observation of observations) {
|
|
60
|
+
const field = STATE_FIELDS_BY_OBSERVATION_ID[observation.id];
|
|
61
|
+
if (field !== undefined) {
|
|
62
|
+
chargerState[field] = observation.value;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const cloudObservation = observations.find(
|
|
67
|
+
(observation) => observation.id === 250,
|
|
68
|
+
);
|
|
69
|
+
if (cloudObservation) {
|
|
70
|
+
chargerState.isOnline = Boolean(cloudObservation.value);
|
|
71
|
+
}
|
|
72
|
+
chargerState.voltage = null;
|
|
73
|
+
for (const field of SUPPLY_VOLTAGE_FIELDS) {
|
|
74
|
+
const value = chargerState[field];
|
|
75
|
+
if (
|
|
76
|
+
typeof value === "number" &&
|
|
77
|
+
Number.isFinite(value) &&
|
|
78
|
+
value >= 100 &&
|
|
79
|
+
value <= 300
|
|
80
|
+
) {
|
|
81
|
+
chargerState.voltage = value;
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return chargerState;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = { CHARGER_STATE_OBSERVATION_IDS, observationsToChargerState };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const axios = require("axios").default;
|
|
4
|
+
const signalR = require("@microsoft/signalr");
|
|
5
|
+
const { CookieJar } = require("tough-cookie");
|
|
6
|
+
|
|
7
|
+
function hasHeader(headers, name) {
|
|
8
|
+
return Object.keys(headers).some(
|
|
9
|
+
(headerName) => headerName.toLowerCase() === name.toLowerCase(),
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class AxiosSignalRHttpClient extends signalR.HttpClient {
|
|
14
|
+
/** @param {any} [httpClient] */
|
|
15
|
+
constructor(httpClient = axios) {
|
|
16
|
+
super();
|
|
17
|
+
this.httpClient = httpClient;
|
|
18
|
+
this.cookieJar = new CookieJar();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async send(request) {
|
|
22
|
+
if (!request.url) {
|
|
23
|
+
throw new Error("SignalR HTTP request URL is missing");
|
|
24
|
+
}
|
|
25
|
+
const headers = { ...request.headers };
|
|
26
|
+
const cookie = this.cookieJar.getCookieStringSync(request.url);
|
|
27
|
+
if (cookie && !hasHeader(headers, "cookie")) {
|
|
28
|
+
headers.Cookie = cookie;
|
|
29
|
+
}
|
|
30
|
+
const cancelSource = axios.CancelToken.source();
|
|
31
|
+
const abortHandler = () =>
|
|
32
|
+
cancelSource.cancel("SignalR HTTP request aborted");
|
|
33
|
+
if (request.abortSignal) {
|
|
34
|
+
request.abortSignal.onabort = abortHandler;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const response = await this.httpClient.request({
|
|
38
|
+
method: request.method || "GET",
|
|
39
|
+
url: request.url,
|
|
40
|
+
headers,
|
|
41
|
+
data: request.content,
|
|
42
|
+
timeout: request.timeout,
|
|
43
|
+
cancelToken: cancelSource.token,
|
|
44
|
+
responseType:
|
|
45
|
+
request.responseType === "arraybuffer" ? "arraybuffer" : "text",
|
|
46
|
+
transformResponse: [(data) => data],
|
|
47
|
+
validateStatus: () => true,
|
|
48
|
+
});
|
|
49
|
+
for (const setCookie of response.headers?.["set-cookie"] || []) {
|
|
50
|
+
await this.cookieJar.setCookie(setCookie, request.url, {
|
|
51
|
+
ignoreError: true,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
let content = response.data;
|
|
55
|
+
if (Buffer.isBuffer(content) && request.responseType === "arraybuffer") {
|
|
56
|
+
content = content.buffer.slice(
|
|
57
|
+
content.byteOffset,
|
|
58
|
+
content.byteOffset + content.byteLength,
|
|
59
|
+
);
|
|
60
|
+
} else if (
|
|
61
|
+
typeof content !== "string" &&
|
|
62
|
+
request.responseType !== "arraybuffer"
|
|
63
|
+
) {
|
|
64
|
+
content = content == null ? "" : JSON.stringify(content);
|
|
65
|
+
}
|
|
66
|
+
return new signalR.HttpResponse(
|
|
67
|
+
response.status,
|
|
68
|
+
response.statusText,
|
|
69
|
+
content,
|
|
70
|
+
);
|
|
71
|
+
} finally {
|
|
72
|
+
if (request.abortSignal?.onabort === abortHandler) {
|
|
73
|
+
request.abortSignal.onabort = null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
getCookieString(url) {
|
|
79
|
+
return this.cookieJar.getCookieStringSync(url);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
module.exports = AxiosSignalRHttpClient;
|