iobroker.miele-local 0.3.45 → 0.3.46
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 +3 -0
- package/README_de.md +3 -0
- package/io-package.json +14 -14
- package/lib/takt.js +55 -0
- package/main.js +44 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -237,6 +237,9 @@ engineering work of the projects `MieleRESTServer` (akappner),
|
|
|
237
237
|
### **WORK IN PROGRESS**
|
|
238
238
|
-->
|
|
239
239
|
|
|
240
|
+
### 0.3.46
|
|
241
|
+
- (SmarthomeElektroniker) Only the running appliance is polled at the short interval ("Poll interval (active)"); idle appliances keep the idle interval. Until now all appliances were polled at the short interval as soon as one was running - fewer requests to the Miele modules, which serve only one connection at a time
|
|
242
|
+
|
|
240
243
|
### 0.3.45
|
|
241
244
|
- (SmarthomeElektroniker) The last German state ID is gone: `eco.quelle` is now `eco.source`, its value is always English. Existing installations are migrated on start
|
|
242
245
|
- (SmarthomeElektroniker) `statusText`, `programText`, `programPhaseText`, `programTypeText` and `dryingStepText` follow the "German names" option - with the option off they are English (until now they were always German)
|
package/README_de.md
CHANGED
|
@@ -245,6 +245,9 @@ Reverse-Engineering-Arbeit der Projekte `MieleRESTServer` (akappner),
|
|
|
245
245
|
### **WORK IN PROGRESS**
|
|
246
246
|
-->
|
|
247
247
|
|
|
248
|
+
### 0.3.46
|
|
249
|
+
- Nur das laufende Gerät wird im kurzen Takt abgefragt („Abfrageintervall (aktiv)“), Geräte in Ruhe behalten den Ruhetakt. Bisher wurden alle Geräte im kurzen Takt abgefragt, sobald eines lief – weniger Anfragen an die Miele-Module, die nur eine Verbindung gleichzeitig bedienen.
|
|
250
|
+
|
|
248
251
|
### 0.3.45
|
|
249
252
|
- Die letzte deutsche Datenpunkt-ID ist weg: `eco.quelle` heißt jetzt `eco.source`, der Wert ist immer englisch. Vorhandene Installationen ziehen beim Start um.
|
|
250
253
|
- `statusText`, `programText`, `programPhaseText`, `programTypeText` und `dryingStepText` folgen der Option „Deutsche Namen“ - ist sie aus, sind die Texte englisch (bisher immer deutsch).
|
package/io-package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "miele-local",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.46",
|
|
5
5
|
"titleLang": {
|
|
6
6
|
"en": "Miele@local",
|
|
7
7
|
"de": "Miele@local",
|
|
@@ -52,6 +52,19 @@
|
|
|
52
52
|
"readme": "https://github.com/SmarthomeElektroniker/ioBroker.miele-local/blob/main/README.md",
|
|
53
53
|
"loglevel": "info",
|
|
54
54
|
"news": {
|
|
55
|
+
"0.3.46": {
|
|
56
|
+
"en": "Only the running appliance is polled at the short interval, idle appliances keep the idle interval - fewer requests to the Miele modules (until now all appliances were polled at the short interval as soon as one was running)",
|
|
57
|
+
"de": "Nur das laufende Gerät wird im kurzen Takt abgefragt, Geräte in Ruhe behalten den Ruhetakt - weniger Anfragen an die Miele-Module (bisher wurden alle Geräte im kurzen Takt abgefragt, sobald eines lief)",
|
|
58
|
+
"ru": "С коротким интервалом опрашивается только работающий прибор, приборы в покое сохраняют интервал покоя - меньше запросов к модулям Miele (раньше все приборы опрашивались с коротким интервалом, как только работал один)",
|
|
59
|
+
"pt": "Apenas o aparelho em funcionamento é consultado no intervalo curto, aparelhos inativos mantêm o intervalo de repouso - menos pedidos aos módulos Miele (até agora todos eram consultados no intervalo curto assim que um estava a funcionar)",
|
|
60
|
+
"nl": "Alleen het draaiende apparaat wordt met het korte interval opgevraagd, apparaten in rust houden het rustinterval - minder verzoeken aan de Miele-modules (tot nu toe werden alle apparaten kort opgevraagd zodra er één draaide)",
|
|
61
|
+
"fr": "Seul l'appareil en marche est interrogé à l'intervalle court, les appareils au repos gardent l'intervalle de repos - moins de requêtes vers les modules Miele (jusqu'ici tous étaient interrogés à l'intervalle court dès qu'un appareil fonctionnait)",
|
|
62
|
+
"it": "Solo l'elettrodomestico in funzione viene interrogato all'intervallo breve, quelli inattivi mantengono l'intervallo di riposo - meno richieste ai moduli Miele (finora tutti venivano interrogati all'intervallo breve appena uno era in funzione)",
|
|
63
|
+
"es": "Solo el aparato en marcha se consulta con el intervalo corto, los aparatos en reposo mantienen el intervalo de reposo - menos peticiones a los módulos Miele (hasta ahora todos se consultaban con el intervalo corto en cuanto uno funcionaba)",
|
|
64
|
+
"pl": "Tylko pracujące urządzenie jest odpytywane w krótkim interwale, urządzenia w spoczynku zachowują interwał spoczynku - mniej zapytań do modułów Miele (dotąd wszystkie były odpytywane krótko, gdy tylko jedno pracowało)",
|
|
65
|
+
"uk": "З коротким інтервалом опитується лише працюючий прилад, прилади у спокої зберігають інтервал спокою - менше запитів до модулів Miele (досі всі прилади опитувалися з коротким інтервалом, щойно працював один)",
|
|
66
|
+
"zh-cn": "只有正在运行的电器使用短间隔轮询,空闲电器保持空闲间隔 - 减少对 Miele 模块的请求(此前只要有一台在运行,所有电器都按短间隔轮询)"
|
|
67
|
+
},
|
|
55
68
|
"0.3.45": {
|
|
56
69
|
"en": "Only English IDs left: eco.quelle -> eco.source, eco.felderJson -> eco.fieldsJson; settings use English keys (collectorActive, leafStates, energyMeters ...), migrated once on start; text states follow the German names option; background loops never overlap",
|
|
57
70
|
"de": "Nur noch englische IDs: eco.quelle -> eco.source, eco.felderJson -> eco.fieldsJson; Einstellungen mit englischen Namen (collectorActive, leafStates, energyMeters ...), beim Start einmalig übernommen; Textdatenpunkte folgen der Option „Deutsche Namen“; Hintergrundschleifen überlappen nicht mehr",
|
|
@@ -129,19 +142,6 @@
|
|
|
129
142
|
"pl": "README: wskazówki przy nieudanym logowaniu (bloker reklam), przy przenoszeniu na inny system i dlaczego mDNS nic nie znajduje; czytelniejszy komunikat w dzienniku, gdy nie znaleziono urządzenia (#12).",
|
|
130
143
|
"uk": "README: підказки при невдалому вході (блокувальник реклами), при перенесенні на іншу систему та чому mDNS нічого не знаходить; зрозуміліше повідомлення в журналі, якщо пристрій не знайдено (#12).",
|
|
131
144
|
"zh-cn": "README:登录失败(广告拦截器)、迁移到其他系统以及 mDNS 找不到设备原因的提示;未找到设备时日志信息更清晰 (#12)。"
|
|
132
|
-
},
|
|
133
|
-
"0.3.39": {
|
|
134
|
-
"en": "Unknown program or phase IDs are shown as \"Programm 201\" instead of keeping the text of the previous program. Dishwasher program IDs of the G7771 added (#13).",
|
|
135
|
-
"de": "Unbekannte Programm- oder Phasennummern erscheinen als „Programm 201“, statt den Text des vorigen Programms stehen zu lassen. Programmnummern des Geschirrspülers G7771 ergänzt (#13).",
|
|
136
|
-
"ru": "Неизвестные номера программ или фаз отображаются как «Programm 201», а не сохраняют текст предыдущей программы. Добавлены номера программ посудомоечной машины G7771 (#13).",
|
|
137
|
-
"pt": "IDs de programa ou fase desconhecidos aparecem como \"Programm 201\" em vez de manter o texto do programa anterior. Adicionados os IDs de programa da máquina de lavar loiça G7771 (#13).",
|
|
138
|
-
"nl": "Onbekende programma- of fasenummers verschijnen als \"Programm 201\" in plaats van de tekst van het vorige programma te laten staan. Programmanummers van de vaatwasser G7771 toegevoegd (#13).",
|
|
139
|
-
"fr": "Les numéros de programme ou de phase inconnus s'affichent comme « Programm 201 » au lieu de conserver le texte du programme précédent. Numéros de programme du lave-vaisselle G7771 ajoutés (#13).",
|
|
140
|
-
"it": "I numeri di programma o di fase sconosciuti vengono mostrati come \"Programm 201\" invece di mantenere il testo del programma precedente. Aggiunti i numeri di programma della lavastoviglie G7771 (#13).",
|
|
141
|
-
"es": "Los números de programa o fase desconocidos se muestran como \"Programm 201\" en lugar de conservar el texto del programa anterior. Añadidos los números de programa del lavavajillas G7771 (#13).",
|
|
142
|
-
"pl": "Nieznane numery programów lub faz są wyświetlane jako „Programm 201” zamiast pozostawiać tekst poprzedniego programu. Dodano numery programów zmywarki G7771 (#13).",
|
|
143
|
-
"uk": "Невідомі номери програм або фаз відображаються як «Programm 201», а не зберігають текст попередньої програми. Додано номери програм посудомийної машини G7771 (#13).",
|
|
144
|
-
"zh-cn": "未知的程序或阶段编号显示为“Programm 201”,不再保留上一个程序的文本。新增 G7771 洗碗机的程序编号 (#13)。"
|
|
145
145
|
}
|
|
146
146
|
},
|
|
147
147
|
"mode": "daemon",
|
package/lib/takt.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Abfragetakt je Geraet (seit 0.3.46).
|
|
5
|
+
*
|
|
6
|
+
* Bis 0.3.45 galt der kurze Takt fuer ALLE Geraete, sobald eines lief: Backte der Ofen, wurden
|
|
7
|
+
* Wasch- und Spuelmaschine im Minutentakt mitgefragt, obwohl sie aus waren. Ein XKM-Modul bedient
|
|
8
|
+
* nur eine Verbindung gleichzeitig - jede ueberfluessige Frage nimmt der Miele-App einen
|
|
9
|
+
* Zeitschlitz weg. Jetzt hat jedes Geraet seinen eigenen Termin: kurz, solange es laeuft, sonst
|
|
10
|
+
* der Ruhetakt. Die Schleife wacht zum fruehesten Termin auf und fragt nur, wer dran ist.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** Kein Wecken in kuerzeren Abstaenden als diesem - auch wenn mehrere Termine dicht liegen. */
|
|
14
|
+
const MIN_WECKABSTAND_MS = 1000;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Abstand bis zur naechsten Abfrage eines Geraets.
|
|
18
|
+
*
|
|
19
|
+
* @param {{active?: boolean}} dev Geraeteeintrag
|
|
20
|
+
* @param {number} aktivMs Takt im Betrieb
|
|
21
|
+
* @param {number} ruheMs Takt in Ruhe
|
|
22
|
+
* @returns {number} Millisekunden
|
|
23
|
+
*/
|
|
24
|
+
function abstand(dev, aktivMs, ruheMs) {
|
|
25
|
+
return dev && dev.active ? aktivMs : ruheMs;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Ist dieses Geraet jetzt dran? Ein Geraet ohne Termin (gerade gefunden) ist sofort dran.
|
|
30
|
+
*
|
|
31
|
+
* @param {{naechsteAbfrage?: number}} dev Geraeteeintrag
|
|
32
|
+
* @param {number} jetzt Zeitpunkt in ms
|
|
33
|
+
* @returns {boolean} true, wenn es jetzt abgefragt werden soll
|
|
34
|
+
*/
|
|
35
|
+
function istFaellig(dev, jetzt) {
|
|
36
|
+
return (dev.naechsteAbfrage || 0) <= jetzt;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Wann die Schleife wieder aufwachen soll: zum fruehesten Termin aller Geraete.
|
|
41
|
+
*
|
|
42
|
+
* @param {Array<{naechsteAbfrage?: number}>} geraete alle Geraeteeintraege
|
|
43
|
+
* @param {number} jetzt Zeitpunkt in ms
|
|
44
|
+
* @param {number} ruheMs Abstand, wenn (noch) kein Geraet bekannt ist
|
|
45
|
+
* @returns {number} Millisekunden bis zum naechsten Durchgang
|
|
46
|
+
*/
|
|
47
|
+
function weckAbstand(geraete, jetzt, ruheMs) {
|
|
48
|
+
if (!geraete.length) {
|
|
49
|
+
return ruheMs;
|
|
50
|
+
}
|
|
51
|
+
const fruehester = Math.min(...geraete.map(d => d.naechsteAbfrage || 0));
|
|
52
|
+
return Math.max(MIN_WECKABSTAND_MS, fruehester - jetzt);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = { abstand, istFaellig, weckAbstand, MIN_WECKABSTAND_MS };
|
package/main.js
CHANGED
|
@@ -12,6 +12,7 @@ const paket = require('./package.json');
|
|
|
12
12
|
const { MieleCrypto } = require('./lib/crypto');
|
|
13
13
|
const { MieleDeviceApi } = require('./lib/api');
|
|
14
14
|
const { discover, scanSubnet, istMiele } = require('./lib/discovery');
|
|
15
|
+
const takt = require('./lib/takt');
|
|
15
16
|
const cloud = require('./lib/cloud');
|
|
16
17
|
const objdef = require('./lib/objects');
|
|
17
18
|
const namen = require('./lib/names');
|
|
@@ -2164,19 +2165,41 @@ class MieleLocal extends utils.Adapter {
|
|
|
2164
2165
|
this._histCreated[deviceId] = true;
|
|
2165
2166
|
}
|
|
2166
2167
|
|
|
2168
|
+
/**
|
|
2169
|
+
* Abstand bis zur naechsten Abfrage EINES Geraets: kurz, solange es laeuft, sonst der Ruhetakt.
|
|
2170
|
+
*
|
|
2171
|
+
* Bis 0.3.45 galt der kurze Takt fuer ALLE Geraete, sobald eines lief - backte der Ofen,
|
|
2172
|
+
* wurden Wasch- und Spuelmaschine im Minutentakt mitgefragt, obwohl sie aus waren. Ein
|
|
2173
|
+
* XKM-Modul bedient nur eine Verbindung; jede ueberfluessige Frage nimmt der Miele-App
|
|
2174
|
+
* einen Zeitschlitz weg.
|
|
2175
|
+
*
|
|
2176
|
+
* @param dev Geraeteeintrag aus this.devices
|
|
2177
|
+
*/
|
|
2178
|
+
abstandFuer(dev) {
|
|
2179
|
+
return takt.abstand(
|
|
2180
|
+
dev,
|
|
2181
|
+
MieleLocal.intervallMs(this.config.activePollInterval, 5, 1),
|
|
2182
|
+
MieleLocal.intervallMs(this.config.pollInterval, 15, 1),
|
|
2183
|
+
);
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2167
2186
|
schedulePoll(immediate = false) {
|
|
2168
2187
|
if (this.pollTimer) {
|
|
2169
2188
|
this.clearTimeout(this.pollTimer);
|
|
2170
2189
|
}
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2190
|
+
// Geweckt wird zur naechsten faelligen Abfrage irgendeines Geraets; pollAll(true) fragt
|
|
2191
|
+
// dann nur die faelligen. Ein Geraet ohne Termin (neu gefunden) ist sofort faellig.
|
|
2192
|
+
const interval = takt.weckAbstand(
|
|
2193
|
+
Object.values(this.devices),
|
|
2194
|
+
Date.now(),
|
|
2195
|
+
MieleLocal.intervallMs(this.config.pollInterval, 15, 1),
|
|
2196
|
+
);
|
|
2175
2197
|
const run = async () => {
|
|
2176
2198
|
if (this.stopping) {
|
|
2177
2199
|
return;
|
|
2178
2200
|
}
|
|
2179
|
-
|
|
2201
|
+
// Ein sofortiger Durchgang (nach einem Schreibbefehl) fragt alle, sonst nur die faelligen.
|
|
2202
|
+
await this.pollAll(!immediate);
|
|
2180
2203
|
this.schedulePoll(false);
|
|
2181
2204
|
};
|
|
2182
2205
|
const nextDelayMs = immediate ? 100 : interval;
|
|
@@ -2286,7 +2309,7 @@ class MieleLocal extends utils.Adapter {
|
|
|
2286
2309
|
* stauten sich am Modul. Jetzt gibt es nie zwei Laeufe derselben Aufgabe gleichzeitig.
|
|
2287
2310
|
*
|
|
2288
2311
|
* @param {string} name Feld, in dem der Timer steht (fuer clearTimeout in onUnload)
|
|
2289
|
-
* @param {() =>
|
|
2312
|
+
* @param {() => (void | Promise<void>)} aufgabe die Aufgabe; darf ein Promise liefern
|
|
2290
2313
|
* @param {number} abstandMs Pause zwischen Ende eines Laufs und Beginn des naechsten
|
|
2291
2314
|
*/
|
|
2292
2315
|
schleife(name, aufgabe, abstandMs) {
|
|
@@ -3180,9 +3203,20 @@ class MieleLocal extends utils.Adapter {
|
|
|
3180
3203
|
return 1500;
|
|
3181
3204
|
}
|
|
3182
3205
|
|
|
3183
|
-
|
|
3206
|
+
/**
|
|
3207
|
+
* Alle Geraete abfragen - oder nur die, deren Termin gekommen ist (siehe abstandFuer()).
|
|
3208
|
+
*
|
|
3209
|
+
* @param nurFaellige true: Geraete mit spaeterem Termin auslassen
|
|
3210
|
+
*/
|
|
3211
|
+
async pollAll(nurFaellige = false) {
|
|
3184
3212
|
let ok = false;
|
|
3213
|
+
const jetzt = Date.now();
|
|
3185
3214
|
for (const [deviceId, dev] of Object.entries(this.devices)) {
|
|
3215
|
+
if (nurFaellige && !takt.istFaellig(dev, jetzt)) {
|
|
3216
|
+
// Nicht dran - fuer info.connection zaehlt sein letzter Stand.
|
|
3217
|
+
ok = ok || dev.erreichbar === true;
|
|
3218
|
+
continue;
|
|
3219
|
+
}
|
|
3186
3220
|
// Zweiter Anlauf, bevor ein Abruf als Fehler gilt. Das XKM-Modul der Geraete legt im
|
|
3187
3221
|
// laufenden Betrieb sporadisch auf ("read ECONNRESET") oder antwortet kurz mit 404 -
|
|
3188
3222
|
// am 23.08.2026 an der laufenden Waschmaschine mit 21 % der Abrufe gemessen, waehrend
|
|
@@ -3215,6 +3249,9 @@ class MieleLocal extends utils.Adapter {
|
|
|
3215
3249
|
if (fehler) {
|
|
3216
3250
|
await this.setStateAsync(`${deviceId}.info.connected`, { val: false, ack: true });
|
|
3217
3251
|
}
|
|
3252
|
+
dev.erreichbar = !fehler;
|
|
3253
|
+
// Erst nach applyState: dev.active ist dann auf dem Stand dieser Abfrage.
|
|
3254
|
+
dev.naechsteAbfrage = Date.now() + this.abstandFuer(dev);
|
|
3218
3255
|
await this.verbucheAbfrage(deviceId, fehler, wiederholt && !fehler);
|
|
3219
3256
|
}
|
|
3220
3257
|
await this.setStateAsync('info.connection', { val: ok, ack: true });
|
package/package.json
CHANGED