iobroker.device-watcher 2.1.0 → 2.2.1
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 +15 -0
- package/admin/i18n/de/translations.json +100 -0
- package/admin/i18n/en/translations.json +96 -0
- package/admin/i18n/es/translations.json +100 -0
- package/admin/i18n/fr/translations.json +100 -0
- package/admin/i18n/it/translations.json +100 -0
- package/admin/i18n/nl/translations.json +100 -0
- package/admin/i18n/pl/translations.json +100 -0
- package/admin/i18n/pt/translations.json +100 -0
- package/admin/i18n/ru/translations.json +100 -0
- package/admin/i18n/uk/translations.json +100 -0
- package/admin/i18n/zh-cn/translations.json +100 -0
- package/admin/jsonConfig.json +1592 -0
- package/admin/words.js +109 -0
- package/io-package.json +92 -30
- package/lib/arrApart.js +22 -3
- package/main.js +921 -618
- package/package.json +2 -1
package/main.js
CHANGED
|
@@ -10,7 +10,7 @@ const schedule = require('node-schedule');
|
|
|
10
10
|
const arrApart = require('./lib/arrApart.js'); // list of supported adapters
|
|
11
11
|
|
|
12
12
|
// Sentry error reporting, disable when testing code!
|
|
13
|
-
const enableSendSentry =
|
|
13
|
+
const enableSendSentry = false;
|
|
14
14
|
|
|
15
15
|
// indicator if the adapter is running or not (for intervall/shedule)
|
|
16
16
|
let isUnloaded = false;
|
|
@@ -40,18 +40,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
40
40
|
this.batteryLowPoweredRaw = [];
|
|
41
41
|
this.offlineDevicesRaw = [];
|
|
42
42
|
|
|
43
|
-
// raw counts
|
|
44
|
-
this.offlineDevicesCountRaw = 0;
|
|
45
|
-
this.offlineDevicesCountRawOld = 0;
|
|
46
|
-
this.lowBatteryPoweredCountRaw = 0;
|
|
47
|
-
this.upgradableDevicesCountRawOld = 0;
|
|
48
|
-
|
|
49
43
|
// counts
|
|
50
44
|
this.offlineDevicesCount = 0;
|
|
51
45
|
this.deviceCounter = 0;
|
|
52
46
|
this.linkQualityCount = 0;
|
|
53
47
|
this.batteryPoweredCount = 0;
|
|
54
48
|
this.lowBatteryPoweredCount = 0;
|
|
49
|
+
this.upgradableDevicesCount = 0;
|
|
55
50
|
|
|
56
51
|
// Interval timer
|
|
57
52
|
this.refreshDataTimeout = null;
|
|
@@ -90,6 +85,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
90
85
|
hs100: this.config.hs100Devices,
|
|
91
86
|
hue: this.config.hueDevices,
|
|
92
87
|
hueExt: this.config.hueExtDevices,
|
|
88
|
+
innogy: this.config.innogyDevices,
|
|
93
89
|
jeelink: this.config.jeelinkDevices,
|
|
94
90
|
lupusec: this.config.lupusecDevices,
|
|
95
91
|
maxcube: this.config.maxcubeDevices,
|
|
@@ -99,6 +95,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
99
95
|
mihomeVacuum: this.config.mihomeVacuumDevices,
|
|
100
96
|
mqttClientZigbee2Mqtt: this.config.mqttClientZigbee2MqttDevices,
|
|
101
97
|
mqttNuki: this.config.mqttNukiDevices,
|
|
98
|
+
musiccast: this.config.musiccastDevices,
|
|
102
99
|
netatmo: this.config.netatmoDevices,
|
|
103
100
|
nukiExt: this.config.nukiExtDevices,
|
|
104
101
|
nut: this.config.nutDevices,
|
|
@@ -136,6 +133,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
136
133
|
hs100: this.config.hs100MaxMinutes,
|
|
137
134
|
hue: this.config.hueMaxMinutes,
|
|
138
135
|
hueExt: this.config.hueextMaxMinutes,
|
|
136
|
+
innogy: this.config.innogyMaxMinutes,
|
|
139
137
|
jeelink: this.config.jeelinkMaxMinutes,
|
|
140
138
|
lupusec: this.config.lupusecMaxMinutes,
|
|
141
139
|
maxcube: this.config.maxcubeMaxMinutes,
|
|
@@ -145,6 +143,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
145
143
|
mihomeVacuum: this.config.mihomeVacuumMaxMinutes,
|
|
146
144
|
mqttClientZigbee2Mqtt: this.config.mqttClientZigbee2MqttMaxMinutes,
|
|
147
145
|
mqttNuki: this.config.mqttNukiMaxMinutes,
|
|
146
|
+
musiccast: this.config.musiccastMaxMinutes,
|
|
148
147
|
netatmo: this.config.netatmoMaxMinutes,
|
|
149
148
|
nukiExt: this.config.nukiextendMaxMinutes,
|
|
150
149
|
nut: this.config.nutMaxMinutes,
|
|
@@ -196,41 +195,41 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
196
195
|
}
|
|
197
196
|
|
|
198
197
|
//create and fill datapoints for each adapter if selected
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (
|
|
203
|
-
if (this.
|
|
198
|
+
if (this.config.createOwnFolder) {
|
|
199
|
+
try {
|
|
200
|
+
for (const [id] of Object.entries(arrApart)) {
|
|
201
|
+
if (!isUnloaded) {
|
|
202
|
+
if (this.supAdapter !== undefined && this.supAdapter[id]) {
|
|
204
203
|
await this.createDPsForEachAdapter(id);
|
|
205
204
|
if (this.config.createHtmlList) await this.createHtmlListDatapoints(id);
|
|
206
|
-
this.log.debug(`Created datapoints for ${
|
|
205
|
+
this.log.debug(`Created datapoints for ${this.capitalize(id)}`);
|
|
207
206
|
}
|
|
207
|
+
} else {
|
|
208
|
+
return; // cancel run if unloaded was called.
|
|
208
209
|
}
|
|
209
|
-
} else {
|
|
210
|
-
return; // cancel run if unloaded was called.
|
|
211
210
|
}
|
|
211
|
+
} catch (error) {
|
|
212
|
+
this.errorReporting('[onReady - create and fill datapoints for each adapter]', error);
|
|
212
213
|
}
|
|
213
|
-
} catch (error) {
|
|
214
|
-
this.errorReporting('[onReady - create and fill datapoints for each adapter]', error);
|
|
215
214
|
}
|
|
216
215
|
|
|
217
216
|
// create HTML list
|
|
218
217
|
if (this.config.createHtmlList) await this.createHtmlListDatapoints();
|
|
219
218
|
|
|
220
|
-
//
|
|
221
|
-
await this.
|
|
219
|
+
//read data first at start
|
|
220
|
+
await this.main();
|
|
222
221
|
|
|
223
|
-
//
|
|
224
|
-
|
|
225
|
-
if (this.config.checkSendAdapterUpdateNotify) {
|
|
226
|
-
this.subscribeForeignStatesAsync(`admin.*.info.updatesJson`);
|
|
227
|
-
}*/
|
|
222
|
+
// update last contact data in interval
|
|
223
|
+
await this.refreshData();
|
|
228
224
|
|
|
229
225
|
// send overview for low battery devices
|
|
230
|
-
if (this.config.
|
|
226
|
+
if (this.config.checkSendBatteryMsgDaily) await this.sendBatteryNotifyShedule();
|
|
231
227
|
|
|
232
228
|
// send overview of offline devices
|
|
233
229
|
if (this.config.checkSendOfflineMsgDaily) await this.sendOfflineNotificationsShedule();
|
|
230
|
+
|
|
231
|
+
// send overview of upgradeable devices
|
|
232
|
+
if (this.config.checkSendUpgradeMsgDaily) await this.sendUpgradeNotificationsShedule();
|
|
234
233
|
} catch (error) {
|
|
235
234
|
this.errorReporting('[onReady]', error);
|
|
236
235
|
this.terminate ? this.terminate(15) : process.exit(15);
|
|
@@ -242,11 +241,121 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
242
241
|
* @param {string} id
|
|
243
242
|
* @param {ioBroker.State | null | undefined} state
|
|
244
243
|
*/
|
|
245
|
-
onStateChange(id, state) {
|
|
244
|
+
async onStateChange(id, state) {
|
|
246
245
|
// Admin JSON for Adapter updates
|
|
247
246
|
if (id && state) {
|
|
248
247
|
this.log.debug(`State changed: ${id} changed ${state.val}`);
|
|
249
|
-
|
|
248
|
+
let batteryData;
|
|
249
|
+
let oldLowBatState;
|
|
250
|
+
let contactData;
|
|
251
|
+
let oldStatus;
|
|
252
|
+
let oldSignalStrength;
|
|
253
|
+
|
|
254
|
+
for (const device of this.listAllDevicesRaw) {
|
|
255
|
+
// On statechange update available datapoint
|
|
256
|
+
switch (id) {
|
|
257
|
+
case device.UpdateDP:
|
|
258
|
+
if (state.val) {
|
|
259
|
+
device.Upgradable = state.val;
|
|
260
|
+
|
|
261
|
+
await this.createLists();
|
|
262
|
+
await this.writeDatapoints();
|
|
263
|
+
if (this.config.createOwnFolder) await this.createDataForEachAdapter(device.adapterID);
|
|
264
|
+
if (!this.blacklistNotify.includes(device.Path)) {
|
|
265
|
+
await this.sendDeviceUpdatesNotification(device.Device, device.Adapter);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
break;
|
|
269
|
+
|
|
270
|
+
case device.SignalStrengthDP:
|
|
271
|
+
oldSignalStrength = device.SignalStrength;
|
|
272
|
+
device.SignalStrength = await this.calculateSignalStrength(state, device.adapterID);
|
|
273
|
+
if (oldSignalStrength !== device.SignalStrength) {
|
|
274
|
+
await this.createLists();
|
|
275
|
+
await this.writeDatapoints();
|
|
276
|
+
if (this.config.createOwnFolder) await this.createDataForEachAdapter(device.adapterID);
|
|
277
|
+
}
|
|
278
|
+
break;
|
|
279
|
+
|
|
280
|
+
case device.batteryDP:
|
|
281
|
+
if (device.isBatteryDevice) {
|
|
282
|
+
oldLowBatState = device.LowBat;
|
|
283
|
+
batteryData = await this.getBatteryData(state.val, oldLowBatState, device.adapterID);
|
|
284
|
+
|
|
285
|
+
device.Battery = batteryData[0];
|
|
286
|
+
device.BatteryRaw = batteryData[2];
|
|
287
|
+
device.LowBat = await this.setLowbatIndicator(state.val, undefined, device.LowBatDP);
|
|
288
|
+
|
|
289
|
+
if (device.LowBat && oldLowBatState !== device.LowBat) {
|
|
290
|
+
await this.createLists();
|
|
291
|
+
await this.writeDatapoints();
|
|
292
|
+
if (this.config.createOwnFolder) await this.createDataForEachAdapter(device.adapterID);
|
|
293
|
+
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(device.Path)) {
|
|
294
|
+
await this.sendLowBatNoticiation(device.Device, device.Adapter, device.Battery);
|
|
295
|
+
}
|
|
296
|
+
} else if (!device.LowBat && oldLowBatState !== device.LowBat) {
|
|
297
|
+
await this.createLists();
|
|
298
|
+
await this.writeDatapoints();
|
|
299
|
+
if (this.config.createOwnFolder) await this.createDataForEachAdapter(device.adapterID);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
break;
|
|
303
|
+
|
|
304
|
+
case device.LowBatDP:
|
|
305
|
+
if (device.isBatteryDevice) {
|
|
306
|
+
oldLowBatState = device.LowBat;
|
|
307
|
+
batteryData = await this.getBatteryData(device.BatteryRaw, state.val, device.adapterID);
|
|
308
|
+
device.Battery = batteryData[0];
|
|
309
|
+
device.BatteryRaw = batteryData[2];
|
|
310
|
+
device.LowBat = await this.setLowbatIndicator(device.BatteryRaw, state.val, device.LowBatDP);
|
|
311
|
+
|
|
312
|
+
if (device.LowBat && oldLowBatState !== device.LowBat) {
|
|
313
|
+
await this.createLists();
|
|
314
|
+
await this.writeDatapoints();
|
|
315
|
+
if (this.config.createOwnFolder) await this.createDataForEachAdapter(device.adapterID);
|
|
316
|
+
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(device.Path)) {
|
|
317
|
+
await this.sendLowBatNoticiation(device.Device, device.Adapter, device.Battery);
|
|
318
|
+
}
|
|
319
|
+
} else if (!device.LowBat && oldLowBatState !== device.LowBat) {
|
|
320
|
+
await this.createLists();
|
|
321
|
+
await this.writeDatapoints();
|
|
322
|
+
if (this.config.createOwnFolder) await this.createDataForEachAdapter(device.adapterID);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
break;
|
|
327
|
+
case device.UnreachDP:
|
|
328
|
+
case device.DeviceStateSelectorDP:
|
|
329
|
+
case device.rssiPeerSelectorDP:
|
|
330
|
+
case device.Path:
|
|
331
|
+
oldStatus = device.Status;
|
|
332
|
+
device.UnreachState = await this.getInitValue(device.UnreachDP);
|
|
333
|
+
contactData = await this.getOnlineState(
|
|
334
|
+
device.Path,
|
|
335
|
+
device.adapterID,
|
|
336
|
+
device.UnreachDP,
|
|
337
|
+
device.SignalStrength,
|
|
338
|
+
device.UnreachState,
|
|
339
|
+
device.DeviceStateSelectorDP,
|
|
340
|
+
device.rssiPeerSelectorDP,
|
|
341
|
+
);
|
|
342
|
+
if (contactData !== undefined) {
|
|
343
|
+
device.LastContact = contactData[0];
|
|
344
|
+
device.Status = contactData[1];
|
|
345
|
+
device.SignalStrength = contactData[2];
|
|
346
|
+
}
|
|
347
|
+
if (device.Status !== oldStatus) {
|
|
348
|
+
await this.createLists();
|
|
349
|
+
await this.writeDatapoints();
|
|
350
|
+
if (this.config.createOwnFolder) await this.createDataForEachAdapter(device.adapterID);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (device.Status && oldStatus !== device.Status && this.config.checkSendOfflineMsg && !this.blacklistNotify.includes(device.Path)) {
|
|
354
|
+
await this.sendOfflineNotifications(device.Device, device.Adapter, device.Status, device.LastContact);
|
|
355
|
+
}
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
250
359
|
}
|
|
251
360
|
}
|
|
252
361
|
|
|
@@ -286,11 +395,12 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
286
395
|
|
|
287
396
|
/**
|
|
288
397
|
* refresh data with interval
|
|
398
|
+
* is neccessary to refresh lastContact data, especially of devices without state changes
|
|
289
399
|
*/
|
|
290
400
|
async refreshData() {
|
|
291
401
|
const nextTimeout = this.config.updateinterval * 1000;
|
|
292
402
|
|
|
293
|
-
await this.
|
|
403
|
+
await this.checkLastContact();
|
|
294
404
|
|
|
295
405
|
// Clear existing timeout
|
|
296
406
|
if (this.refreshDataTimeout) {
|
|
@@ -315,25 +425,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
315
425
|
async main() {
|
|
316
426
|
this.log.debug(`Function started: ${this.main.name}`);
|
|
317
427
|
|
|
318
|
-
// fill datapoints for each adapter if selected
|
|
319
|
-
try {
|
|
320
|
-
for (const [id] of Object.entries(arrApart)) {
|
|
321
|
-
if (!isUnloaded) {
|
|
322
|
-
if (this.supAdapter !== undefined && this.supAdapter[id]) {
|
|
323
|
-
if (this.config.createOwnFolder) {
|
|
324
|
-
await this.createDataForEachAdapter(id);
|
|
325
|
-
this.log.debug(`Created and filled data for ${await this.capitalize(id)}`);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
} else {
|
|
329
|
-
this.log.warn('broke up');
|
|
330
|
-
return; // cancel run if unloaded was called.
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
} catch (error) {
|
|
334
|
-
this.errorReporting('[main - create and fill datapoints for each adapter]', error);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
428
|
// fill counts and lists of all selected adapter
|
|
338
429
|
try {
|
|
339
430
|
await this.createDataOfAllAdapter();
|
|
@@ -342,6 +433,20 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
342
433
|
this.errorReporting('[main - create data of all adapter]', error);
|
|
343
434
|
}
|
|
344
435
|
|
|
436
|
+
// fill datapoints for each adapter if selected
|
|
437
|
+
if (this.config.createOwnFolder) {
|
|
438
|
+
try {
|
|
439
|
+
for (const [id] of Object.entries(arrApart)) {
|
|
440
|
+
if (this.supAdapter !== undefined && this.supAdapter[id]) {
|
|
441
|
+
await this.createDataForEachAdapter(id);
|
|
442
|
+
this.log.debug(`Created and filled data for ${this.capitalize(id)}`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
} catch (error) {
|
|
446
|
+
this.errorReporting('[main - create and fill datapoints for each adapter]', error);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
345
450
|
this.log.debug(`Function finished: ${this.main.name}`);
|
|
346
451
|
} //<--End of main function
|
|
347
452
|
|
|
@@ -438,17 +543,22 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
438
543
|
const shortDeviceObject = await this.getForeignObjectAsync(shortCurrDeviceString);
|
|
439
544
|
const shortshortDeviceObject = await this.getForeignObjectAsync(shortshortCurrDeviceString);
|
|
440
545
|
let deviceName;
|
|
546
|
+
let folderName;
|
|
547
|
+
let deviceID;
|
|
441
548
|
|
|
442
549
|
// Get ID with currDeviceString from datapoint
|
|
443
550
|
switch (this.arrDev[i].adapterID) {
|
|
444
551
|
// Get ID for Switchbot and ESPHome Devices
|
|
445
552
|
case 'switchbotBle':
|
|
446
553
|
case 'esphome':
|
|
447
|
-
case 'fullybrowser':
|
|
448
554
|
case 'apcups':
|
|
449
555
|
deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
|
|
450
556
|
break;
|
|
451
557
|
|
|
558
|
+
case 'fullybrowser':
|
|
559
|
+
deviceName = (await this.getInitValue(currDeviceString + this.arrDev[i].id)) + ' ' + (await this.getInitValue(currDeviceString + this.arrDev[i].id2));
|
|
560
|
+
break;
|
|
561
|
+
|
|
452
562
|
// Get ID with short currDeviceString from objectjson
|
|
453
563
|
case 'hueExt':
|
|
454
564
|
case 'hmrpc':
|
|
@@ -469,7 +579,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
469
579
|
// Get ID with short currDeviceString from datapoint
|
|
470
580
|
case 'mihomeVacuum':
|
|
471
581
|
case 'roomba':
|
|
472
|
-
|
|
582
|
+
folderName = shortCurrDeviceString.slice(shortCurrDeviceString.lastIndexOf('.') + 1);
|
|
583
|
+
deviceID = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].id);
|
|
584
|
+
deviceName = `I${folderName} ${deviceID}`;
|
|
473
585
|
break;
|
|
474
586
|
|
|
475
587
|
//Get ID of foldername
|
|
@@ -508,6 +620,163 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
508
620
|
}
|
|
509
621
|
}
|
|
510
622
|
|
|
623
|
+
/**
|
|
624
|
+
* calculate Signalstrength
|
|
625
|
+
* @param {object} deviceQualityState - State value
|
|
626
|
+
* @param {object} adapterID - adapter name
|
|
627
|
+
*/
|
|
628
|
+
async calculateSignalStrength(deviceQualityState, adapterID) {
|
|
629
|
+
let linkQuality;
|
|
630
|
+
let mqttNukiValue;
|
|
631
|
+
|
|
632
|
+
if (deviceQualityState != null) {
|
|
633
|
+
switch (typeof deviceQualityState.val) {
|
|
634
|
+
case 'number':
|
|
635
|
+
if (this.config.trueState) {
|
|
636
|
+
linkQuality = deviceQualityState.val;
|
|
637
|
+
} else {
|
|
638
|
+
switch (adapterID) {
|
|
639
|
+
case 'roomba':
|
|
640
|
+
case 'sonoff':
|
|
641
|
+
linkQuality = deviceQualityState.val + '%'; // If quality state is already an percent value
|
|
642
|
+
break;
|
|
643
|
+
case 'lupusec':
|
|
644
|
+
linkQuality = deviceQualityState.val;
|
|
645
|
+
break;
|
|
646
|
+
|
|
647
|
+
default:
|
|
648
|
+
// If quality state is an RSSI value calculate in percent:
|
|
649
|
+
if (deviceQualityState.val == -255) {
|
|
650
|
+
linkQuality = ' - ';
|
|
651
|
+
} else if (deviceQualityState.val < 0) {
|
|
652
|
+
linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
|
|
653
|
+
// If Quality State is an value between 0-255 (zigbee) calculate in percent:
|
|
654
|
+
} else if (deviceQualityState.val >= 0) {
|
|
655
|
+
linkQuality = parseFloat(((100 / 255) * deviceQualityState.val).toFixed(0)) + '%';
|
|
656
|
+
}
|
|
657
|
+
break;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
break;
|
|
661
|
+
|
|
662
|
+
case 'string':
|
|
663
|
+
switch (adapterID) {
|
|
664
|
+
case 'netatmo':
|
|
665
|
+
// for Netatmo devices
|
|
666
|
+
linkQuality = deviceQualityState.val;
|
|
667
|
+
break;
|
|
668
|
+
case 'nukiExt':
|
|
669
|
+
linkQuality = ' - ';
|
|
670
|
+
break;
|
|
671
|
+
case 'mqttNuki':
|
|
672
|
+
linkQuality = deviceQualityState.val;
|
|
673
|
+
mqttNukiValue = parseInt(linkQuality);
|
|
674
|
+
if (this.config.trueState) {
|
|
675
|
+
linkQuality = deviceQualityState.val;
|
|
676
|
+
} else if (mqttNukiValue < 0) {
|
|
677
|
+
linkQuality = Math.min(Math.max(2 * (mqttNukiValue + 100), 0), 100) + '%';
|
|
678
|
+
// If Quality State is an value between 0-255 (zigbee) calculate in percent:
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
break;
|
|
682
|
+
}
|
|
683
|
+
} else {
|
|
684
|
+
linkQuality = ' - ';
|
|
685
|
+
}
|
|
686
|
+
return linkQuality;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* get battery data
|
|
691
|
+
* @param {object} deviceBatteryState - State value
|
|
692
|
+
* @param {object} deviceLowBatState - State value
|
|
693
|
+
* @param {object} adapterID - adapter name
|
|
694
|
+
*/
|
|
695
|
+
async getBatteryData(deviceBatteryState, deviceLowBatState, adapterID) {
|
|
696
|
+
let batteryHealthRaw;
|
|
697
|
+
let batteryHealth;
|
|
698
|
+
let isBatteryDevice;
|
|
699
|
+
|
|
700
|
+
if (deviceBatteryState === undefined) {
|
|
701
|
+
if (deviceLowBatState !== undefined) {
|
|
702
|
+
switch (deviceLowBatState) {
|
|
703
|
+
case 'none':
|
|
704
|
+
break;
|
|
705
|
+
default:
|
|
706
|
+
if (deviceLowBatState !== true || deviceLowBatState === 'NORMAL' || deviceLowBatState === 1) {
|
|
707
|
+
batteryHealth = 'ok';
|
|
708
|
+
isBatteryDevice = true;
|
|
709
|
+
} else {
|
|
710
|
+
batteryHealth = 'low';
|
|
711
|
+
isBatteryDevice = true;
|
|
712
|
+
}
|
|
713
|
+
break;
|
|
714
|
+
}
|
|
715
|
+
} else {
|
|
716
|
+
batteryHealth = ' - ';
|
|
717
|
+
}
|
|
718
|
+
} else {
|
|
719
|
+
switch (adapterID) {
|
|
720
|
+
case 'hmrpc':
|
|
721
|
+
if (deviceBatteryState === 0 || (deviceBatteryState && deviceBatteryState >= 6)) {
|
|
722
|
+
batteryHealth = ' - ';
|
|
723
|
+
} else {
|
|
724
|
+
batteryHealth = deviceBatteryState + 'V';
|
|
725
|
+
batteryHealthRaw = deviceBatteryState;
|
|
726
|
+
isBatteryDevice = true;
|
|
727
|
+
}
|
|
728
|
+
break;
|
|
729
|
+
default:
|
|
730
|
+
batteryHealth = deviceBatteryState + '%';
|
|
731
|
+
batteryHealthRaw = deviceBatteryState;
|
|
732
|
+
isBatteryDevice = true;
|
|
733
|
+
break;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
return [batteryHealth, isBatteryDevice, batteryHealthRaw];
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
*set low bat indicator
|
|
741
|
+
* @param {object} deviceBatteryState
|
|
742
|
+
* @param {object} deviceLowBatState
|
|
743
|
+
* @param {object} isLowBatDP
|
|
744
|
+
*/
|
|
745
|
+
|
|
746
|
+
async setLowbatIndicator(deviceBatteryState, deviceLowBatState, isLowBatDP) {
|
|
747
|
+
let lowBatIndicator = false;
|
|
748
|
+
/*=============================================
|
|
749
|
+
= Set Lowbat indicator =
|
|
750
|
+
=============================================*/
|
|
751
|
+
if (deviceLowBatState !== null && isLowBatDP !== 'none') {
|
|
752
|
+
switch (typeof deviceLowBatState) {
|
|
753
|
+
case 'number':
|
|
754
|
+
if (deviceLowBatState === 0) {
|
|
755
|
+
lowBatIndicator = true;
|
|
756
|
+
}
|
|
757
|
+
break;
|
|
758
|
+
|
|
759
|
+
case 'string':
|
|
760
|
+
if (deviceLowBatState !== 'NORMAL') {
|
|
761
|
+
// Tado devices
|
|
762
|
+
lowBatIndicator = true;
|
|
763
|
+
}
|
|
764
|
+
break;
|
|
765
|
+
|
|
766
|
+
case 'boolean':
|
|
767
|
+
if (deviceLowBatState) {
|
|
768
|
+
lowBatIndicator = true;
|
|
769
|
+
}
|
|
770
|
+
break;
|
|
771
|
+
}
|
|
772
|
+
} else {
|
|
773
|
+
if (deviceBatteryState < this.config.minWarnBatterie) {
|
|
774
|
+
lowBatIndicator = true;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
return lowBatIndicator;
|
|
778
|
+
}
|
|
779
|
+
|
|
511
780
|
/**
|
|
512
781
|
* get Last Contact
|
|
513
782
|
* @param {object} selector - Selector
|
|
@@ -527,118 +796,181 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
527
796
|
}
|
|
528
797
|
|
|
529
798
|
/**
|
|
530
|
-
*
|
|
799
|
+
* get online state and time
|
|
800
|
+
* @param {object} id - ID
|
|
801
|
+
* @param {string} adapterID - ID of Adapter
|
|
802
|
+
* @param {string} unreachDP - Datapoint of Unreach
|
|
803
|
+
* @param {object} linkQuality - Linkquality Value
|
|
804
|
+
* @param {object} deviceUnreachState - State of deviceUnreach datapoint
|
|
805
|
+
* @param {string} deviceStateSelectorDP - Selector of device state (like .state)
|
|
806
|
+
* @param {string} rssiPeerSelectorDP - HM RSSI Peer Datapoint
|
|
531
807
|
*/
|
|
532
|
-
async
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
this.batteryLowPowered = [];
|
|
536
|
-
this.listAllDevices = [];
|
|
537
|
-
this.offlineDevices = [];
|
|
538
|
-
this.batteryLowPoweredRaw = [];
|
|
539
|
-
this.offlineDevicesRaw = [];
|
|
540
|
-
this.upgradableList = [];
|
|
541
|
-
|
|
542
|
-
for (const device of this.listAllDevicesRaw) {
|
|
543
|
-
/*---------- fill raw lists ----------*/
|
|
544
|
-
// low bat list
|
|
545
|
-
if (device['LowBat'] && device['Status'] !== 'Offline') {
|
|
546
|
-
this.batteryLowPoweredRaw.push({
|
|
547
|
-
Path: device['Path'],
|
|
548
|
-
Device: device['Device'],
|
|
549
|
-
Adapter: device['Adapter'],
|
|
550
|
-
Battery: device['Battery'],
|
|
551
|
-
});
|
|
552
|
-
}
|
|
553
|
-
// offline raw list
|
|
554
|
-
if (device['Status'] === 'Offline') {
|
|
555
|
-
this.offlineDevicesRaw.push({
|
|
556
|
-
Path: device['Path'],
|
|
557
|
-
Device: device['Device'],
|
|
558
|
-
Adapter: device['Adapter'],
|
|
559
|
-
'Last contact': device['Last contact'],
|
|
560
|
-
});
|
|
561
|
-
}
|
|
808
|
+
async getOnlineState(id, adapterID, unreachDP, linkQuality, deviceUnreachState, deviceStateSelectorDP, rssiPeerSelectorDP) {
|
|
809
|
+
let lastContactString;
|
|
810
|
+
let deviceState = 'Online';
|
|
562
811
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
Adapter: device['Adapter'],
|
|
578
|
-
'Signal strength': device['Signal strength'],
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
// Battery lists
|
|
582
|
-
if (device['isBatteryDevice']) {
|
|
583
|
-
this.batteryPowered.push({
|
|
584
|
-
Device: device['Device'],
|
|
585
|
-
Adapter: device['Adapter'],
|
|
586
|
-
Battery: device['Battery'],
|
|
587
|
-
Status: device['Status'],
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
|
-
// Low Bat lists
|
|
591
|
-
if (device['LowBat'] && device['Status'] !== 'Offline') {
|
|
592
|
-
this.batteryLowPowered.push({
|
|
593
|
-
Device: device['Device'],
|
|
594
|
-
Adapter: device['Adapter'],
|
|
595
|
-
Battery: device['Battery'],
|
|
596
|
-
});
|
|
597
|
-
}
|
|
812
|
+
try {
|
|
813
|
+
const deviceMainSelector = await this.getForeignStateAsync(id);
|
|
814
|
+
if (deviceMainSelector) {
|
|
815
|
+
const deviceUnreachSelector = await this.getForeignStateAsync(unreachDP);
|
|
816
|
+
const deviceStateSelector = await this.getForeignStateAsync(deviceStateSelectorDP); // for hmrpc devices
|
|
817
|
+
const rssiPeerSelector = await this.getForeignStateAsync(rssiPeerSelectorDP);
|
|
818
|
+
const lastContact = await this.getTimestamp(deviceMainSelector.ts);
|
|
819
|
+
const lastDeviceUnreachStateChange = deviceUnreachSelector != undefined ? await this.getTimestamp(deviceUnreachSelector.lc) : await this.getTimestamp(deviceMainSelector.ts);
|
|
820
|
+
// If there is no contact since user sets minutes add device in offline list
|
|
821
|
+
// calculate to days after 48 hours
|
|
822
|
+
switch (unreachDP) {
|
|
823
|
+
case 'none':
|
|
824
|
+
lastContactString = await this.getLastContact(deviceMainSelector.ts);
|
|
825
|
+
break;
|
|
598
826
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
827
|
+
default:
|
|
828
|
+
//State changed
|
|
829
|
+
if (adapterID === 'hmrpc') {
|
|
830
|
+
if (linkQuality !== ' - ') {
|
|
831
|
+
if (deviceUnreachState) {
|
|
832
|
+
lastContactString = await this.getLastContact(deviceMainSelector.lc);
|
|
833
|
+
} else {
|
|
834
|
+
lastContactString = await this.getLastContact(deviceMainSelector.ts);
|
|
835
|
+
}
|
|
836
|
+
} else {
|
|
837
|
+
if (deviceStateSelector) {
|
|
838
|
+
// because old hm devices don't send rssi states
|
|
839
|
+
lastContactString = await this.getLastContact(deviceStateSelector.ts);
|
|
840
|
+
} else if (rssiPeerSelector) {
|
|
841
|
+
// because old hm sensors don't send rssi/state values
|
|
842
|
+
lastContactString = await this.getLastContact(rssiPeerSelector.ts);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
} else {
|
|
846
|
+
if (!deviceUnreachState) {
|
|
847
|
+
lastContactString = await this.getLastContact(deviceMainSelector.lc);
|
|
848
|
+
} else {
|
|
849
|
+
lastContactString = await this.getLastContact(deviceMainSelector.ts);
|
|
850
|
+
}
|
|
851
|
+
break;
|
|
852
|
+
}
|
|
606
853
|
}
|
|
607
854
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
855
|
+
/*=============================================
|
|
856
|
+
= Set Online Status =
|
|
857
|
+
=============================================*/
|
|
858
|
+
if (this.maxMinutes !== undefined) {
|
|
859
|
+
switch (adapterID) {
|
|
860
|
+
case 'hmrpc':
|
|
861
|
+
case 'hmiP':
|
|
862
|
+
case 'maxcube':
|
|
863
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
864
|
+
if (deviceUnreachState) {
|
|
865
|
+
deviceState = 'Offline'; //set online state to offline
|
|
866
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
867
|
+
}
|
|
868
|
+
} else if (lastDeviceUnreachStateChange > this.maxMinutes[adapterID] && deviceUnreachState) {
|
|
869
|
+
deviceState = 'Offline'; //set online state to offline
|
|
870
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
871
|
+
}
|
|
872
|
+
break;
|
|
873
|
+
case 'apcups':
|
|
874
|
+
case 'hue':
|
|
875
|
+
case 'hueExt':
|
|
876
|
+
case 'ping':
|
|
877
|
+
case 'deconz':
|
|
878
|
+
case 'shelly':
|
|
879
|
+
case 'sonoff':
|
|
880
|
+
case 'unifi':
|
|
881
|
+
case 'zigbee':
|
|
882
|
+
case 'zigbee2MQTT':
|
|
883
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
884
|
+
if (!deviceUnreachState) {
|
|
885
|
+
deviceState = 'Offline'; //set online state to offline
|
|
886
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
887
|
+
}
|
|
888
|
+
} else if (!deviceUnreachState && lastDeviceUnreachStateChange > this.maxMinutes[adapterID]) {
|
|
889
|
+
deviceState = 'Offline'; //set online state to offline
|
|
890
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
891
|
+
}
|
|
892
|
+
break;
|
|
893
|
+
case 'mqttClientZigbee2Mqtt':
|
|
894
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
895
|
+
if (deviceUnreachState !== 'online') {
|
|
896
|
+
deviceState = 'Offline'; //set online state to offline
|
|
897
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
898
|
+
}
|
|
899
|
+
} else if (deviceUnreachState !== 'online' && lastDeviceUnreachStateChange > this.maxMinutes[adapterID]) {
|
|
900
|
+
deviceState = 'Offline'; //set online state to offline
|
|
901
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
902
|
+
}
|
|
903
|
+
break;
|
|
904
|
+
case 'mihome':
|
|
905
|
+
if (deviceUnreachState !== undefined) {
|
|
906
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
907
|
+
if (!deviceUnreachState) {
|
|
908
|
+
deviceState = 'Offline'; //set online state to offline
|
|
909
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
910
|
+
}
|
|
911
|
+
} else if (lastContact > this.maxMinutes[adapterID]) {
|
|
912
|
+
deviceState = 'Offline'; //set online state to offline
|
|
913
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
914
|
+
}
|
|
915
|
+
} else {
|
|
916
|
+
if (this.config.mihomeMaxMinutes <= 0) {
|
|
917
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
918
|
+
deviceState = 'Offline'; //set online state to offline
|
|
919
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
920
|
+
}
|
|
921
|
+
} else if (lastContact > this.maxMinutes[adapterID]) {
|
|
922
|
+
deviceState = 'Offline'; //set online state to offline
|
|
923
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
break;
|
|
927
|
+
default:
|
|
928
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
929
|
+
if (!deviceUnreachState) {
|
|
930
|
+
deviceState = 'Offline'; //set online state to offline
|
|
931
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
932
|
+
}
|
|
933
|
+
} else if (lastContact > this.maxMinutes[adapterID]) {
|
|
934
|
+
deviceState = 'Offline'; //set online state to offline
|
|
935
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
936
|
+
}
|
|
937
|
+
break;
|
|
938
|
+
}
|
|
614
939
|
}
|
|
615
940
|
}
|
|
941
|
+
return [lastContactString, deviceState, linkQuality];
|
|
942
|
+
} catch (error) {
|
|
943
|
+
this.errorReporting('[getLastContact]', error);
|
|
616
944
|
}
|
|
617
945
|
}
|
|
618
946
|
|
|
619
947
|
/**
|
|
620
|
-
*
|
|
948
|
+
* when was last contact of device
|
|
621
949
|
*/
|
|
622
|
-
async
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
950
|
+
async checkLastContact() {
|
|
951
|
+
for (const device of this.listAllDevicesRaw) {
|
|
952
|
+
const oldContactState = device.Status;
|
|
953
|
+
device.UnreachState = await this.getInitValue(device.UnreachDP);
|
|
954
|
+
const contactData = await this.getOnlineState(
|
|
955
|
+
device.Path,
|
|
956
|
+
device.adapterID,
|
|
957
|
+
device.UnreachDP,
|
|
958
|
+
device.SignalStrength,
|
|
959
|
+
device.UnreachState,
|
|
960
|
+
device.DeviceStateSelectorDP,
|
|
961
|
+
device.rssiPeerSelectorDP,
|
|
962
|
+
);
|
|
963
|
+
if (contactData !== undefined) {
|
|
964
|
+
device.LastContact = contactData[0];
|
|
965
|
+
device.Status = contactData[1];
|
|
966
|
+
device.linkQuality = contactData[2];
|
|
967
|
+
}
|
|
968
|
+
if (this.config.checkSendOfflineMsg && oldContactState !== device.Status && !this.blacklistNotify.includes(device.Path)) {
|
|
969
|
+
await this.sendOfflineNotifications(device.Device, device.Adapter, device.Status, device.LastContact);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
await this.createLists();
|
|
973
|
+
await this.writeDatapoints();
|
|
642
974
|
}
|
|
643
975
|
|
|
644
976
|
/**
|
|
@@ -670,347 +1002,127 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
670
1002
|
/*=============================================
|
|
671
1003
|
= Get signal strength =
|
|
672
1004
|
=============================================*/
|
|
1005
|
+
let deviceQualityDP = currDeviceString + this.arrDev[i].rssiState;
|
|
673
1006
|
let deviceQualityState;
|
|
674
|
-
let linkQuality;
|
|
675
|
-
let mqttNukiValue;
|
|
676
1007
|
|
|
677
1008
|
switch (adapterID) {
|
|
678
1009
|
case 'mihomeVacuum':
|
|
679
|
-
|
|
1010
|
+
deviceQualityDP = shortCurrDeviceString + this.arrDev[i].rssiState;
|
|
1011
|
+
deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
|
|
680
1012
|
break;
|
|
681
1013
|
|
|
682
1014
|
case 'netatmo':
|
|
683
|
-
deviceQualityState = await this.getForeignStateAsync(
|
|
1015
|
+
deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
|
|
684
1016
|
if (!deviceQualityState) {
|
|
685
|
-
|
|
1017
|
+
deviceQualityDP = currDeviceString + this.arrDev[i].rfState;
|
|
1018
|
+
deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
|
|
686
1019
|
}
|
|
687
1020
|
break;
|
|
688
1021
|
|
|
689
1022
|
default:
|
|
690
|
-
deviceQualityState = await this.getForeignStateAsync(
|
|
1023
|
+
deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
|
|
691
1024
|
break;
|
|
692
1025
|
}
|
|
1026
|
+
//subscribe to states
|
|
1027
|
+
this.subscribeForeignStatesAsync(deviceQualityDP);
|
|
693
1028
|
|
|
694
|
-
|
|
695
|
-
switch (typeof deviceQualityState.val) {
|
|
696
|
-
case 'number':
|
|
697
|
-
if (this.config.trueState) {
|
|
698
|
-
linkQuality = deviceQualityState.val;
|
|
699
|
-
} else {
|
|
700
|
-
switch (adapterID) {
|
|
701
|
-
case 'roomba':
|
|
702
|
-
case 'sonoff':
|
|
703
|
-
linkQuality = deviceQualityState.val + '%'; // If quality state is already an percent value
|
|
704
|
-
break;
|
|
705
|
-
case 'lupusec':
|
|
706
|
-
linkQuality = deviceQualityState.val;
|
|
707
|
-
break;
|
|
708
|
-
|
|
709
|
-
default:
|
|
710
|
-
// If quality state is an RSSI value calculate in percent:
|
|
711
|
-
if (deviceQualityState.val == -255) {
|
|
712
|
-
linkQuality = ' - ';
|
|
713
|
-
} else if (deviceQualityState.val < 0) {
|
|
714
|
-
linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
|
|
715
|
-
// If Quality State is an value between 0-255 (zigbee) calculate in percent:
|
|
716
|
-
} else if (deviceQualityState.val >= 0) {
|
|
717
|
-
linkQuality = parseFloat(((100 / 255) * deviceQualityState.val).toFixed(0)) + '%';
|
|
718
|
-
}
|
|
719
|
-
break;
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
break;
|
|
723
|
-
|
|
724
|
-
case 'string':
|
|
725
|
-
switch (adapterID) {
|
|
726
|
-
case 'netatmo':
|
|
727
|
-
// for Netatmo devices
|
|
728
|
-
linkQuality = deviceQualityState.val;
|
|
729
|
-
break;
|
|
730
|
-
case 'nukiExt':
|
|
731
|
-
linkQuality = ' - ';
|
|
732
|
-
break;
|
|
733
|
-
case 'mqttNuki':
|
|
734
|
-
linkQuality = deviceQualityState.val;
|
|
735
|
-
mqttNukiValue = parseInt(linkQuality);
|
|
736
|
-
if (this.config.trueState) {
|
|
737
|
-
linkQuality = deviceQualityState.val;
|
|
738
|
-
} else if (mqttNukiValue < 0) {
|
|
739
|
-
linkQuality = Math.min(Math.max(2 * (mqttNukiValue + 100), 0), 100) + '%';
|
|
740
|
-
// If Quality State is an value between 0-255 (zigbee) calculate in percent:
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
break;
|
|
744
|
-
}
|
|
745
|
-
} else {
|
|
746
|
-
linkQuality = ' - ';
|
|
747
|
-
}
|
|
1029
|
+
let linkQuality = await this.calculateSignalStrength(deviceQualityState, adapterID);
|
|
748
1030
|
|
|
749
1031
|
/*=============================================
|
|
750
1032
|
= Get battery data =
|
|
751
1033
|
=============================================*/
|
|
752
|
-
let
|
|
753
|
-
let
|
|
754
|
-
let isBatteryDevice;
|
|
755
|
-
|
|
1034
|
+
let deviceBatteryStateDP;
|
|
1035
|
+
let deviceBatteryState;
|
|
756
1036
|
// Get battery states
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
// Get low bat states
|
|
769
|
-
let deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat);
|
|
770
|
-
if (deviceLowBatState === undefined) {
|
|
771
|
-
deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat2);
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
if (deviceBatteryState === undefined && shortDeviceBatteryState === undefined) {
|
|
775
|
-
if (deviceLowBatState !== undefined) {
|
|
776
|
-
switch (this.arrDev[i].isLowBat || this.arrDev[i].isLowBat2) {
|
|
777
|
-
case 'none':
|
|
778
|
-
batteryHealth = ' - ';
|
|
779
|
-
break;
|
|
780
|
-
default:
|
|
781
|
-
if (deviceLowBatState === false || deviceLowBatState === 'NORMAL' || deviceLowBatState === 1) {
|
|
782
|
-
batteryHealth = 'ok';
|
|
783
|
-
isBatteryDevice = true;
|
|
784
|
-
} else {
|
|
785
|
-
batteryHealth = 'low';
|
|
786
|
-
isBatteryDevice = true;
|
|
787
|
-
}
|
|
788
|
-
break;
|
|
789
|
-
}
|
|
790
|
-
} else {
|
|
791
|
-
batteryHealth = ' - ';
|
|
792
|
-
}
|
|
793
|
-
} else {
|
|
794
|
-
switch (adapterID) {
|
|
795
|
-
case 'hmrpc':
|
|
796
|
-
if (deviceBatteryState === 0 || (deviceBatteryState && deviceBatteryState >= 6)) {
|
|
797
|
-
batteryHealth = ' - ';
|
|
798
|
-
} else {
|
|
799
|
-
batteryHealth = deviceBatteryState + 'V';
|
|
800
|
-
isBatteryDevice = true;
|
|
801
|
-
}
|
|
802
|
-
break;
|
|
803
|
-
|
|
804
|
-
case 'hueExt':
|
|
805
|
-
case 'mihomeVacuum':
|
|
806
|
-
case 'mqttNuki':
|
|
807
|
-
if (shortDeviceBatteryState) {
|
|
808
|
-
batteryHealth = shortDeviceBatteryState + '%';
|
|
809
|
-
isBatteryDevice = true;
|
|
810
|
-
}
|
|
811
|
-
break;
|
|
812
|
-
|
|
813
|
-
default:
|
|
814
|
-
batteryHealth = deviceBatteryState + '%';
|
|
815
|
-
isBatteryDevice = true;
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
/*=============================================
|
|
820
|
-
= Set Lowbat indicator =
|
|
821
|
-
=============================================*/
|
|
822
|
-
switch (typeof deviceLowBatState) {
|
|
823
|
-
case 'number':
|
|
824
|
-
if (deviceLowBatState === 0) {
|
|
825
|
-
lowBatIndicator = true;
|
|
826
|
-
}
|
|
827
|
-
break;
|
|
828
|
-
|
|
829
|
-
case 'string':
|
|
830
|
-
if (deviceLowBatState !== 'NORMAL') {
|
|
831
|
-
// Tado devices
|
|
832
|
-
lowBatIndicator = true;
|
|
833
|
-
}
|
|
834
|
-
break;
|
|
835
|
-
|
|
836
|
-
case 'boolean':
|
|
837
|
-
if (deviceLowBatState) {
|
|
838
|
-
lowBatIndicator = true;
|
|
1037
|
+
switch (adapterID) {
|
|
1038
|
+
case 'hueExt':
|
|
1039
|
+
case 'mihomeVacuum':
|
|
1040
|
+
case 'mqttNuki':
|
|
1041
|
+
deviceBatteryStateDP = shortCurrDeviceString + this.arrDev[i].battery;
|
|
1042
|
+
deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
|
|
1043
|
+
if (deviceBatteryState === undefined) {
|
|
1044
|
+
deviceBatteryStateDP = shortCurrDeviceString + this.arrDev[i].battery2;
|
|
1045
|
+
deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
|
|
839
1046
|
}
|
|
840
1047
|
break;
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
1048
|
+
default:
|
|
1049
|
+
deviceBatteryStateDP = currDeviceString + this.arrDev[i].battery;
|
|
1050
|
+
deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
|
|
1051
|
+
if (deviceBatteryState === undefined) {
|
|
1052
|
+
deviceBatteryStateDP = currDeviceString + this.arrDev[i].battery2;
|
|
1053
|
+
deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
|
|
845
1054
|
}
|
|
846
1055
|
break;
|
|
847
1056
|
}
|
|
848
1057
|
|
|
849
|
-
|
|
850
|
-
=
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
/*=============================================
|
|
902
|
-
= Set Online Status =
|
|
903
|
-
=============================================*/
|
|
904
|
-
if (this.maxMinutes !== undefined) {
|
|
905
|
-
switch (adapterID) {
|
|
906
|
-
case 'hmrpc':
|
|
907
|
-
case 'hmiP':
|
|
908
|
-
case 'maxcube':
|
|
909
|
-
if (this.maxMinutes[adapterID] <= 0) {
|
|
910
|
-
if (deviceUnreachState) {
|
|
911
|
-
deviceState = 'Offline'; //set online state to offline
|
|
912
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
913
|
-
}
|
|
914
|
-
} else if (lastDeviceUnreachStateChange > this.maxMinutes[adapterID] && deviceUnreachState) {
|
|
915
|
-
deviceState = 'Offline'; //set online state to offline
|
|
916
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
917
|
-
}
|
|
918
|
-
break;
|
|
919
|
-
case 'apcups':
|
|
920
|
-
case 'hue':
|
|
921
|
-
case 'hueExt':
|
|
922
|
-
case 'ping':
|
|
923
|
-
case 'deconz':
|
|
924
|
-
case 'shelly':
|
|
925
|
-
case 'sonoff':
|
|
926
|
-
case 'unifi':
|
|
927
|
-
case 'zigbee':
|
|
928
|
-
case 'zigbee2MQTT':
|
|
929
|
-
if (this.maxMinutes[adapterID] <= 0) {
|
|
930
|
-
if (!deviceUnreachState) {
|
|
931
|
-
deviceState = 'Offline'; //set online state to offline
|
|
932
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
933
|
-
}
|
|
934
|
-
} else if (!deviceUnreachState && lastDeviceUnreachStateChange > this.maxMinutes[adapterID]) {
|
|
935
|
-
deviceState = 'Offline'; //set online state to offline
|
|
936
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
937
|
-
}
|
|
938
|
-
break;
|
|
939
|
-
case 'mqttClientZigbee2Mqtt':
|
|
940
|
-
if (this.maxMinutes[adapterID] <= 0) {
|
|
941
|
-
if (deviceUnreachState !== 'online') {
|
|
942
|
-
deviceState = 'Offline'; //set online state to offline
|
|
943
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
944
|
-
}
|
|
945
|
-
} else if (deviceUnreachState !== 'online' && lastDeviceUnreachStateChange > this.maxMinutes[adapterID]) {
|
|
946
|
-
deviceState = 'Offline'; //set online state to offline
|
|
947
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
948
|
-
}
|
|
949
|
-
break;
|
|
950
|
-
case 'mihomeVacuum':
|
|
951
|
-
if (this.maxMinutes[adapterID] <= 0) {
|
|
952
|
-
if (!shortDeviceUnreachState) {
|
|
953
|
-
deviceState = 'Offline'; //set online state to offline
|
|
954
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
955
|
-
}
|
|
956
|
-
} else if (lastContact > this.maxMinutes[adapterID]) {
|
|
957
|
-
deviceState = 'Offline'; //set online state to offline
|
|
958
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
959
|
-
}
|
|
960
|
-
break;
|
|
961
|
-
case 'mihome':
|
|
962
|
-
if (this.arrDev[i].battery === 'none') {
|
|
963
|
-
if (this.maxMinutes[adapterID] <= 0) {
|
|
964
|
-
if (!deviceUnreachState) {
|
|
965
|
-
deviceState = 'Offline'; //set online state to offline
|
|
966
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
967
|
-
}
|
|
968
|
-
} else if (lastContact > this.maxMinutes[adapterID]) {
|
|
969
|
-
deviceState = 'Offline'; //set online state to offline
|
|
970
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
971
|
-
}
|
|
972
|
-
} else {
|
|
973
|
-
if (this.config.mihomeMaxMinutes <= 0) {
|
|
974
|
-
if (this.maxMinutes[adapterID] <= 0) {
|
|
975
|
-
deviceState = 'Offline'; //set online state to offline
|
|
976
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
977
|
-
}
|
|
978
|
-
} else if (lastContact > this.maxMinutes[adapterID]) {
|
|
979
|
-
deviceState = 'Offline'; //set online state to offline
|
|
980
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
break;
|
|
984
|
-
default:
|
|
985
|
-
if (this.maxMinutes[adapterID] <= 0) {
|
|
986
|
-
if (!deviceUnreachState) {
|
|
987
|
-
deviceState = 'Offline'; //set online state to offline
|
|
988
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
989
|
-
}
|
|
990
|
-
} else if (lastContact > this.maxMinutes[adapterID]) {
|
|
991
|
-
deviceState = 'Offline'; //set online state to offline
|
|
992
|
-
linkQuality = '0%'; // set linkQuality to nothing
|
|
993
|
-
}
|
|
994
|
-
break;
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
} catch (error) {
|
|
998
|
-
this.errorReporting('[getLastContact]', error);
|
|
999
|
-
}
|
|
1058
|
+
// Get low bat states
|
|
1059
|
+
let isLowBatDP = currDeviceString + this.arrDev[i].isLowBat;
|
|
1060
|
+
let deviceLowBatState = await this.getInitValue(isLowBatDP);
|
|
1061
|
+
if (deviceLowBatState === undefined) {
|
|
1062
|
+
isLowBatDP = currDeviceString + this.arrDev[i].isLowBat2;
|
|
1063
|
+
deviceLowBatState = await this.getInitValue(isLowBatDP);
|
|
1064
|
+
}
|
|
1065
|
+
if (deviceLowBatState === undefined) isLowBatDP = 'none';
|
|
1066
|
+
|
|
1067
|
+
//subscribe to states
|
|
1068
|
+
this.subscribeForeignStatesAsync(deviceBatteryStateDP);
|
|
1069
|
+
this.subscribeForeignStatesAsync(isLowBatDP);
|
|
1070
|
+
|
|
1071
|
+
const batteryData = await this.getBatteryData(deviceBatteryState, deviceLowBatState, adapterID);
|
|
1072
|
+
const batteryHealth = batteryData[0];
|
|
1073
|
+
const batteryHealthRaw = batteryData[2];
|
|
1074
|
+
const isBatteryDevice = batteryData[1];
|
|
1075
|
+
let lowBatIndicator;
|
|
1076
|
+
|
|
1077
|
+
if (isBatteryDevice) {
|
|
1078
|
+
lowBatIndicator = await this.setLowbatIndicator(deviceBatteryState, deviceLowBatState, isLowBatDP);
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/*=============================================
|
|
1082
|
+
= Get last contact of device =
|
|
1083
|
+
=============================================*/
|
|
1084
|
+
let unreachDP = currDeviceString + this.arrDev[i].reach;
|
|
1085
|
+
const deviceStateSelectorDP = shortCurrDeviceString + this.arrDev[i].stateValue;
|
|
1086
|
+
const rssiPeerSelectorDP = currDeviceString + this.arrDev[i].rssiPeerState;
|
|
1087
|
+
|
|
1088
|
+
let deviceUnreachState = await this.getInitValue(unreachDP);
|
|
1089
|
+
if (deviceUnreachState === undefined) {
|
|
1090
|
+
unreachDP = shortCurrDeviceString + this.arrDev[i].reach;
|
|
1091
|
+
deviceUnreachState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].reach);
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
// subscribe to states
|
|
1095
|
+
this.subscribeForeignStatesAsync(id);
|
|
1096
|
+
this.subscribeForeignStatesAsync(unreachDP);
|
|
1097
|
+
this.subscribeForeignStatesAsync(deviceStateSelectorDP);
|
|
1098
|
+
this.subscribeForeignStatesAsync(rssiPeerSelectorDP);
|
|
1099
|
+
|
|
1100
|
+
const onlineState = await this.getOnlineState(id, adapterID, unreachDP, linkQuality, deviceUnreachState, deviceStateSelectorDP, rssiPeerSelectorDP);
|
|
1101
|
+
let deviceState;
|
|
1102
|
+
let lastContactString;
|
|
1103
|
+
|
|
1104
|
+
if (onlineState) {
|
|
1105
|
+
lastContactString = onlineState[0];
|
|
1106
|
+
deviceState = onlineState[1];
|
|
1107
|
+
linkQuality = onlineState[2];
|
|
1000
1108
|
}
|
|
1109
|
+
|
|
1001
1110
|
/*=============================================
|
|
1002
1111
|
= Get update data =
|
|
1003
1112
|
=============================================*/
|
|
1004
|
-
|
|
1113
|
+
const deviceUpdateDP = currDeviceString + this.arrDev[i].upgrade;
|
|
1005
1114
|
let isUpgradable;
|
|
1006
1115
|
|
|
1007
1116
|
if (this.config.checkSendDeviceUpgrade) {
|
|
1008
|
-
deviceUpdateSelector = await this.getInitValue(
|
|
1117
|
+
const deviceUpdateSelector = await this.getInitValue(deviceUpdateDP);
|
|
1118
|
+
|
|
1009
1119
|
if (deviceUpdateSelector) {
|
|
1010
1120
|
isUpgradable = true;
|
|
1011
|
-
} else {
|
|
1121
|
+
} else if (!deviceUpdateSelector) {
|
|
1012
1122
|
isUpgradable = false;
|
|
1013
1123
|
}
|
|
1124
|
+
// subscribe to states
|
|
1125
|
+
this.subscribeForeignStatesAsync(deviceUpdateDP);
|
|
1014
1126
|
}
|
|
1015
1127
|
|
|
1016
1128
|
/*=============================================
|
|
@@ -1018,33 +1130,51 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1018
1130
|
=============================================*/
|
|
1019
1131
|
|
|
1020
1132
|
/* Add only devices with battery in the rawlist */
|
|
1021
|
-
if (this.listOnlyBattery) {
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1133
|
+
if (this.listOnlyBattery && isBatteryDevice) {
|
|
1134
|
+
this.listAllDevicesRaw.push({
|
|
1135
|
+
Path: id,
|
|
1136
|
+
Device: deviceName,
|
|
1137
|
+
adapterID: adapterID,
|
|
1138
|
+
Adapter: adapter,
|
|
1139
|
+
isBatteryDevice: isBatteryDevice,
|
|
1140
|
+
Battery: batteryHealth,
|
|
1141
|
+
BatteryRaw: batteryHealthRaw,
|
|
1142
|
+
batteryDP: deviceBatteryStateDP,
|
|
1143
|
+
LowBat: lowBatIndicator,
|
|
1144
|
+
LowBatDP: isLowBatDP,
|
|
1145
|
+
SignalStrengthDP: deviceQualityDP,
|
|
1146
|
+
SignalStrength: linkQuality,
|
|
1147
|
+
UnreachState: deviceUnreachState,
|
|
1148
|
+
UnreachDP: unreachDP,
|
|
1149
|
+
DeviceStateSelectorDP: deviceStateSelectorDP,
|
|
1150
|
+
rssiPeerSelectorDP: rssiPeerSelectorDP,
|
|
1151
|
+
LastContact: lastContactString,
|
|
1152
|
+
Status: deviceState,
|
|
1153
|
+
UpdateDP: deviceUpdateDP,
|
|
1154
|
+
Upgradable: isUpgradable,
|
|
1155
|
+
});
|
|
1036
1156
|
} else {
|
|
1037
1157
|
/* Add all devices */
|
|
1038
1158
|
this.listAllDevicesRaw.push({
|
|
1039
1159
|
Path: id,
|
|
1040
1160
|
Device: deviceName,
|
|
1161
|
+
adapterID: adapterID,
|
|
1041
1162
|
Adapter: adapter,
|
|
1042
1163
|
isBatteryDevice: isBatteryDevice,
|
|
1043
1164
|
Battery: batteryHealth,
|
|
1165
|
+
BatteryRaw: batteryHealthRaw,
|
|
1166
|
+
batteryDP: deviceBatteryStateDP,
|
|
1044
1167
|
LowBat: lowBatIndicator,
|
|
1045
|
-
|
|
1046
|
-
|
|
1168
|
+
LowBatDP: isLowBatDP,
|
|
1169
|
+
SignalStrengthDP: deviceQualityDP,
|
|
1170
|
+
SignalStrength: linkQuality,
|
|
1171
|
+
UnreachState: deviceUnreachState,
|
|
1172
|
+
UnreachDP: unreachDP,
|
|
1173
|
+
DeviceStateSelectorDP: deviceStateSelectorDP,
|
|
1174
|
+
rssiPeerSelectorDP: rssiPeerSelectorDP,
|
|
1175
|
+
LastContact: lastContactString,
|
|
1047
1176
|
Status: deviceState,
|
|
1177
|
+
UpdateDP: deviceUpdateDP,
|
|
1048
1178
|
Upgradable: isUpgradable,
|
|
1049
1179
|
});
|
|
1050
1180
|
}
|
|
@@ -1053,10 +1183,133 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1053
1183
|
return;
|
|
1054
1184
|
}
|
|
1055
1185
|
} // <-- end of loop
|
|
1056
|
-
await this.createLists();
|
|
1057
|
-
await this.countDevices();
|
|
1058
1186
|
} // <-- end of createData
|
|
1059
1187
|
|
|
1188
|
+
/**
|
|
1189
|
+
* Create Lists
|
|
1190
|
+
*/
|
|
1191
|
+
async createLists(adptName) {
|
|
1192
|
+
this.linkQualityDevices = [];
|
|
1193
|
+
this.batteryPowered = [];
|
|
1194
|
+
this.batteryLowPowered = [];
|
|
1195
|
+
this.listAllDevices = [];
|
|
1196
|
+
this.offlineDevices = [];
|
|
1197
|
+
this.batteryLowPoweredRaw = [];
|
|
1198
|
+
this.offlineDevicesRaw = [];
|
|
1199
|
+
this.upgradableList = [];
|
|
1200
|
+
|
|
1201
|
+
if (adptName === undefined) {
|
|
1202
|
+
adptName = '';
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
for (const device of this.listAllDevicesRaw) {
|
|
1206
|
+
if (device.adapterID.includes(adptName)) {
|
|
1207
|
+
/*---------- fill raw lists ----------*/
|
|
1208
|
+
// low bat list
|
|
1209
|
+
if (device.LowBat && device.Status !== 'Offline') {
|
|
1210
|
+
this.batteryLowPoweredRaw.push({
|
|
1211
|
+
Path: device.Path,
|
|
1212
|
+
Device: device.Device,
|
|
1213
|
+
Adapter: device.Adapter,
|
|
1214
|
+
Battery: device.Battery,
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
// offline raw list
|
|
1218
|
+
if (device.Status === 'Offline') {
|
|
1219
|
+
this.offlineDevicesRaw.push({
|
|
1220
|
+
Path: device.Path,
|
|
1221
|
+
Device: device.Device,
|
|
1222
|
+
Adapter: device.Adapter,
|
|
1223
|
+
'Last contact': device.LastContact,
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
/*---------- fill user lists ----------*/
|
|
1228
|
+
if (!this.blacklistLists.includes(device.Path)) {
|
|
1229
|
+
this.listAllDevices.push({
|
|
1230
|
+
Device: device.Device,
|
|
1231
|
+
Adapter: device.Adapter,
|
|
1232
|
+
Battery: device.Battery,
|
|
1233
|
+
'Signal strength': device.SignalStrength,
|
|
1234
|
+
'Last contact': device.LastContact,
|
|
1235
|
+
Status: device.Status,
|
|
1236
|
+
});
|
|
1237
|
+
// LinkQuality lists
|
|
1238
|
+
if (device.SignalStrength != ' - ') {
|
|
1239
|
+
this.linkQualityDevices.push({
|
|
1240
|
+
Device: device.Device,
|
|
1241
|
+
Adapter: device.Adapter,
|
|
1242
|
+
'Signal strength': device.SignalStrength,
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
// Battery lists
|
|
1246
|
+
if (device['isBatteryDevice']) {
|
|
1247
|
+
this.batteryPowered.push({
|
|
1248
|
+
Device: device.Device,
|
|
1249
|
+
Adapter: device.Adapter,
|
|
1250
|
+
Battery: device.Battery,
|
|
1251
|
+
Status: device.Status,
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
// Low Bat lists
|
|
1255
|
+
if (device.LowBat && device.Status !== 'Offline') {
|
|
1256
|
+
this.batteryLowPowered.push({
|
|
1257
|
+
Device: device.Device,
|
|
1258
|
+
Adapter: device.Adapter,
|
|
1259
|
+
Battery: device.Battery,
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
// Offline List
|
|
1264
|
+
if (device.Status === 'Offline') {
|
|
1265
|
+
this.offlineDevices.push({
|
|
1266
|
+
Device: device.Device,
|
|
1267
|
+
Adapter: device.Adapter,
|
|
1268
|
+
'Last contact': device.LastContact,
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
// Device update List
|
|
1273
|
+
if (device.Upgradable) {
|
|
1274
|
+
this.upgradableList.push({
|
|
1275
|
+
Device: device.Device,
|
|
1276
|
+
Adapter: device.Adapter,
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
await this.countDevices();
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
/**
|
|
1286
|
+
* Count devices for each type
|
|
1287
|
+
*/
|
|
1288
|
+
async countDevices() {
|
|
1289
|
+
// Count how many devices with link Quality
|
|
1290
|
+
this.linkQualityCount = this.linkQualityDevices.length;
|
|
1291
|
+
|
|
1292
|
+
// Count how many devcies are offline
|
|
1293
|
+
this.offlineDevicesCount = this.offlineDevices.length;
|
|
1294
|
+
|
|
1295
|
+
// Count how many devices are with battery
|
|
1296
|
+
this.batteryPoweredCount = this.batteryPowered.length;
|
|
1297
|
+
|
|
1298
|
+
// 3d. Count how many devices are with low battery
|
|
1299
|
+
this.lowBatteryPoweredCount = this.batteryLowPowered.length;
|
|
1300
|
+
|
|
1301
|
+
// Count how many devices are exists
|
|
1302
|
+
this.deviceCounter = this.listAllDevices.length;
|
|
1303
|
+
|
|
1304
|
+
// Count how many devices has update available
|
|
1305
|
+
this.upgradableDevicesCount = this.upgradableList.length;
|
|
1306
|
+
|
|
1307
|
+
// raws
|
|
1308
|
+
|
|
1309
|
+
// Count how many devcies are offline
|
|
1310
|
+
this.offlineDevicesCountRaw = this.offlineDevicesRaw.length;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1060
1313
|
/**
|
|
1061
1314
|
* @param {string} adptName - Adapter name
|
|
1062
1315
|
*/
|
|
@@ -1064,13 +1317,12 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1064
1317
|
// create Data for each Adapter in own lists
|
|
1065
1318
|
this.log.debug(`Function started: ${this.createDataForEachAdapter.name}`);
|
|
1066
1319
|
|
|
1067
|
-
await this.resetVars(); // reset the arrays and counts
|
|
1068
|
-
|
|
1069
1320
|
try {
|
|
1070
|
-
for (
|
|
1071
|
-
if (
|
|
1321
|
+
for (const device of this.listAllDevicesRaw) {
|
|
1322
|
+
if (device.adapterID.includes(adptName)) {
|
|
1072
1323
|
// list device only if selected adapter matched with device
|
|
1073
|
-
await this.
|
|
1324
|
+
await this.createLists(adptName);
|
|
1325
|
+
await this.writeDatapoints(adptName);
|
|
1074
1326
|
}
|
|
1075
1327
|
}
|
|
1076
1328
|
|
|
@@ -1089,22 +1341,10 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1089
1341
|
this.log.debug(`Function started: ${this.createDataOfAllAdapter.name}`);
|
|
1090
1342
|
|
|
1091
1343
|
try {
|
|
1092
|
-
await this.resetVars(); // reset the arrays and counts
|
|
1093
|
-
|
|
1094
1344
|
for (let i = 0; i < this.arrDev.length; i++) {
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
} else {
|
|
1098
|
-
return; // cancel run if unloaded was called.
|
|
1099
|
-
}
|
|
1345
|
+
await this.createData(i);
|
|
1346
|
+
await this.createLists();
|
|
1100
1347
|
}
|
|
1101
|
-
|
|
1102
|
-
// send message if new devices are offline
|
|
1103
|
-
if (this.config.checkSendOfflineMsg) await this.sendOfflineNotifications();
|
|
1104
|
-
|
|
1105
|
-
// send overview of upgradable devices
|
|
1106
|
-
if (this.config.checkSendDeviceUpgrade) await this.sendDeviceUpdatesNotification();
|
|
1107
|
-
|
|
1108
1348
|
await this.writeDatapoints(); // fill the datapoints
|
|
1109
1349
|
} catch (error) {
|
|
1110
1350
|
this.errorReporting('[createDataOfAllAdapter]', error);
|
|
@@ -1291,12 +1531,12 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1291
1531
|
let deviceList = '';
|
|
1292
1532
|
|
|
1293
1533
|
for (const id of this.batteryLowPoweredRaw) {
|
|
1294
|
-
if (!this.blacklistNotify.includes(id
|
|
1534
|
+
if (!this.blacklistNotify.includes(id.Path)) {
|
|
1295
1535
|
if (!this.config.showAdapterNameinMsg) {
|
|
1296
|
-
deviceList = `${deviceList}\n${id
|
|
1536
|
+
deviceList = `${deviceList}\n${id.Device} (${id.Battery})`;
|
|
1297
1537
|
} else {
|
|
1298
1538
|
// Add adaptername if checkbox is checked true in options by user
|
|
1299
|
-
deviceList = `${deviceList}\n${id
|
|
1539
|
+
deviceList = `${deviceList}\n${id.Adapter}: ${id.Device} (${id.Battery})`;
|
|
1300
1540
|
}
|
|
1301
1541
|
}
|
|
1302
1542
|
}
|
|
@@ -1313,41 +1553,66 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1313
1553
|
}
|
|
1314
1554
|
} //<--End of battery notification
|
|
1315
1555
|
|
|
1556
|
+
/**
|
|
1557
|
+
* check if device updates are available and send notification
|
|
1558
|
+
* @param {string} deviceName
|
|
1559
|
+
* @param {string} adapter
|
|
1560
|
+
* @param {string} battery
|
|
1561
|
+
**/
|
|
1562
|
+
async sendLowBatNoticiation(deviceName, adapter, battery) {
|
|
1563
|
+
this.log.debug(`Start the function: ${this.sendLowBatNoticiation.name}`);
|
|
1564
|
+
|
|
1565
|
+
try {
|
|
1566
|
+
let msg = '';
|
|
1567
|
+
let deviceList = '';
|
|
1568
|
+
|
|
1569
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
1570
|
+
deviceList = `${deviceList}\n${deviceName} (${battery})`;
|
|
1571
|
+
} else {
|
|
1572
|
+
deviceList = `${deviceList}\n${adapter}: ${deviceName} (${battery})`;
|
|
1573
|
+
}
|
|
1574
|
+
msg = `Gerät mit geringer Batterie erkannt: \n`;
|
|
1575
|
+
|
|
1576
|
+
this.log.info(msg + deviceList);
|
|
1577
|
+
await this.setStateAsync('lastNotification', msg + deviceList, true);
|
|
1578
|
+
await this.sendNotification(msg + deviceList);
|
|
1579
|
+
} catch (error) {
|
|
1580
|
+
this.errorReporting('[sendLowBatNoticiation]', error);
|
|
1581
|
+
}
|
|
1582
|
+
this.log.debug(`Finished the function: ${this.sendLowBatNoticiation.name}`);
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1316
1585
|
/**
|
|
1317
1586
|
* send message if an device is offline
|
|
1587
|
+
* @param {string} deviceName
|
|
1588
|
+
* @param {string} adapter
|
|
1589
|
+
* @param {string} status
|
|
1590
|
+
* @param {string} lastContact
|
|
1318
1591
|
*/
|
|
1319
|
-
async sendOfflineNotifications() {
|
|
1592
|
+
async sendOfflineNotifications(deviceName, adapter, status, lastContact) {
|
|
1320
1593
|
this.log.debug(`Start the function: ${this.sendOfflineNotifications.name}`);
|
|
1321
1594
|
|
|
1322
1595
|
try {
|
|
1323
1596
|
let msg = '';
|
|
1324
1597
|
let deviceList = '';
|
|
1325
1598
|
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
} else {
|
|
1331
|
-
deviceList = `${deviceList}\n${id['Adapter']}: ${id['Device']} (${id['Last contact']})`;
|
|
1332
|
-
}
|
|
1333
|
-
}
|
|
1599
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
1600
|
+
deviceList = `${deviceList}\n${deviceName} (${lastContact})`;
|
|
1601
|
+
} else {
|
|
1602
|
+
deviceList = `${deviceList}\n${adapter}: ${deviceName} (${lastContact})`;
|
|
1334
1603
|
}
|
|
1335
|
-
if (deviceList.length !== this.offlineDevicesCountRawOld) {
|
|
1336
|
-
if (deviceList.length === 0) {
|
|
1337
|
-
msg = 'Alle Geräte sind Online.';
|
|
1338
|
-
} else if (deviceList.length === 1) {
|
|
1339
|
-
// make singular if it is only one device
|
|
1340
|
-
msg = 'Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n';
|
|
1341
|
-
} else if (deviceList.length >= 2) {
|
|
1342
|
-
//make plural if it is more than one device
|
|
1343
|
-
msg = `Folgende Geräte sind seit einiger Zeit nicht erreichbar: \n`;
|
|
1344
|
-
}
|
|
1345
1604
|
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1605
|
+
if (status === 'Online') {
|
|
1606
|
+
// make singular if it is only one device
|
|
1607
|
+
msg = 'Folgendes Gerät ist wieder erreichbar: \n';
|
|
1608
|
+
} else if (status === 'Offline') {
|
|
1609
|
+
//make plural if it is more than one device
|
|
1610
|
+
msg = `Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n`;
|
|
1350
1611
|
}
|
|
1612
|
+
|
|
1613
|
+
this.log.info(msg + deviceList);
|
|
1614
|
+
await this.setStateAsync('lastNotification', msg + deviceList, true);
|
|
1615
|
+
await this.sendNotification(msg + deviceList);
|
|
1351
1616
|
} catch (error) {
|
|
1352
1617
|
this.errorReporting('[sendOfflineMessage]', error);
|
|
1353
1618
|
}
|
|
@@ -1386,11 +1651,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1386
1651
|
let deviceList = '';
|
|
1387
1652
|
|
|
1388
1653
|
for (const id of this.offlineDevicesRaw) {
|
|
1389
|
-
if (!this.blacklistNotify.includes(id
|
|
1654
|
+
if (!this.blacklistNotify.includes(id.Path)) {
|
|
1390
1655
|
if (!this.config.showAdapterNameinMsg) {
|
|
1391
|
-
deviceList = `${deviceList}\n${id
|
|
1656
|
+
deviceList = `${deviceList}\n${id.Device} (${id.LastContact})`;
|
|
1392
1657
|
} else {
|
|
1393
|
-
deviceList = `${deviceList}\n${id
|
|
1658
|
+
deviceList = `${deviceList}\n${id.Adapter}: ${id.Device} (${id.LastContact})`;
|
|
1394
1659
|
}
|
|
1395
1660
|
}
|
|
1396
1661
|
}
|
|
@@ -1408,69 +1673,29 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1408
1673
|
}
|
|
1409
1674
|
} //<--End of daily offline notification
|
|
1410
1675
|
|
|
1411
|
-
/**
|
|
1412
|
-
* check if adapter updates are available and send notification
|
|
1413
|
-
* @param {string} id
|
|
1414
|
-
* @param {ioBroker.State | null | undefined} state
|
|
1415
|
-
*/
|
|
1416
|
-
/*
|
|
1417
|
-
async sendAdapterUpdatesNotification(id, state) {
|
|
1418
|
-
this.log.debug(`Start the function: ${this.sendAdapterUpdatesNotification.name}`);
|
|
1419
|
-
|
|
1420
|
-
try {
|
|
1421
|
-
if (state && state !== undefined) {
|
|
1422
|
-
const list = await this.parseData(state.val);
|
|
1423
|
-
let msg = '';
|
|
1424
|
-
let adapterList = '';
|
|
1425
|
-
|
|
1426
|
-
for (const [id] of Object.entries(list)) {
|
|
1427
|
-
adapterList = `${adapterList}\n${this.capitalize(id)} - Version: ${list[id].availableVersion}`;
|
|
1428
|
-
}
|
|
1429
|
-
if (adapterList.length !== 0) {
|
|
1430
|
-
msg = `Neue Adapter Updates vorhanden: \n`;
|
|
1431
|
-
|
|
1432
|
-
this.log.info(msg + adapterList);
|
|
1433
|
-
await this.setStateAsync('lastNotification', msg + adapterList, true);
|
|
1434
|
-
await this.sendNotification(msg + adapterList);
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
} catch (error) {
|
|
1438
|
-
this.errorReporting('[sendAdapterUpdatesNotification]', error);
|
|
1439
|
-
}
|
|
1440
|
-
this.log.debug(`Finished the function: ${this.sendAdapterUpdatesNotification.name}`);
|
|
1441
|
-
}*/
|
|
1442
|
-
|
|
1443
1676
|
/**
|
|
1444
1677
|
* check if device updates are available and send notification
|
|
1678
|
+
* @param {string} deviceName
|
|
1679
|
+
* @param {string} adapter
|
|
1445
1680
|
**/
|
|
1446
|
-
async sendDeviceUpdatesNotification() {
|
|
1681
|
+
async sendDeviceUpdatesNotification(deviceName, adapter) {
|
|
1447
1682
|
this.log.debug(`Start the function: ${this.sendDeviceUpdatesNotification.name}`);
|
|
1448
1683
|
|
|
1449
1684
|
try {
|
|
1450
1685
|
let msg = '';
|
|
1451
1686
|
let deviceList = '';
|
|
1452
1687
|
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
} else {
|
|
1458
|
-
deviceList = `${deviceList}\n${id['Adapter']}: ${id['Device']}`;
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
if (deviceList.length !== this.upgradableDevicesCountRawOld) {
|
|
1463
|
-
if (deviceList.length >= 1) {
|
|
1464
|
-
msg = `Neue Geräte Updates vorhanden: \n`;
|
|
1465
|
-
|
|
1466
|
-
this.log.info(msg + deviceList);
|
|
1467
|
-
this.upgradableDevicesCountRawOld = deviceList.length;
|
|
1468
|
-
await this.setStateAsync('lastNotification', msg + deviceList, true);
|
|
1469
|
-
await this.sendNotification(msg + deviceList);
|
|
1470
|
-
} else {
|
|
1471
|
-
this.upgradableDevicesCountRawOld = deviceList.length;
|
|
1472
|
-
}
|
|
1688
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
1689
|
+
deviceList = `${deviceList}\n${deviceName}`;
|
|
1690
|
+
} else {
|
|
1691
|
+
deviceList = `${deviceList}\n${adapter}: ${deviceName}`;
|
|
1473
1692
|
}
|
|
1693
|
+
|
|
1694
|
+
msg = `Neue Geräte Updates vorhanden: \n`;
|
|
1695
|
+
|
|
1696
|
+
this.log.info(msg + deviceList);
|
|
1697
|
+
await this.setStateAsync('lastNotification', msg + deviceList, true);
|
|
1698
|
+
await this.sendNotification(msg + deviceList);
|
|
1474
1699
|
} catch (error) {
|
|
1475
1700
|
this.errorReporting('[sendDeviceUpdatesNotification]', error);
|
|
1476
1701
|
}
|
|
@@ -1478,35 +1703,58 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1478
1703
|
}
|
|
1479
1704
|
|
|
1480
1705
|
/**
|
|
1481
|
-
*
|
|
1706
|
+
* send shedule message with offline devices
|
|
1482
1707
|
*/
|
|
1483
|
-
async
|
|
1484
|
-
|
|
1485
|
-
this.log.debug(`Function started: ${this.resetVars.name}`);
|
|
1708
|
+
async sendUpgradeNotificationsShedule() {
|
|
1709
|
+
const time = this.config.checkSendUpgradeTime.split(':');
|
|
1486
1710
|
|
|
1487
|
-
//
|
|
1488
|
-
this.offlineDevices = [];
|
|
1489
|
-
this.linkQualityDevices = [];
|
|
1490
|
-
this.batteryPowered = [];
|
|
1491
|
-
this.batteryLowPowered = [];
|
|
1492
|
-
this.listAllDevices = [];
|
|
1493
|
-
this.listAllDevicesRaw = [];
|
|
1711
|
+
const checkDays = []; // list of selected days
|
|
1494
1712
|
|
|
1495
|
-
//
|
|
1496
|
-
this.
|
|
1497
|
-
this.
|
|
1498
|
-
this.
|
|
1499
|
-
this.
|
|
1713
|
+
// push the selected days in list
|
|
1714
|
+
if (this.config.checkUpgradeMonday) checkDays.push(1);
|
|
1715
|
+
if (this.config.checkUpgradeTuesday) checkDays.push(2);
|
|
1716
|
+
if (this.config.checkUpgradeWednesday) checkDays.push(3);
|
|
1717
|
+
if (this.config.checkUpgradeThursday) checkDays.push(4);
|
|
1718
|
+
if (this.config.checkUpgradeFriday) checkDays.push(5);
|
|
1719
|
+
if (this.config.checkUpgradeSaturday) checkDays.push(6);
|
|
1720
|
+
if (this.config.checkUpgradeSunday) checkDays.push(0);
|
|
1500
1721
|
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1722
|
+
if (checkDays.length >= 1) {
|
|
1723
|
+
// check if an day is selected
|
|
1724
|
+
this.log.debug(`Number of selected days for daily Upgrade message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
1725
|
+
} else {
|
|
1726
|
+
this.log.warn(`No days selected for daily Upgrade message. Please check the instance configuration!`);
|
|
1727
|
+
return; // cancel function if no day is selected
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
if (!isUnloaded) {
|
|
1731
|
+
const cron = '10 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
1732
|
+
schedule.scheduleJob(cron, () => {
|
|
1733
|
+
try {
|
|
1734
|
+
let deviceList = '';
|
|
1735
|
+
|
|
1736
|
+
for (const id of this.upgradableList) {
|
|
1737
|
+
if (!this.blacklistNotify.includes(id.Path)) {
|
|
1738
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
1739
|
+
deviceList = `${deviceList}\n${id.Device}`;
|
|
1740
|
+
} else {
|
|
1741
|
+
deviceList = `${deviceList}\n${id.Adapter}: ${id.Device}`;
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
if (deviceList.length > 0) {
|
|
1747
|
+
this.log.info(`Geräte Upgrade: ${deviceList}`);
|
|
1748
|
+
this.setStateAsync('lastNotification', `Geräte Upgrade: ${deviceList}`, true);
|
|
1507
1749
|
|
|
1508
|
-
|
|
1509
|
-
|
|
1750
|
+
this.sendNotification(`Geräte Upgrade:\n${deviceList}`);
|
|
1751
|
+
}
|
|
1752
|
+
} catch (error) {
|
|
1753
|
+
this.errorReporting('[sendUpgradeNotificationsShedule]', error);
|
|
1754
|
+
}
|
|
1755
|
+
});
|
|
1756
|
+
}
|
|
1757
|
+
} //<--End of daily offline notification
|
|
1510
1758
|
|
|
1511
1759
|
/**
|
|
1512
1760
|
* @param {string} [adptName] - Adaptername
|
|
@@ -1529,6 +1777,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1529
1777
|
await this.setStateAsync(`${dpSubFolder}countAll`, { val: this.deviceCounter, ack: true });
|
|
1530
1778
|
await this.setStateAsync(`${dpSubFolder}batteryCount`, { val: this.batteryPoweredCount, ack: true });
|
|
1531
1779
|
await this.setStateAsync(`${dpSubFolder}lowBatteryCount`, { val: this.lowBatteryPoweredCount, ack: true });
|
|
1780
|
+
await this.setStateAsync(`${dpSubFolder}upgradableCount`, { val: this.upgradableDevicesCount, ack: true });
|
|
1532
1781
|
|
|
1533
1782
|
if (this.deviceCounter === 0) {
|
|
1534
1783
|
// if no device is count, write the JSON List with default value
|
|
@@ -1545,12 +1794,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1545
1794
|
val: JSON.stringify(this.linkQualityDevices),
|
|
1546
1795
|
ack: true,
|
|
1547
1796
|
});
|
|
1548
|
-
//write HTML list
|
|
1549
|
-
if (this.config.createHtmlList)
|
|
1550
|
-
await this.setStateAsync(`${dpSubFolder}linkQualityListHTML`, {
|
|
1551
|
-
val: await this.creatLinkQualityListHTML(this.linkQualityDevices, this.linkQualityCount),
|
|
1552
|
-
ack: true,
|
|
1553
|
-
});
|
|
1554
1797
|
|
|
1555
1798
|
if (this.offlineDevicesCount === 0) {
|
|
1556
1799
|
// if no device is count, write the JSON List with default value
|
|
@@ -1561,12 +1804,16 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1561
1804
|
val: JSON.stringify(this.offlineDevices),
|
|
1562
1805
|
ack: true,
|
|
1563
1806
|
});
|
|
1564
|
-
|
|
1565
|
-
if (this.
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1807
|
+
|
|
1808
|
+
if (this.upgradableDevicesCount === 0) {
|
|
1809
|
+
// if no device is count, write the JSON List with default value
|
|
1810
|
+
this.upgradableList = [{ Device: '--none--', Adapter: '', 'Last contact': '' }];
|
|
1811
|
+
}
|
|
1812
|
+
//write JSON list
|
|
1813
|
+
await this.setStateAsync(`${dpSubFolder}upgradableList`, {
|
|
1814
|
+
val: JSON.stringify(this.upgradableList),
|
|
1815
|
+
ack: true,
|
|
1816
|
+
});
|
|
1570
1817
|
|
|
1571
1818
|
if (this.batteryPoweredCount === 0) {
|
|
1572
1819
|
// if no device is count, write the JSON List with default value
|
|
@@ -1577,12 +1824,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1577
1824
|
val: JSON.stringify(this.batteryPowered),
|
|
1578
1825
|
ack: true,
|
|
1579
1826
|
});
|
|
1580
|
-
//write HTML list
|
|
1581
|
-
if (this.config.createHtmlList)
|
|
1582
|
-
await this.setStateAsync(`${dpSubFolder}batteryListHTML`, {
|
|
1583
|
-
val: await this.createBatteryListHTML(this.batteryPowered, this.batteryPoweredCount, false),
|
|
1584
|
-
ack: true,
|
|
1585
|
-
});
|
|
1586
1827
|
|
|
1587
1828
|
if (this.lowBatteryPoweredCount === 0) {
|
|
1588
1829
|
// if no device is count, write the JSON List with default value
|
|
@@ -1593,12 +1834,26 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1593
1834
|
val: JSON.stringify(this.batteryLowPowered),
|
|
1594
1835
|
ack: true,
|
|
1595
1836
|
});
|
|
1837
|
+
|
|
1596
1838
|
//write HTML list
|
|
1597
|
-
if (this.config.createHtmlList)
|
|
1839
|
+
if (this.config.createHtmlList) {
|
|
1840
|
+
await this.setStateAsync(`${dpSubFolder}linkQualityListHTML`, {
|
|
1841
|
+
val: await this.creatLinkQualityListHTML(this.linkQualityDevices, this.linkQualityCount),
|
|
1842
|
+
ack: true,
|
|
1843
|
+
});
|
|
1844
|
+
await this.setStateAsync(`${dpSubFolder}offlineListHTML`, {
|
|
1845
|
+
val: await this.createOfflineListHTML(this.offlineDevices, this.offlineDevicesCount),
|
|
1846
|
+
ack: true,
|
|
1847
|
+
});
|
|
1848
|
+
await this.setStateAsync(`${dpSubFolder}batteryListHTML`, {
|
|
1849
|
+
val: await this.createBatteryListHTML(this.batteryPowered, this.batteryPoweredCount, false),
|
|
1850
|
+
ack: true,
|
|
1851
|
+
});
|
|
1598
1852
|
await this.setStateAsync(`${dpSubFolder}lowBatteryListHTML`, {
|
|
1599
1853
|
val: await this.createBatteryListHTML(this.batteryLowPowered, this.lowBatteryPoweredCount, true),
|
|
1600
1854
|
ack: true,
|
|
1601
1855
|
});
|
|
1856
|
+
}
|
|
1602
1857
|
|
|
1603
1858
|
// create timestamp of last run
|
|
1604
1859
|
const lastCheck = this.formatDate(new Date(), 'DD.MM.YYYY') + ' - ' + this.formatDate(new Date(), 'hh:mm:ss');
|
|
@@ -1637,7 +1892,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1637
1892
|
html += `<tr>
|
|
1638
1893
|
<td><font>${device.Device}</font></td>
|
|
1639
1894
|
<td align=center><font>${device.Adapter}</font></td>
|
|
1640
|
-
<td align=right><font>${device
|
|
1895
|
+
<td align=right><font>${device.SignalStrength}</font></td>
|
|
1641
1896
|
</tr>`;
|
|
1642
1897
|
}
|
|
1643
1898
|
|
|
@@ -1673,7 +1928,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1673
1928
|
html += `<tr>
|
|
1674
1929
|
<td><font>${device.Device}</font></td>
|
|
1675
1930
|
<td align=center><font>${device.Adapter}</font></td>
|
|
1676
|
-
<td align=center><font color=orange>${device
|
|
1931
|
+
<td align=center><font color=orange>${device.LastContact}</font></td>
|
|
1677
1932
|
</tr>`;
|
|
1678
1933
|
}
|
|
1679
1934
|
|
|
@@ -1941,6 +2196,54 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1941
2196
|
},
|
|
1942
2197
|
native: {},
|
|
1943
2198
|
});
|
|
2199
|
+
|
|
2200
|
+
await this.setObjectNotExistsAsync(`${adptName}.upgradableCount`, {
|
|
2201
|
+
type: 'state',
|
|
2202
|
+
common: {
|
|
2203
|
+
name: {
|
|
2204
|
+
en: 'Number of devices with available updates ',
|
|
2205
|
+
de: 'Anzahl der Geräte mit verfügbaren Updates',
|
|
2206
|
+
ru: 'Количество устройств с доступными обновлениями',
|
|
2207
|
+
pt: 'Número de dispositivos com atualizações disponíveis',
|
|
2208
|
+
nl: 'Nummer van apparatuur met beschikbare updates',
|
|
2209
|
+
fr: 'Nombre de dispositifs avec mises à jour disponibles',
|
|
2210
|
+
it: 'Numero di dispositivi con aggiornamenti disponibili',
|
|
2211
|
+
es: 'Número de dispositivos con actualizaciones disponibles',
|
|
2212
|
+
pl: 'Liczba urządzeń z dostępną aktualizacją',
|
|
2213
|
+
uk: 'Кількість пристроїв з доступними оновленнями',
|
|
2214
|
+
'zh-cn': '现有更新的装置数目',
|
|
2215
|
+
},
|
|
2216
|
+
type: 'number',
|
|
2217
|
+
role: 'value',
|
|
2218
|
+
read: true,
|
|
2219
|
+
write: false,
|
|
2220
|
+
},
|
|
2221
|
+
native: {},
|
|
2222
|
+
});
|
|
2223
|
+
|
|
2224
|
+
await this.setObjectNotExistsAsync(`${adptName}.upgradableList`, {
|
|
2225
|
+
type: 'state',
|
|
2226
|
+
common: {
|
|
2227
|
+
name: {
|
|
2228
|
+
en: 'JSON List of devices with available updates ',
|
|
2229
|
+
de: 'JSON Liste der Geräte mit verfügbaren Updates',
|
|
2230
|
+
ru: 'ДЖСОН Список устройств с доступными обновлениями',
|
|
2231
|
+
pt: 'J. Lista de dispositivos com atualizações disponíveis',
|
|
2232
|
+
nl: 'JSON List van apparatuur met beschikbare updates',
|
|
2233
|
+
fr: 'JSON Liste des appareils avec mises à jour disponibles',
|
|
2234
|
+
it: 'JSON Elenco dei dispositivi con aggiornamenti disponibili',
|
|
2235
|
+
es: 'JSON Lista de dispositivos con actualizaciones disponibles',
|
|
2236
|
+
pl: 'JSON Lista urządzeń korzystających z aktualizacji',
|
|
2237
|
+
uk: 'Сонце Перелік пристроїв з доступними оновленнями',
|
|
2238
|
+
'zh-cn': '附 件 现有最新设备清单',
|
|
2239
|
+
},
|
|
2240
|
+
type: 'array',
|
|
2241
|
+
role: 'json',
|
|
2242
|
+
read: true,
|
|
2243
|
+
write: false,
|
|
2244
|
+
},
|
|
2245
|
+
native: {},
|
|
2246
|
+
});
|
|
1944
2247
|
}
|
|
1945
2248
|
|
|
1946
2249
|
/**
|