iobroker.device-watcher 2.15.12 → 2.15.14
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 +6 -6
- package/io-package.json +28 -2
- package/main.js +67 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -191,6 +191,12 @@ This adapter would not have been possible without the great work of Christian Be
|
|
|
191
191
|
Placeholder for the next version (at the beginning of the line):
|
|
192
192
|
### **WORK IN PROGRESS**
|
|
193
193
|
-->
|
|
194
|
+
### 2.15.14 (2026-05-13)
|
|
195
|
+
* (arteck) fix high i/o
|
|
196
|
+
|
|
197
|
+
### 2.15.13 (2026-05-13)
|
|
198
|
+
* (arteck) fix new devices
|
|
199
|
+
|
|
194
200
|
### 2.15.12 (2026-05-06)
|
|
195
201
|
* (arteck) fix hueExtended battery check
|
|
196
202
|
|
|
@@ -201,12 +207,6 @@ This adapter would not have been possible without the great work of Christian Be
|
|
|
201
207
|
- (copilot) Adapter requires node.js >= 22 now
|
|
202
208
|
* (arteck) fix adapter crash after delete a device
|
|
203
209
|
|
|
204
|
-
### 2.15.9 (2026-04-22)
|
|
205
|
-
* (arteck) new xsense (v. 0.4.0) structure, plz update before
|
|
206
|
-
|
|
207
|
-
### 2.15.8 (2026-04-18)
|
|
208
|
-
* (arteck) fix cronParserLib.parseExpression message
|
|
209
|
-
|
|
210
210
|
## License
|
|
211
211
|
|
|
212
212
|
MIT License
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "device-watcher",
|
|
4
|
-
"version": "2.15.
|
|
4
|
+
"version": "2.15.14",
|
|
5
5
|
"news": {
|
|
6
|
+
"2.15.14": {
|
|
7
|
+
"en": "fix high i/o",
|
|
8
|
+
"de": "hoch i/o",
|
|
9
|
+
"ru": "фиксировать высокий i/o",
|
|
10
|
+
"pt": "fixar i/o elevado",
|
|
11
|
+
"nl": "fix high i/o",
|
|
12
|
+
"fr": "fixer haut i/o",
|
|
13
|
+
"it": "correzione alta i/o",
|
|
14
|
+
"es": "fijar alto i/o",
|
|
15
|
+
"pl": "fix high i / o",
|
|
16
|
+
"uk": "фіксувати високий i/o",
|
|
17
|
+
"zh-cn": "固定高 i/o"
|
|
18
|
+
},
|
|
19
|
+
"2.15.13": {
|
|
20
|
+
"en": "fix new devices",
|
|
21
|
+
"de": "neue geräte installieren",
|
|
22
|
+
"ru": "ремонт новых устройств",
|
|
23
|
+
"pt": "corrigir novos dispositivos",
|
|
24
|
+
"nl": "nieuwe apparaten herstellen",
|
|
25
|
+
"fr": "correction de nouveaux dispositifs",
|
|
26
|
+
"it": "fissare nuovi dispositivi",
|
|
27
|
+
"es": "nuevos dispositivos",
|
|
28
|
+
"pl": "naprawić nowe urządzenia",
|
|
29
|
+
"uk": "фіксувати нові пристрої",
|
|
30
|
+
"zh-cn": "修复新设备"
|
|
31
|
+
},
|
|
6
32
|
"2.15.12": {
|
|
7
33
|
"en": "fix hueExtended battery check",
|
|
8
34
|
"de": "hueExtended Akku Check",
|
|
@@ -28,7 +54,7 @@
|
|
|
28
54
|
"pl": "fix",
|
|
29
55
|
"uk": "fix",
|
|
30
56
|
"zh-cn": "fix"
|
|
31
|
-
},
|
|
57
|
+
},
|
|
32
58
|
"2.15.5": {
|
|
33
59
|
"en": "fix admin",
|
|
34
60
|
"de": "admin",
|
package/main.js
CHANGED
|
@@ -83,9 +83,16 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
83
83
|
// Interval timer
|
|
84
84
|
this.refreshDataTimeout = null;
|
|
85
85
|
|
|
86
|
+
// Debounce timer for list/datapoint updates triggered by stateChange
|
|
87
|
+
this.listUpdateDebounceTimer = null;
|
|
88
|
+
this.LIST_UPDATE_DEBOUNCE_MS = 5000; // 5 Sekunden Ruhezeit
|
|
89
|
+
|
|
86
90
|
// Check if main function is running
|
|
87
91
|
this.mainRunning = false;
|
|
88
92
|
|
|
93
|
+
// Pending rescan flag (set if a new device was detected while main() was running)
|
|
94
|
+
this.pendingRescan = false;
|
|
95
|
+
|
|
89
96
|
this.on('ready', this.onReady.bind(this));
|
|
90
97
|
this.on('stateChange', this.onStateChange.bind(this));
|
|
91
98
|
this.on('objectChange', this.onObjectChange.bind(this));
|
|
@@ -280,6 +287,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
280
287
|
}
|
|
281
288
|
this.mainRunning = false;
|
|
282
289
|
this.log.debug(`Function finished: ${this.main.name}`);
|
|
290
|
+
|
|
291
|
+
// If a new device was detected while main() was running, trigger a rescan now
|
|
292
|
+
if (this.pendingRescan) {
|
|
293
|
+
this.pendingRescan = false;
|
|
294
|
+
this.log.info(`[main] Pending rescan detected – restarting main() for new device`);
|
|
295
|
+
await this.main();
|
|
296
|
+
}
|
|
283
297
|
} //<--End of main function
|
|
284
298
|
|
|
285
299
|
// If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.
|
|
@@ -302,10 +316,23 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
302
316
|
if (!this.mainRunning) {
|
|
303
317
|
await this.main();
|
|
304
318
|
} else {
|
|
305
|
-
|
|
319
|
+
this.pendingRescan = true;
|
|
306
320
|
}
|
|
307
321
|
} else {
|
|
308
|
-
|
|
322
|
+
// Check if the changed object belongs to a monitored adapter (new device)
|
|
323
|
+
const belongsToMonitoredAdapter = this.adapterSelected.some((adapterKey) =>
|
|
324
|
+
id.toLowerCase().startsWith(`${adapterKey.toLowerCase() }.`)
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
if (belongsToMonitoredAdapter) {
|
|
328
|
+
if (!this.mainRunning) {
|
|
329
|
+
this.log.info(`[onObjectChange] New device detected: ${id} – triggering rescan`);
|
|
330
|
+
await this.main();
|
|
331
|
+
} else {
|
|
332
|
+
this.log.debug(`[onObjectChange] main() is running – rescan for ${id} queued`);
|
|
333
|
+
this.pendingRescan = true;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
309
336
|
}
|
|
310
337
|
}
|
|
311
338
|
} catch (error) {
|
|
@@ -343,6 +370,36 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
343
370
|
}
|
|
344
371
|
}
|
|
345
372
|
|
|
373
|
+
/**
|
|
374
|
+
* Debounced update of all lists and datapoints.
|
|
375
|
+
* Prevents excessive system load on rapid state changes.
|
|
376
|
+
* Waits LIST_UPDATE_DEBOUNCE_MS ms after the last call before executing.
|
|
377
|
+
*/
|
|
378
|
+
scheduleListUpdate() {
|
|
379
|
+
if (this.listUpdateDebounceTimer) {
|
|
380
|
+
this.clearTimeout(this.listUpdateDebounceTimer);
|
|
381
|
+
}
|
|
382
|
+
this.listUpdateDebounceTimer = this.setTimeout(async () => {
|
|
383
|
+
this.listUpdateDebounceTimer = null;
|
|
384
|
+
try {
|
|
385
|
+
await crud.createLists(this);
|
|
386
|
+
await crud.writeDatapoints(this);
|
|
387
|
+
|
|
388
|
+
if (this.configCreateOwnFolder) {
|
|
389
|
+
for (const [adId] of Object.entries(adapterArray)) {
|
|
390
|
+
const adapter = adapterArray[adId];
|
|
391
|
+
if (this.adapterSelected.includes(adapter.adapterKey)) {
|
|
392
|
+
await crud.createLists(this, adId);
|
|
393
|
+
await crud.writeDatapoints(this, adId);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
} catch (error) {
|
|
398
|
+
this.log.error(`[scheduleListUpdate] - ${error}`);
|
|
399
|
+
}
|
|
400
|
+
}, this.LIST_UPDATE_DEBOUNCE_MS);
|
|
401
|
+
}
|
|
402
|
+
|
|
346
403
|
async onStateChange(id, state) {
|
|
347
404
|
if (state) {
|
|
348
405
|
// this.log.debug(`State changed: ${id} changed ${state.val}`);
|
|
@@ -366,6 +423,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
366
423
|
=============================================*/
|
|
367
424
|
if (Array.from(this.listAllDevicesRaw.values()).some((obj) => Object.values(obj).includes(id))) {
|
|
368
425
|
await this.renewDeviceData(id, state);
|
|
426
|
+
|
|
427
|
+
// Debounced update – verhindert Systemlast bei schnellen State-Änderungen
|
|
428
|
+
this.scheduleListUpdate();
|
|
369
429
|
}
|
|
370
430
|
} catch (error) {
|
|
371
431
|
this.log.error(`Issue at state change: ${id}`);
|
|
@@ -2422,6 +2482,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2422
2482
|
this.refreshDataTimeout = null;
|
|
2423
2483
|
}
|
|
2424
2484
|
|
|
2485
|
+
if (this.listUpdateDebounceTimer) {
|
|
2486
|
+
this.clearTimeout(this.listUpdateDebounceTimer);
|
|
2487
|
+
this.listUpdateDebounceTimer = null;
|
|
2488
|
+
}
|
|
2489
|
+
|
|
2425
2490
|
this.log.info('cleaned everything up...');
|
|
2426
2491
|
|
|
2427
2492
|
callback();
|