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 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.12",
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
- return;
319
+ this.pendingRescan = true;
306
320
  }
307
321
  } else {
308
- return;
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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.device-watcher",
3
- "version": "2.15.12",
3
+ "version": "2.15.14",
4
4
  "description": "Watchdog for devices",
5
5
  "author": "Christian Behrends <mail@christian-behrends.de>",
6
6
  "contributors": [