iobroker.device-watcher 2.15.11 → 2.15.13
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 -7
- package/io-package.json +38 -77
- package/lib/crud.js +21 -11
- package/main.js +126 -51
- package/package.json +3 -3
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.13 (2026-05-13)
|
|
195
|
+
* (arteck) fix new devices
|
|
196
|
+
|
|
197
|
+
### 2.15.12 (2026-05-06)
|
|
198
|
+
* (arteck) fix hueExtended battery check
|
|
199
|
+
|
|
194
200
|
### 2.15.11 (2026-05-06)
|
|
195
201
|
* (arteck)
|
|
196
202
|
|
|
@@ -201,13 +207,6 @@ This adapter would not have been possible without the great work of Christian Be
|
|
|
201
207
|
### 2.15.9 (2026-04-22)
|
|
202
208
|
* (arteck) new xsense (v. 0.4.0) structure, plz update before
|
|
203
209
|
|
|
204
|
-
### 2.15.8 (2026-04-18)
|
|
205
|
-
* (arteck) fix cronParserLib.parseExpression message
|
|
206
|
-
|
|
207
|
-
### 2.15.7 (2026-04-18)
|
|
208
|
-
* (arteck) fix matter
|
|
209
|
-
* (arteck) fix cronParserLib.parseExpression message
|
|
210
|
-
|
|
211
210
|
## License
|
|
212
211
|
|
|
213
212
|
MIT License
|
package/io-package.json
CHANGED
|
@@ -1,85 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "device-watcher",
|
|
4
|
-
"version": "2.15.
|
|
4
|
+
"version": "2.15.13",
|
|
5
5
|
"news": {
|
|
6
|
+
"2.15.13": {
|
|
7
|
+
"en": "fix new devices",
|
|
8
|
+
"de": "neue geräte installieren",
|
|
9
|
+
"ru": "ремонт новых устройств",
|
|
10
|
+
"pt": "corrigir novos dispositivos",
|
|
11
|
+
"nl": "nieuwe apparaten herstellen",
|
|
12
|
+
"fr": "correction de nouveaux dispositifs",
|
|
13
|
+
"it": "fissare nuovi dispositivi",
|
|
14
|
+
"es": "nuevos dispositivos",
|
|
15
|
+
"pl": "naprawić nowe urządzenia",
|
|
16
|
+
"uk": "фіксувати нові пристрої",
|
|
17
|
+
"zh-cn": "修复新设备"
|
|
18
|
+
},
|
|
19
|
+
"2.15.12": {
|
|
20
|
+
"en": "fix hueExtended battery check",
|
|
21
|
+
"de": "hueExtended Akku Check",
|
|
22
|
+
"ru": "проверка батареи Extended battery check",
|
|
23
|
+
"pt": "corrigir matizExtended verificação da bateria",
|
|
24
|
+
"nl": "fix hueExtended batterijcontrole",
|
|
25
|
+
"fr": "fix hueVérification étendue de la batterie",
|
|
26
|
+
"it": "correggere il controllo della batteria estesa",
|
|
27
|
+
"es": "hue de fijaciónComprobar la batería",
|
|
28
|
+
"pl": "fix hueExtended kontrola baterii",
|
|
29
|
+
"uk": "fix hueExtended перевірка батареї",
|
|
30
|
+
"zh-cn": "修复 hue 扩展电池检查"
|
|
31
|
+
},
|
|
6
32
|
"2.15.11": {
|
|
7
|
-
"en": "",
|
|
8
|
-
"de": "",
|
|
9
|
-
"ru": "",
|
|
10
|
-
"pt": "",
|
|
11
|
-
"nl": "",
|
|
12
|
-
"fr": "",
|
|
13
|
-
"it": "",
|
|
14
|
-
"es": "",
|
|
15
|
-
"pl": "",
|
|
16
|
-
"uk": "",
|
|
17
|
-
"zh-cn": ""
|
|
18
|
-
},
|
|
19
|
-
"2.15.10": {
|
|
20
|
-
"en": "Adapter requires node.js >= 22 now\nfix adapter crash after delete a device",
|
|
21
|
-
"de": "Adapter benötigt node.js >= 22 jetzt\nfix adapter crash nach dem löschen eines geräts",
|
|
22
|
-
"ru": "Адаптер требует node.js >= 22 сейчас\nисправить сбой адаптера после удаления устройства",
|
|
23
|
-
"pt": "Adaptador requer nod.js >= 22 agora\ncorrigir falha do adaptador após apagar um dispositivo",
|
|
24
|
-
"nl": "Voor de adapter zijn node.js < 22 nu nodig\nfix adapter crash na het verwijderen van een apparaat",
|
|
25
|
-
"fr": "Adaptateur nécessite node.js >= 22 maintenant\ncorrection du crash de l'adaptateur après suppression d'un périphérique",
|
|
26
|
-
"it": "Adattatore richiede node.js >= 22 ora\nfissare l'arresto dell'adattatore dopo eliminare un dispositivo",
|
|
27
|
-
"es": "Adaptador requiere node.js ю= 22 ahora\najuste de bloqueo del adaptador después de eliminar un dispositivo",
|
|
28
|
-
"pl": "Adapter wymaga node.js > = 22\nnaprawić awarię adaptera po usunięciu urządzenia",
|
|
29
|
-
"uk": "Адаптер вимагає node.js >= 22 тепер\nвиправлено аварійний перехід після видалення пристрою",
|
|
30
|
-
"zh-cn": "适配器需要节点.js 现在22\n删除设备后修复适配器崩溃"
|
|
31
|
-
},
|
|
32
|
-
"2.15.9": {
|
|
33
|
-
"en": "new xsense (v. 0.4.0) structure, plz update before",
|
|
34
|
-
"de": "neue xsense (v. 0.4.0) struktur, plz update vor",
|
|
35
|
-
"ru": "новая структура xsense (v. 0.4.0), обновление plz до",
|
|
36
|
-
"pt": "nova estrutura xsense (v. 0.4.0), atualização plz antes",
|
|
37
|
-
"nl": "nieuwe xsense (v. 0.4.0) structuur, plz update voor",
|
|
38
|
-
"fr": "nouvelle structure xsense (v. 0.4.0), mise à jour plz",
|
|
39
|
-
"it": "nuova struttura xsense (v. 0.4.0), aggiornamento plz prima",
|
|
40
|
-
"es": "nueva estructura xsense (v. 0.4.0)",
|
|
41
|
-
"pl": "nowa struktura xsense (v. 0.4.0), aktualizacja plz przed",
|
|
42
|
-
"uk": "новий xsense (v. 0.4.0) структура, оновлення plz перед",
|
|
43
|
-
"zh-cn": "新的 xsense (v. 04. 0) 结构, plz 更新前"
|
|
44
|
-
},
|
|
45
|
-
"2.15.8": {
|
|
46
|
-
"en": "fix cronParserLib.parseExpression message",
|
|
47
|
-
"de": "cronParserLib.parseExpressionsnachricht",
|
|
48
|
-
"ru": "исправить сообщение cronParserLib.parse",
|
|
49
|
-
"pt": "corrigir cronParserLib.parseExpression message",
|
|
50
|
-
"nl": "fix cronParserLib.parseExpressiebericht",
|
|
51
|
-
"fr": "correction du message cronParserLib.parseExpression",
|
|
52
|
-
"it": "correzione cronParserLib.parseExpression messaggio",
|
|
53
|
-
"es": "fijar cronParserLib.parse",
|
|
54
|
-
"pl": "naprawić wiadomość cronParserLib.parseExpression",
|
|
55
|
-
"uk": "виправлено cronParserLib.parseExpression повідомлення",
|
|
56
|
-
"zh-cn": "修补 cronParserLib.parsepression 信件"
|
|
57
|
-
},
|
|
58
|
-
"2.15.7": {
|
|
59
|
-
"en": "fix matter \n",
|
|
60
|
-
"de": "fixkosten\n",
|
|
61
|
-
"ru": "исправлять\n",
|
|
62
|
-
"pt": "corrigir a matéria\n",
|
|
63
|
-
"nl": "fix materie\n",
|
|
64
|
-
"fr": "fixer la matière\n",
|
|
65
|
-
"it": "risolvere la questione\n",
|
|
66
|
-
"es": "arregla la materia\n",
|
|
67
|
-
"pl": "materia stabilna\n",
|
|
68
|
-
"uk": "фіксувати матерію\n",
|
|
69
|
-
"zh-cn": "固定事项\n"
|
|
70
|
-
},
|
|
71
|
-
"2.15.6": {
|
|
72
|
-
"en": "Adapter requires admin >= 7.7.22 now\nfix instanz restart\nfix cronParserLib.parseExpression message\nfix group in zigbee2mqtt",
|
|
73
|
-
"de": "Adapter benötigt admin >= 7.7.22 jetzt\ninstanz restart\ncronParserLib.parseExpressionsnachricht\nfix group in zigbee2mqtt",
|
|
74
|
-
"ru": "Адаптер требует администратора >= 7.7.22\nвосстановление instanz\nисправить сообщение cronParserLib.parse\nфиксированная группа в zigbee2mqtt",
|
|
75
|
-
"pt": "Adaptador requer admin >= 7.7.22 agora\ncorrigir instanz reiniciar\ncorrigir cronParserLib.parseExpression message\ngrupo de correção em zigbee2mqtt",
|
|
76
|
-
"nl": "Adapter vereist admin < 7.7.22 nu\nfix instanz herstart\nfix cronParserLib.parseExpressiebericht\nfix groep in zigbee2mqtt",
|
|
77
|
-
"fr": "Adaptateur nécessite admin >= 7.7.22 maintenant\ncorrection du redémarrage de l'instanz\ncorrection du message cronParserLib.parseExpression\nfixer le groupe dans zigbee2mqtt",
|
|
78
|
-
"it": "Adattatore richiede admin >= 7.7.22 ora\nfix instanz riavvio\ncorrezione cronParserLib.parseExpression messaggio\ngruppo di correzione in zigbee2mqt",
|
|
79
|
-
"es": "El adaptador requiere administrador= 7.7.22 ahora\nfijación instanz restart\nfijar cronParserLib.parse\ngrupo de fijación en zigbee2mqt",
|
|
80
|
-
"pl": "Adapter wymaga admin > = 7.7.22\nfix instanz restart\nnaprawić wiadomość cronParserLib.parseExpression\nfix group in zigbee2mqtt",
|
|
81
|
-
"uk": "Адаптер вимагає адмін >= 7.7.22 тепер\nвиправити instanz перезавантаження\nвиправлено cronParserLib.parseExpression повідомлення\nфіксувати групу в zigbee2mqtt",
|
|
82
|
-
"zh-cn": "适任者需要管理员 \\ 7.7.22 现在\n修复即时状态重新启动\n修补 cronParserLib.parsepression 信件\n以zigbee2mqtt为单位的固定组"
|
|
33
|
+
"en": "fix",
|
|
34
|
+
"de": "fix",
|
|
35
|
+
"ru": "fix",
|
|
36
|
+
"pt": "fix",
|
|
37
|
+
"nl": "fix",
|
|
38
|
+
"fr": "fix",
|
|
39
|
+
"it": "fix",
|
|
40
|
+
"es": "fix",
|
|
41
|
+
"pl": "fix",
|
|
42
|
+
"uk": "fix",
|
|
43
|
+
"zh-cn": "fix"
|
|
83
44
|
},
|
|
84
45
|
"2.15.5": {
|
|
85
46
|
"en": "fix admin",
|
package/lib/crud.js
CHANGED
|
@@ -1204,18 +1204,28 @@ async function createData(adaptr, i) {
|
|
|
1204
1204
|
deviceBatteryState = await tools.getInitValue(adaptr, deviceBatteryStateDP);
|
|
1205
1205
|
}
|
|
1206
1206
|
break;
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1207
|
+
case 'hueExt':
|
|
1208
|
+
// hue-extended: battery is at currDeviceString level (e.g. hue-extended.0.lights.1.config.battery)
|
|
1209
|
+
// NOT shortCurrDeviceString (which is the lights/sensors folder, e.g. hue-extended.0.lights)
|
|
1210
|
+
deviceBatteryStateDP = currDeviceString + adaptr.selAdapter[i].battery;
|
|
1211
|
+
deviceBatteryState = await tools.getInitValue(adaptr, deviceBatteryStateDP);
|
|
1212
|
+
|
|
1213
|
+
if (deviceBatteryState === undefined) {
|
|
1214
|
+
deviceBatteryStateDP = currDeviceString + adaptr.selAdapter[i].battery2;
|
|
1212
1215
|
deviceBatteryState = await tools.getInitValue(adaptr, deviceBatteryStateDP);
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1216
|
+
}
|
|
1217
|
+
break;
|
|
1218
|
+
case 'mihomeVacuum':
|
|
1219
|
+
case 'mqttNuki':
|
|
1220
|
+
case 'loqedSmartLock':
|
|
1221
|
+
deviceBatteryStateDP = shortCurrDeviceString + adaptr.selAdapter[i].battery;
|
|
1222
|
+
deviceBatteryState = await tools.getInitValue(adaptr, deviceBatteryStateDP);
|
|
1223
|
+
|
|
1224
|
+
if (deviceBatteryState === undefined) {
|
|
1225
|
+
deviceBatteryStateDP = shortCurrDeviceString + adaptr.selAdapter[i].battery2;
|
|
1226
|
+
deviceBatteryState = await tools.getInitValue(adaptr, deviceBatteryStateDP);
|
|
1227
|
+
}
|
|
1228
|
+
break;
|
|
1219
1229
|
case 'homee': // only battery devices, structure problem like homee.0.*.BatteryLevel-964
|
|
1220
1230
|
const devicePrefix = `${currDeviceString}.BatteryLevel-`;
|
|
1221
1231
|
const listeDP = await adaptr.getObjectViewAsync('system', 'state', {
|
package/main.js
CHANGED
|
@@ -86,6 +86,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
86
86
|
// Check if main function is running
|
|
87
87
|
this.mainRunning = false;
|
|
88
88
|
|
|
89
|
+
// Pending rescan flag (set if a new device was detected while main() was running)
|
|
90
|
+
this.pendingRescan = false;
|
|
91
|
+
|
|
89
92
|
this.on('ready', this.onReady.bind(this));
|
|
90
93
|
this.on('stateChange', this.onStateChange.bind(this));
|
|
91
94
|
this.on('objectChange', this.onObjectChange.bind(this));
|
|
@@ -280,6 +283,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
280
283
|
}
|
|
281
284
|
this.mainRunning = false;
|
|
282
285
|
this.log.debug(`Function finished: ${this.main.name}`);
|
|
286
|
+
|
|
287
|
+
// If a new device was detected while main() was running, trigger a rescan now
|
|
288
|
+
if (this.pendingRescan) {
|
|
289
|
+
this.pendingRescan = false;
|
|
290
|
+
this.log.info(`[main] Pending rescan detected – restarting main() for new device`);
|
|
291
|
+
await this.main();
|
|
292
|
+
}
|
|
283
293
|
} //<--End of main function
|
|
284
294
|
|
|
285
295
|
// If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.
|
|
@@ -302,10 +312,23 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
302
312
|
if (!this.mainRunning) {
|
|
303
313
|
await this.main();
|
|
304
314
|
} else {
|
|
305
|
-
|
|
315
|
+
this.pendingRescan = true;
|
|
306
316
|
}
|
|
307
317
|
} else {
|
|
308
|
-
|
|
318
|
+
// Check if the changed object belongs to a monitored adapter (new device)
|
|
319
|
+
const belongsToMonitoredAdapter = this.adapterSelected.some((adapterKey) =>
|
|
320
|
+
id.toLowerCase().startsWith(`${adapterKey.toLowerCase() }.`)
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
if (belongsToMonitoredAdapter) {
|
|
324
|
+
if (!this.mainRunning) {
|
|
325
|
+
this.log.info(`[onObjectChange] New device detected: ${id} – triggering rescan`);
|
|
326
|
+
await this.main();
|
|
327
|
+
} else {
|
|
328
|
+
this.log.debug(`[onObjectChange] main() is running – rescan for ${id} queued`);
|
|
329
|
+
this.pendingRescan = true;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
309
332
|
}
|
|
310
333
|
}
|
|
311
334
|
} catch (error) {
|
|
@@ -366,6 +389,21 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
366
389
|
=============================================*/
|
|
367
390
|
if (Array.from(this.listAllDevicesRaw.values()).some((obj) => Object.values(obj).includes(id))) {
|
|
368
391
|
await this.renewDeviceData(id, state);
|
|
392
|
+
|
|
393
|
+
// Update lists and datapoints immediately after device data change
|
|
394
|
+
await crud.createLists(this);
|
|
395
|
+
await crud.writeDatapoints(this);
|
|
396
|
+
|
|
397
|
+
// Also update per-adapter folder if configured
|
|
398
|
+
if (this.configCreateOwnFolder) {
|
|
399
|
+
for (const [adId] of Object.entries(adapterArray)) {
|
|
400
|
+
const adapter = adapterArray[adId];
|
|
401
|
+
if (this.adapterSelected.includes(adapter.adapterKey)) {
|
|
402
|
+
await crud.createLists(this, adId);
|
|
403
|
+
await crud.writeDatapoints(this, adId);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
369
407
|
}
|
|
370
408
|
} catch (error) {
|
|
371
409
|
this.log.error(`Issue at state change: ${id}`);
|
|
@@ -1085,76 +1123,113 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1085
1123
|
async theLists(device) {
|
|
1086
1124
|
// Raw List with all devices for user
|
|
1087
1125
|
if (device.Status !== 'disabled') {
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1126
|
+
// Deduplication: some adapters (e.g. hmrpc with multiple channels, hue-extended with
|
|
1127
|
+
// devices appearing under both lights and sensors) create multiple Map entries for the
|
|
1128
|
+
// same physical device. Use Path as unique key to prevent duplicate list entries.
|
|
1129
|
+
const lang = this.config.userSelectedLanguage;
|
|
1130
|
+
const alreadyInUserRaw = this.listAllDevicesUserRaw.some((d) => d.Device === device.Device && d.Adapter === device.Adapter);
|
|
1131
|
+
if (!alreadyInUserRaw) {
|
|
1132
|
+
this.listAllDevicesUserRaw.push({
|
|
1133
|
+
Device: device.Device,
|
|
1134
|
+
Adapter: device.Adapter,
|
|
1135
|
+
Instance: device.instance,
|
|
1136
|
+
'Instance connected': device.instanceDeviceConnected,
|
|
1137
|
+
isBatteryDevice: device.isBatteryDevice,
|
|
1138
|
+
Battery: device.Battery,
|
|
1139
|
+
BatteryRaw: device.BatteryRaw,
|
|
1140
|
+
BatteryUnitRaw: device.BatteryUnitRaw,
|
|
1141
|
+
isLowBat: device.LowBat,
|
|
1142
|
+
'Signal strength': device.SignalStrength,
|
|
1143
|
+
'Signal strength Raw': device.SignalStrengthRaw,
|
|
1144
|
+
'Last contact': device.LastContact,
|
|
1145
|
+
'Update Available': device.Upgradable,
|
|
1146
|
+
Status: device.Status,
|
|
1147
|
+
});
|
|
1148
|
+
}
|
|
1104
1149
|
|
|
1105
1150
|
// List with all devices
|
|
1106
|
-
this.listAllDevices.
|
|
1107
|
-
[translations.Device[
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1151
|
+
const alreadyInAll = this.listAllDevices.some(
|
|
1152
|
+
(d) => d[translations.Device[lang]] === device.Device && d[translations.Adapter[lang]] === device.Adapter,
|
|
1153
|
+
);
|
|
1154
|
+
if (!alreadyInAll) {
|
|
1155
|
+
this.listAllDevices.push({
|
|
1156
|
+
[translations.Device[lang]]: device.Device,
|
|
1157
|
+
[translations.Adapter[lang]]: device.Adapter,
|
|
1158
|
+
[translations.Battery[lang]]: device.Battery,
|
|
1159
|
+
[translations.Signal_strength[lang]]: device.SignalStrength,
|
|
1160
|
+
[translations.Last_Contact[lang]]: device.LastContact,
|
|
1161
|
+
[translations.Status[lang]]: device.Status,
|
|
1162
|
+
});
|
|
1163
|
+
}
|
|
1114
1164
|
|
|
1115
1165
|
// LinkQuality lists
|
|
1116
1166
|
if (device.SignalStrength !== ' - ') {
|
|
1117
|
-
this.linkQualityDevices.
|
|
1118
|
-
[translations.Device[
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1167
|
+
const alreadyInLQ = this.linkQualityDevices.some(
|
|
1168
|
+
(d) => d[translations.Device[lang]] === device.Device && d[translations.Adapter[lang]] === device.Adapter,
|
|
1169
|
+
);
|
|
1170
|
+
if (!alreadyInLQ) {
|
|
1171
|
+
this.linkQualityDevices.push({
|
|
1172
|
+
[translations.Device[lang]]: device.Device,
|
|
1173
|
+
[translations.Adapter[lang]]: device.Adapter,
|
|
1174
|
+
[translations.Signal_strength[lang]]: device.SignalStrength,
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1122
1177
|
}
|
|
1123
1178
|
|
|
1124
1179
|
// Battery lists
|
|
1125
1180
|
if (device.isBatteryDevice) {
|
|
1126
|
-
this.batteryPowered.
|
|
1127
|
-
[translations.Device[
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1181
|
+
const alreadyInBat = this.batteryPowered.some(
|
|
1182
|
+
(d) => d[translations.Device[lang]] === device.Device && d[translations.Adapter[lang]] === device.Adapter,
|
|
1183
|
+
);
|
|
1184
|
+
if (!alreadyInBat) {
|
|
1185
|
+
this.batteryPowered.push({
|
|
1186
|
+
[translations.Device[lang]]: device.Device,
|
|
1187
|
+
[translations.Adapter[lang]]: device.Adapter,
|
|
1188
|
+
[translations.Battery[lang]]: device.Battery,
|
|
1189
|
+
[translations.Status[lang]]: device.Status,
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1132
1192
|
}
|
|
1133
1193
|
|
|
1134
1194
|
// Low Bat lists
|
|
1135
1195
|
if (device.LowBat && device.Status !== 'Offline') {
|
|
1136
|
-
this.batteryLowPowered.
|
|
1137
|
-
[translations.Device[
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1196
|
+
const alreadyInLowBat = this.batteryLowPowered.some(
|
|
1197
|
+
(d) => d[translations.Device[lang]] === device.Device && d[translations.Adapter[lang]] === device.Adapter,
|
|
1198
|
+
);
|
|
1199
|
+
if (!alreadyInLowBat) {
|
|
1200
|
+
this.batteryLowPowered.push({
|
|
1201
|
+
[translations.Device[lang]]: device.Device,
|
|
1202
|
+
[translations.Adapter[lang]]: device.Adapter,
|
|
1203
|
+
[translations.Battery[lang]]: device.Battery,
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1141
1206
|
}
|
|
1142
1207
|
|
|
1143
1208
|
// Offline List
|
|
1144
1209
|
if (device.Status === 'Offline') {
|
|
1145
|
-
this.offlineDevices.
|
|
1146
|
-
[translations.Device[
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1210
|
+
const alreadyOffline = this.offlineDevices.some(
|
|
1211
|
+
(d) => d[translations.Device[lang]] === device.Device && d[translations.Adapter[lang]] === device.Adapter,
|
|
1212
|
+
);
|
|
1213
|
+
if (!alreadyOffline) {
|
|
1214
|
+
this.offlineDevices.push({
|
|
1215
|
+
[translations.Device[lang]]: device.Device,
|
|
1216
|
+
[translations.Adapter[lang]]: device.Adapter,
|
|
1217
|
+
[translations.Last_Contact[lang]]: device.LastContact,
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1150
1220
|
}
|
|
1151
1221
|
|
|
1152
1222
|
// Device update List
|
|
1153
1223
|
if (device.Upgradable === true || device.Upgradable === 1) {
|
|
1154
|
-
this.upgradableList.
|
|
1155
|
-
[translations.Device[
|
|
1156
|
-
|
|
1157
|
-
|
|
1224
|
+
const alreadyUpgradable = this.upgradableList.some(
|
|
1225
|
+
(d) => d[translations.Device[lang]] === device.Device && d[translations.Adapter[lang]] === device.Adapter,
|
|
1226
|
+
);
|
|
1227
|
+
if (!alreadyUpgradable) {
|
|
1228
|
+
this.upgradableList.push({
|
|
1229
|
+
[translations.Device[lang]]: device.Device,
|
|
1230
|
+
[translations.Adapter[lang]]: device.Adapter,
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1158
1233
|
}
|
|
1159
1234
|
}
|
|
1160
1235
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.device-watcher",
|
|
3
|
-
"version": "2.15.
|
|
3
|
+
"version": "2.15.13",
|
|
4
4
|
"description": "Watchdog for devices",
|
|
5
5
|
"author": "Christian Behrends <mail@christian-behrends.de>",
|
|
6
6
|
"contributors": [
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"@iobroker/adapter-dev": "^1.5.0",
|
|
39
39
|
"@iobroker/eslint-config": "^2.1.0",
|
|
40
40
|
"@iobroker/testing": "^5.2.2",
|
|
41
|
-
"@types/node": "^24.12.
|
|
41
|
+
"@types/node": "^24.12.2",
|
|
42
42
|
"@types/node-schedule": "^2.1.8",
|
|
43
|
-
"typescript": "~6.0.
|
|
43
|
+
"typescript": "~6.0.3"
|
|
44
44
|
},
|
|
45
45
|
"main": "main.js",
|
|
46
46
|
"files": [
|