iobroker.device-watcher 2.4.1 → 2.5.0
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 +5 -0
- package/admin/i18n/de/translations.json +120 -104
- package/admin/i18n/en/translations.json +17 -1
- package/admin/i18n/es/translations.json +17 -1
- package/admin/i18n/fr/translations.json +17 -1
- package/admin/i18n/it/translations.json +17 -1
- package/admin/i18n/nl/translations.json +17 -1
- package/admin/i18n/pl/translations.json +17 -1
- package/admin/i18n/pt/translations.json +17 -1
- package/admin/i18n/ru/translations.json +17 -1
- package/admin/i18n/uk/translations.json +17 -1
- package/admin/i18n/zh-cn/translations.json +17 -1
- package/admin/jsonConfig.json +255 -13
- package/io-package.json +158 -75
- package/main.js +922 -46
- package/package.json +2 -1
package/main.js
CHANGED
|
@@ -8,6 +8,7 @@ const utils = require('@iobroker/adapter-core');
|
|
|
8
8
|
const adapterName = require('./package.json').name.split('.').pop();
|
|
9
9
|
const schedule = require('node-schedule');
|
|
10
10
|
const arrApart = require('./lib/arrApart.js'); // list of supported adapters
|
|
11
|
+
const cronParser = require('cron-parser');
|
|
11
12
|
|
|
12
13
|
// Sentry error reporting, disable when testing code!
|
|
13
14
|
const enableSendSentry = true;
|
|
@@ -23,6 +24,27 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
23
24
|
useFormatDate: true,
|
|
24
25
|
});
|
|
25
26
|
|
|
27
|
+
// instances and adapters
|
|
28
|
+
// raw arrays
|
|
29
|
+
this.adapterUpdatesJsonRaw = [];
|
|
30
|
+
this.listInstanceRaw = [];
|
|
31
|
+
this.listErrorInstanceRaw = [];
|
|
32
|
+
|
|
33
|
+
// user arrays
|
|
34
|
+
this.blacklistInstancesLists = [];
|
|
35
|
+
this.blacklistInstancesNotify = [];
|
|
36
|
+
this.listAllInstances = [];
|
|
37
|
+
this.listDeactivatedInstances = [];
|
|
38
|
+
this.listAdapterUpdates = [];
|
|
39
|
+
this.listErrorInstance = [];
|
|
40
|
+
|
|
41
|
+
//counts
|
|
42
|
+
this.countAllInstances = 0;
|
|
43
|
+
this.countDeactivatedInstances = 0;
|
|
44
|
+
this.countAdapterUpdates = 0;
|
|
45
|
+
this.countErrorInstance = 0;
|
|
46
|
+
|
|
47
|
+
// devices
|
|
26
48
|
// arrays
|
|
27
49
|
this.offlineDevices = [];
|
|
28
50
|
this.linkQualityDevices = [];
|
|
@@ -219,6 +241,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
219
241
|
//read data first at start
|
|
220
242
|
await this.main();
|
|
221
243
|
|
|
244
|
+
if (this.config.checkAdapterInstances) {
|
|
245
|
+
await this.getInstanceData();
|
|
246
|
+
await this.createAdapterUpdateData();
|
|
247
|
+
}
|
|
248
|
+
|
|
222
249
|
// update last contact data in interval
|
|
223
250
|
await this.refreshData();
|
|
224
251
|
|
|
@@ -229,7 +256,10 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
229
256
|
if (this.config.checkSendOfflineMsgDaily) await this.sendOfflineNotificationsShedule();
|
|
230
257
|
|
|
231
258
|
// send overview of upgradeable devices
|
|
232
|
-
if (this.config.checkSendUpgradeMsgDaily) await this.
|
|
259
|
+
if (this.config.checkSendUpgradeMsgDaily) await this.sendDeviceUpdateNotificationsShedule();
|
|
260
|
+
|
|
261
|
+
// send overview of instances with error
|
|
262
|
+
if (this.config.checkSendInstanceFailedDaily) await this.sendInstanceErrorNotificationShedule();
|
|
233
263
|
} catch (error) {
|
|
234
264
|
this.errorReporting('[onReady]', error);
|
|
235
265
|
this.terminate ? this.terminate(15) : process.exit(15);
|
|
@@ -250,11 +280,80 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
250
280
|
let contactData;
|
|
251
281
|
let oldStatus;
|
|
252
282
|
let isLowBatValue;
|
|
283
|
+
let instanceStatusRaw;
|
|
253
284
|
let instanceDeviceConnectionDpTS;
|
|
254
|
-
const instanceDeviceConnectionDpTSminTime =
|
|
285
|
+
const instanceDeviceConnectionDpTSminTime = 10;
|
|
286
|
+
|
|
287
|
+
/*
|
|
288
|
+
if (this.config.checkAdapterInstances) {
|
|
289
|
+
for (const adapter of this.adapterUpdatesJsonRaw) {
|
|
290
|
+
switch (id) {
|
|
291
|
+
case adapter.Path:
|
|
255
292
|
|
|
256
|
-
|
|
257
|
-
|
|
293
|
+
this.sendAdapterUpdatesNotification(id, state);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}*/
|
|
297
|
+
|
|
298
|
+
for (const instance of this.listInstanceRaw) {
|
|
299
|
+
switch (id) {
|
|
300
|
+
case instance.instanceAlivePath:
|
|
301
|
+
if (state.val !== instance.isAlive) {
|
|
302
|
+
instanceStatusRaw = await this.setInstanceStatus(
|
|
303
|
+
instance.instanceMode,
|
|
304
|
+
instance.schedule,
|
|
305
|
+
instance.instanceAlivePath,
|
|
306
|
+
state.val,
|
|
307
|
+
instance.isConnectedHost,
|
|
308
|
+
instance.isConnectedDevice,
|
|
309
|
+
);
|
|
310
|
+
instance.isAlive = instanceStatusRaw[1];
|
|
311
|
+
instance.status = instanceStatusRaw[0];
|
|
312
|
+
instance.isHealthy = instanceStatusRaw[2];
|
|
313
|
+
}
|
|
314
|
+
break;
|
|
315
|
+
case instance.connectedHostPath:
|
|
316
|
+
if (instance.isAlive && state.val !== instance.isConnectedHost) {
|
|
317
|
+
instance.isConnectedHost = state.val;
|
|
318
|
+
instanceStatusRaw = await this.setInstanceStatus(
|
|
319
|
+
instance.instanceMode,
|
|
320
|
+
instance.schedule,
|
|
321
|
+
instance.instanceAlivePath,
|
|
322
|
+
instance.isAlive,
|
|
323
|
+
state.val,
|
|
324
|
+
instance.isConnectedDevice,
|
|
325
|
+
);
|
|
326
|
+
instance.isAlive = instanceStatusRaw[1];
|
|
327
|
+
instance.status = instanceStatusRaw[0];
|
|
328
|
+
instance.isHealthy = instanceStatusRaw[2];
|
|
329
|
+
|
|
330
|
+
if (this.config.checkSendInstanceFailedMsg && !instance.isHealthy && !this.blacklistNotify.includes(instance.instanceAlivePath)) {
|
|
331
|
+
await this.sendInstanceErrorNotification(instance.InstanceName, instance.status);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
break;
|
|
335
|
+
case instance.connectedDevicePath:
|
|
336
|
+
if (instance.isAlive && state.val !== instance.isConnectedDevice) {
|
|
337
|
+
instance.isConnectedDevice = state.val;
|
|
338
|
+
instanceStatusRaw = await this.setInstanceStatus(
|
|
339
|
+
instance.instanceMode,
|
|
340
|
+
instance.schedule,
|
|
341
|
+
instance.instanceAlivePath,
|
|
342
|
+
instance.isAlive,
|
|
343
|
+
instance.isConnectedHost,
|
|
344
|
+
state.val,
|
|
345
|
+
);
|
|
346
|
+
instance.isAlive = instanceStatusRaw[1];
|
|
347
|
+
instance.status = instanceStatusRaw[0];
|
|
348
|
+
instance.isHealthy = instanceStatusRaw[2];
|
|
349
|
+
|
|
350
|
+
if (this.config.checkSendInstanceFailedMsg && !instance.isHealthy && !this.blacklistNotify.includes(instance.instanceAlivePath)) {
|
|
351
|
+
await this.sendInstanceErrorNotification(instance.InstanceName, instance.status);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
258
357
|
|
|
259
358
|
for (const device of this.listAllDevicesRaw) {
|
|
260
359
|
// On statechange update available datapoint
|
|
@@ -269,7 +368,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
269
368
|
if (state.val !== device.Upgradable) {
|
|
270
369
|
device.Upgradable = state.val;
|
|
271
370
|
if (state.val) {
|
|
272
|
-
if (!this.blacklistNotify.includes(device.Path)) {
|
|
371
|
+
if (this.config.checkSendDeviceUpgrade && !this.blacklistNotify.includes(device.Path)) {
|
|
273
372
|
await this.sendDeviceUpdatesNotification(device.Device, device.Adapter);
|
|
274
373
|
}
|
|
275
374
|
}
|
|
@@ -377,6 +476,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
377
476
|
const devices = [];
|
|
378
477
|
let myCount = 0;
|
|
379
478
|
let result;
|
|
479
|
+
const instances = [];
|
|
480
|
+
let myCountInstances = 0;
|
|
481
|
+
let resultInstances;
|
|
380
482
|
|
|
381
483
|
switch (obj.command) {
|
|
382
484
|
case 'devicesList':
|
|
@@ -407,6 +509,35 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
407
509
|
this.sendTo(obj.from, obj.command, obj.callback);
|
|
408
510
|
}
|
|
409
511
|
break;
|
|
512
|
+
|
|
513
|
+
case 'instancesList':
|
|
514
|
+
if (obj.message) {
|
|
515
|
+
try {
|
|
516
|
+
resultInstances = this.listInstanceRaw;
|
|
517
|
+
for (const element in resultInstances) {
|
|
518
|
+
const label = `${resultInstances[element].Adapter}: ${resultInstances[element].InstanceName}`;
|
|
519
|
+
const myValueObject = {
|
|
520
|
+
adapter: resultInstances[element].Adapter,
|
|
521
|
+
instanceName: resultInstances[element].InstanceName,
|
|
522
|
+
path: resultInstances[element].instanceAlivePath,
|
|
523
|
+
};
|
|
524
|
+
instances[myCountInstances] = { label: label, value: JSON.stringify(myValueObject) };
|
|
525
|
+
myCountInstances++;
|
|
526
|
+
}
|
|
527
|
+
const sortInstances = instances.slice(0);
|
|
528
|
+
sortInstances.sort(function (a, b) {
|
|
529
|
+
const x = a.label;
|
|
530
|
+
const y = b.label;
|
|
531
|
+
return x < y ? -1 : x > y ? 1 : 0;
|
|
532
|
+
});
|
|
533
|
+
this.sendTo(obj.from, obj.command, sortInstances, obj.callback);
|
|
534
|
+
} catch (error) {
|
|
535
|
+
this.sendTo(obj.from, obj.command, obj.callback);
|
|
536
|
+
}
|
|
537
|
+
} else {
|
|
538
|
+
this.sendTo(obj.from, obj.command, obj.callback);
|
|
539
|
+
}
|
|
540
|
+
break;
|
|
410
541
|
}
|
|
411
542
|
}
|
|
412
543
|
|
|
@@ -462,6 +593,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
462
593
|
}
|
|
463
594
|
}
|
|
464
595
|
|
|
596
|
+
if (this.config.checkAdapterInstances) {
|
|
597
|
+
await this.createInstanceList();
|
|
598
|
+
await this.writeInstanceDPs();
|
|
599
|
+
}
|
|
600
|
+
|
|
465
601
|
// Clear existing timeout
|
|
466
602
|
if (this.refreshDataTimeout) {
|
|
467
603
|
this.log.debug('clearing old refresh timeout');
|
|
@@ -485,6 +621,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
485
621
|
async createBlacklist() {
|
|
486
622
|
this.log.debug(`Function started: ${this.createBlacklist.name}`);
|
|
487
623
|
|
|
624
|
+
// DEVICES
|
|
488
625
|
const myBlacklist = this.config.tableBlacklist;
|
|
489
626
|
|
|
490
627
|
for (const i in myBlacklist) {
|
|
@@ -510,6 +647,28 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
510
647
|
if (this.blacklistAdapterLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistAdapterLists}`);
|
|
511
648
|
if (this.blacklistNotify.length >= 1) this.log.info(`Found items on blacklist for notificatioons: ${this.blacklistNotify}`);
|
|
512
649
|
|
|
650
|
+
// INSTANCES
|
|
651
|
+
const myBlacklistInstances = this.config.tableBlacklistInstances;
|
|
652
|
+
|
|
653
|
+
for (const i in myBlacklistInstances) {
|
|
654
|
+
try {
|
|
655
|
+
const blacklistParse = await this.parseData(myBlacklistInstances[i].instances);
|
|
656
|
+
// push devices in list to ignor device in lists
|
|
657
|
+
if (myBlacklistInstances[i].checkIgnorLists) {
|
|
658
|
+
this.blacklistInstancesLists.push(blacklistParse.path);
|
|
659
|
+
}
|
|
660
|
+
// push devices in list to ignor device in notifications
|
|
661
|
+
if (myBlacklistInstances[i].checkIgnorNotify) {
|
|
662
|
+
this.blacklistInstancesNotify.push(blacklistParse.path);
|
|
663
|
+
}
|
|
664
|
+
} catch (error) {
|
|
665
|
+
this.errorReporting('[createBlacklist]', error);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
if (this.blacklistInstancesLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistInstancesLists}`);
|
|
670
|
+
if (this.blacklistInstancesNotify.length >= 1) this.log.info(`Found items on blacklist for notificatioons: ${this.blacklistInstancesNotify}`);
|
|
671
|
+
|
|
513
672
|
this.log.debug(`Function finished: ${this.createBlacklist.name}`);
|
|
514
673
|
}
|
|
515
674
|
|
|
@@ -1447,18 +1606,18 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1447
1606
|
}
|
|
1448
1607
|
|
|
1449
1608
|
// Write Datapoints for counts
|
|
1450
|
-
await this.setStateAsync(
|
|
1451
|
-
await this.setStateAsync(
|
|
1452
|
-
await this.setStateAsync(
|
|
1453
|
-
await this.setStateAsync(
|
|
1454
|
-
await this.setStateAsync(
|
|
1609
|
+
await this.setStateAsync(`devices.${dpSubFolder}offlineCount`, { val: this.offlineDevicesCount, ack: true });
|
|
1610
|
+
await this.setStateAsync(`devices.${dpSubFolder}countAll`, { val: this.deviceCounter, ack: true });
|
|
1611
|
+
await this.setStateAsync(`devices.${dpSubFolder}batteryCount`, { val: this.batteryPoweredCount, ack: true });
|
|
1612
|
+
await this.setStateAsync(`devices.${dpSubFolder}lowBatteryCount`, { val: this.lowBatteryPoweredCount, ack: true });
|
|
1613
|
+
await this.setStateAsync(`devices.${dpSubFolder}upgradableCount`, { val: this.upgradableDevicesCount, ack: true });
|
|
1455
1614
|
|
|
1456
1615
|
// List all devices
|
|
1457
1616
|
if (this.deviceCounter === 0) {
|
|
1458
1617
|
// if no device is count, write the JSON List with default value
|
|
1459
1618
|
this.listAllDevices = [{ Device: '--none--', Adapter: '', Battery: '', 'Last contact': '', 'Signal strength': '' }];
|
|
1460
1619
|
}
|
|
1461
|
-
await this.setStateAsync(
|
|
1620
|
+
await this.setStateAsync(`devices.${dpSubFolder}listAll`, { val: JSON.stringify(this.listAllDevices), ack: true });
|
|
1462
1621
|
|
|
1463
1622
|
// List link quality
|
|
1464
1623
|
if (this.linkQualityCount === 0) {
|
|
@@ -1466,7 +1625,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1466
1625
|
this.linkQualityDevices = [{ Device: '--none--', Adapter: '', 'Signal strength': '' }];
|
|
1467
1626
|
}
|
|
1468
1627
|
//write JSON list
|
|
1469
|
-
await this.setStateAsync(
|
|
1628
|
+
await this.setStateAsync(`devices.${dpSubFolder}linkQualityList`, {
|
|
1470
1629
|
val: JSON.stringify(this.linkQualityDevices),
|
|
1471
1630
|
ack: true,
|
|
1472
1631
|
});
|
|
@@ -1477,7 +1636,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1477
1636
|
this.offlineDevices = [{ Device: '--none--', Adapter: '', 'Last contact': '' }];
|
|
1478
1637
|
}
|
|
1479
1638
|
//write JSON list
|
|
1480
|
-
await this.setStateAsync(
|
|
1639
|
+
await this.setStateAsync(`devices.${dpSubFolder}offlineList`, {
|
|
1481
1640
|
val: JSON.stringify(this.offlineDevices),
|
|
1482
1641
|
ack: true,
|
|
1483
1642
|
});
|
|
@@ -1488,7 +1647,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1488
1647
|
this.upgradableList = [{ Device: '--none--', Adapter: '', 'Last contact': '' }];
|
|
1489
1648
|
}
|
|
1490
1649
|
//write JSON list
|
|
1491
|
-
await this.setStateAsync(
|
|
1650
|
+
await this.setStateAsync(`devices.${dpSubFolder}upgradableList`, {
|
|
1492
1651
|
val: JSON.stringify(this.upgradableList),
|
|
1493
1652
|
ack: true,
|
|
1494
1653
|
});
|
|
@@ -1499,7 +1658,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1499
1658
|
this.batteryPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
|
|
1500
1659
|
}
|
|
1501
1660
|
//write JSON list
|
|
1502
|
-
await this.setStateAsync(
|
|
1661
|
+
await this.setStateAsync(`devices.${dpSubFolder}batteryList`, {
|
|
1503
1662
|
val: JSON.stringify(this.batteryPowered),
|
|
1504
1663
|
ack: true,
|
|
1505
1664
|
});
|
|
@@ -1510,43 +1669,43 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1510
1669
|
this.batteryLowPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
|
|
1511
1670
|
}
|
|
1512
1671
|
//write JSON list
|
|
1513
|
-
await this.setStateAsync(
|
|
1672
|
+
await this.setStateAsync(`devices.${dpSubFolder}lowBatteryList`, {
|
|
1514
1673
|
val: JSON.stringify(this.batteryLowPowered),
|
|
1515
1674
|
ack: true,
|
|
1516
1675
|
});
|
|
1517
1676
|
|
|
1518
1677
|
// set booleans datapoints
|
|
1519
1678
|
if (this.offlineDevicesCount === 0) {
|
|
1520
|
-
await this.setStateAsync(
|
|
1679
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceOffline`, {
|
|
1521
1680
|
val: false,
|
|
1522
1681
|
ack: true,
|
|
1523
1682
|
});
|
|
1524
1683
|
} else {
|
|
1525
|
-
await this.setStateAsync(
|
|
1684
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceOffline`, {
|
|
1526
1685
|
val: true,
|
|
1527
1686
|
ack: true,
|
|
1528
1687
|
});
|
|
1529
1688
|
}
|
|
1530
1689
|
|
|
1531
1690
|
if (this.lowBatteryPoweredCount === 0) {
|
|
1532
|
-
await this.setStateAsync(
|
|
1691
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceLowBat`, {
|
|
1533
1692
|
val: false,
|
|
1534
1693
|
ack: true,
|
|
1535
1694
|
});
|
|
1536
1695
|
} else {
|
|
1537
|
-
await this.setStateAsync(
|
|
1696
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceLowBat`, {
|
|
1538
1697
|
val: true,
|
|
1539
1698
|
ack: true,
|
|
1540
1699
|
});
|
|
1541
1700
|
}
|
|
1542
1701
|
|
|
1543
1702
|
if (this.upgradableDevicesCount === 0) {
|
|
1544
|
-
await this.setStateAsync(
|
|
1703
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceUpdatable`, {
|
|
1545
1704
|
val: false,
|
|
1546
1705
|
ack: true,
|
|
1547
1706
|
});
|
|
1548
1707
|
} else {
|
|
1549
|
-
await this.setStateAsync(
|
|
1708
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceUpdatable`, {
|
|
1550
1709
|
val: true,
|
|
1551
1710
|
ack: true,
|
|
1552
1711
|
});
|
|
@@ -1554,19 +1713,19 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1554
1713
|
|
|
1555
1714
|
//write HTML list
|
|
1556
1715
|
if (this.createHtmlList) {
|
|
1557
|
-
await this.setStateAsync(
|
|
1716
|
+
await this.setStateAsync(`devices.${dpSubFolder}linkQualityListHTML`, {
|
|
1558
1717
|
val: await this.creatLinkQualityListHTML(this.linkQualityDevices, this.linkQualityCount),
|
|
1559
1718
|
ack: true,
|
|
1560
1719
|
});
|
|
1561
|
-
await this.setStateAsync(
|
|
1720
|
+
await this.setStateAsync(`devices.${dpSubFolder}offlineListHTML`, {
|
|
1562
1721
|
val: await this.createOfflineListHTML(this.offlineDevices, this.offlineDevicesCount),
|
|
1563
1722
|
ack: true,
|
|
1564
1723
|
});
|
|
1565
|
-
await this.setStateAsync(
|
|
1724
|
+
await this.setStateAsync(`devices.${dpSubFolder}batteryListHTML`, {
|
|
1566
1725
|
val: await this.createBatteryListHTML(this.batteryPowered, this.batteryPoweredCount, false),
|
|
1567
1726
|
ack: true,
|
|
1568
1727
|
});
|
|
1569
|
-
await this.setStateAsync(
|
|
1728
|
+
await this.setStateAsync(`devices.${dpSubFolder}lowBatteryListHTML`, {
|
|
1570
1729
|
val: await this.createBatteryListHTML(this.batteryLowPowered, this.lowBatteryPoweredCount, true),
|
|
1571
1730
|
ack: true,
|
|
1572
1731
|
});
|
|
@@ -1581,6 +1740,534 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1581
1740
|
this.log.debug(`Function finished: ${this.writeDatapoints.name}`);
|
|
1582
1741
|
} //<--End of writing Datapoints
|
|
1583
1742
|
|
|
1743
|
+
/**
|
|
1744
|
+
* get Instances
|
|
1745
|
+
*/
|
|
1746
|
+
async getInstanceData() {
|
|
1747
|
+
try {
|
|
1748
|
+
await this.createDPsForInstances();
|
|
1749
|
+
|
|
1750
|
+
const instanceAliveDP = await this.getForeignStatesAsync(`system.adapter.*.alive`);
|
|
1751
|
+
for (const [id] of Object.entries(instanceAliveDP)) {
|
|
1752
|
+
if (!(typeof id === 'string' && id.startsWith(`system.adapter.`))) continue;
|
|
1753
|
+
|
|
1754
|
+
// get instance name
|
|
1755
|
+
const instanceName = await this.getInstanceName(id);
|
|
1756
|
+
|
|
1757
|
+
// get instance connected to host data
|
|
1758
|
+
const instanceConnectedHostDP = `system.adapter.${instanceName}.connected`;
|
|
1759
|
+
const instanceConnectedHostVal = await this.getInitValue(instanceConnectedHostDP);
|
|
1760
|
+
|
|
1761
|
+
// get instance connected to device data
|
|
1762
|
+
const instanceConnectedDeviceDP = `${instanceName}.info.connection`;
|
|
1763
|
+
let instanceConnectedDeviceVal;
|
|
1764
|
+
if (instanceConnectedDeviceDP !== undefined && typeof instanceConnectedDeviceDP === 'boolean') {
|
|
1765
|
+
instanceConnectedDeviceVal = await this.getInitValue(instanceConnectedDeviceDP);
|
|
1766
|
+
} else {
|
|
1767
|
+
instanceConnectedDeviceVal = 'N/A';
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
// get adapter version
|
|
1771
|
+
const instanceObjectPath = `system.adapter.${instanceName}`;
|
|
1772
|
+
let adapterName;
|
|
1773
|
+
let adapterVersion;
|
|
1774
|
+
let instanceMode;
|
|
1775
|
+
let scheduleTime = 'N/A';
|
|
1776
|
+
const instanceObjectData = await this.getForeignObjectAsync(instanceObjectPath);
|
|
1777
|
+
if (instanceObjectData) {
|
|
1778
|
+
// @ts-ignore
|
|
1779
|
+
adapterName = this.capitalize(instanceObjectData.common.name);
|
|
1780
|
+
adapterVersion = instanceObjectData.common.version;
|
|
1781
|
+
instanceMode = instanceObjectData.common.mode;
|
|
1782
|
+
|
|
1783
|
+
if (instanceMode === 'schedule') {
|
|
1784
|
+
scheduleTime = instanceObjectData.common.schedule;
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
//const adapterVersionVal = await this.getInitValue(adapterVersionDP);
|
|
1789
|
+
const instanceStatusRaw = await this.setInstanceStatus(instanceMode, scheduleTime, id, instanceAliveDP[id].val, instanceConnectedHostVal, instanceConnectedDeviceVal);
|
|
1790
|
+
const isAlive = instanceStatusRaw[1];
|
|
1791
|
+
const instanceStatus = instanceStatusRaw[0];
|
|
1792
|
+
const isHealthy = instanceStatusRaw[2];
|
|
1793
|
+
|
|
1794
|
+
//subscribe to statechanges
|
|
1795
|
+
this.subscribeForeignStatesAsync(id);
|
|
1796
|
+
this.subscribeForeignStatesAsync(instanceConnectedHostDP);
|
|
1797
|
+
this.subscribeForeignStatesAsync(instanceConnectedDeviceDP);
|
|
1798
|
+
//this.subscribeForeignObjectsAsync(instanceObjectPath);
|
|
1799
|
+
|
|
1800
|
+
// create raw list
|
|
1801
|
+
this.listInstanceRaw.push({
|
|
1802
|
+
Adapter: adapterName,
|
|
1803
|
+
InstanceName: instanceName,
|
|
1804
|
+
instanceObjectPath: instanceObjectPath,
|
|
1805
|
+
instanceAlivePath: id,
|
|
1806
|
+
instanceMode: instanceMode,
|
|
1807
|
+
schedule: scheduleTime,
|
|
1808
|
+
adapterVersion: adapterVersion,
|
|
1809
|
+
isAlive: isAlive,
|
|
1810
|
+
isHealthy: isHealthy,
|
|
1811
|
+
connectedHostPath: instanceConnectedHostDP,
|
|
1812
|
+
isConnectedHost: instanceConnectedHostVal,
|
|
1813
|
+
connectedDevicePath: instanceConnectedDeviceDP,
|
|
1814
|
+
isConnectedDevice: instanceConnectedDeviceVal,
|
|
1815
|
+
status: instanceStatus,
|
|
1816
|
+
});
|
|
1817
|
+
}
|
|
1818
|
+
await this.createInstanceList();
|
|
1819
|
+
await this.writeInstanceDPs();
|
|
1820
|
+
} catch (error) {
|
|
1821
|
+
this.errorReporting('[getInstance]', error);
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
/**
|
|
1826
|
+
* get Instances
|
|
1827
|
+
* @param {string} id - Path of alive datapoint
|
|
1828
|
+
*/
|
|
1829
|
+
async getInstanceName(id) {
|
|
1830
|
+
let instance = id;
|
|
1831
|
+
instance = instance.slice(15); // remove "system.adapter."
|
|
1832
|
+
instance = instance.slice(0, instance.lastIndexOf('.') + 1 - 1); // remove ".alive"
|
|
1833
|
+
return instance;
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
/**
|
|
1837
|
+
* set status for instance
|
|
1838
|
+
* @param {object} instanceMode
|
|
1839
|
+
* @param {object} scheduleTime
|
|
1840
|
+
* @param {object} instanceAlivePath
|
|
1841
|
+
* @param {object} isAliveVal
|
|
1842
|
+
* @param {object} connectedHostVal
|
|
1843
|
+
* @param {object} connectedDeviceVal
|
|
1844
|
+
*/
|
|
1845
|
+
async setInstanceStatus(instanceMode, scheduleTime, instanceAlivePath, isAliveVal, connectedHostVal, connectedDeviceVal) {
|
|
1846
|
+
let instanceStatusString = 'not enabled';
|
|
1847
|
+
let lastUpdate;
|
|
1848
|
+
let lastCronRun;
|
|
1849
|
+
let diff;
|
|
1850
|
+
let previousCronRun = null;
|
|
1851
|
+
let isAlive = false;
|
|
1852
|
+
let isHealthy = false;
|
|
1853
|
+
let dpValue;
|
|
1854
|
+
switch (instanceMode) {
|
|
1855
|
+
case 'schedule':
|
|
1856
|
+
dpValue = await this.getForeignStateAsync(instanceAlivePath);
|
|
1857
|
+
if (dpValue) {
|
|
1858
|
+
lastUpdate = Math.round((Date.now() - dpValue.lc) / 1000); // Last state change in seconds
|
|
1859
|
+
previousCronRun = await this.getPreviousCronRun(scheduleTime); // When was the last cron run
|
|
1860
|
+
if (previousCronRun) {
|
|
1861
|
+
lastCronRun = Math.round(previousCronRun / 1000); // change distance to last run in seconds
|
|
1862
|
+
diff = lastCronRun - lastUpdate;
|
|
1863
|
+
if (diff > -300) {
|
|
1864
|
+
// if 5 minutes difference exceeded, instance is not alive
|
|
1865
|
+
isAlive = true;
|
|
1866
|
+
isHealthy = true;
|
|
1867
|
+
instanceStatusString = 'Instance okay';
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
break;
|
|
1872
|
+
case 'daemon':
|
|
1873
|
+
if (!isAliveVal) return ['Instance deactivated', false, null]; // if instance is turned off
|
|
1874
|
+
|
|
1875
|
+
// In case of (re)start, connection may take some time. We take 3 attempts.
|
|
1876
|
+
// Attempt 1/3 - immediately
|
|
1877
|
+
if (connectedHostVal && connectedDeviceVal) {
|
|
1878
|
+
isAlive = true;
|
|
1879
|
+
isHealthy = true;
|
|
1880
|
+
instanceStatusString = 'Instance okay';
|
|
1881
|
+
} else {
|
|
1882
|
+
// Attempt 2/3 - after 10 seconds
|
|
1883
|
+
await this.wait(10000);
|
|
1884
|
+
if (connectedHostVal && connectedDeviceVal) {
|
|
1885
|
+
isAlive = true;
|
|
1886
|
+
isHealthy = true;
|
|
1887
|
+
instanceStatusString = 'Instance okay';
|
|
1888
|
+
} else {
|
|
1889
|
+
// Attempt 3/3 - after 20 seconds in total
|
|
1890
|
+
await this.wait(10000);
|
|
1891
|
+
if (connectedHostVal && connectedDeviceVal) {
|
|
1892
|
+
isAlive = true;
|
|
1893
|
+
isHealthy = true;
|
|
1894
|
+
instanceStatusString = 'Instance okay';
|
|
1895
|
+
} else {
|
|
1896
|
+
if (!connectedDeviceVal) {
|
|
1897
|
+
instanceStatusString = 'not connected to Device';
|
|
1898
|
+
isAlive = true;
|
|
1899
|
+
isHealthy = false;
|
|
1900
|
+
} else if (!connectedHostVal) {
|
|
1901
|
+
instanceStatusString = 'not connected to host';
|
|
1902
|
+
isAlive = true;
|
|
1903
|
+
isHealthy = false;
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
break;
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
return [instanceStatusString, isAlive, isHealthy];
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
async createAdapterUpdateData() {
|
|
1915
|
+
const adapterUpdateListDP = `admin.*.info.updatesJson`;
|
|
1916
|
+
const adapterUpdatesListVal = await this.getForeignStatesAsync(adapterUpdateListDP);
|
|
1917
|
+
|
|
1918
|
+
// subscribe to datapoint
|
|
1919
|
+
this.subscribeForeignStates(adapterUpdateListDP);
|
|
1920
|
+
let adapterJsonList;
|
|
1921
|
+
|
|
1922
|
+
for (const [id] of Object.entries(adapterUpdatesListVal)) {
|
|
1923
|
+
adapterJsonList = await this.parseData(adapterUpdatesListVal[id].val);
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
for (const [id] of Object.entries(adapterJsonList)) {
|
|
1927
|
+
this.adapterUpdatesJsonRaw.push({
|
|
1928
|
+
Path: adapterUpdateListDP,
|
|
1929
|
+
Adapter: this.capitalize(id),
|
|
1930
|
+
newVersion: adapterJsonList[id].availableVersion,
|
|
1931
|
+
oldVersion: adapterJsonList[id].installedVersion,
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
1934
|
+
await this.createAdapterUpdateList();
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1937
|
+
/**
|
|
1938
|
+
* create instanceList
|
|
1939
|
+
*/
|
|
1940
|
+
async createAdapterUpdateList() {
|
|
1941
|
+
this.listAdapterUpdates = [];
|
|
1942
|
+
this.countAdapterUpdates = 0;
|
|
1943
|
+
|
|
1944
|
+
for (const adapter of this.adapterUpdatesJsonRaw) {
|
|
1945
|
+
this.listAdapterUpdates.push({
|
|
1946
|
+
Adapter: adapter.Adapter,
|
|
1947
|
+
'Available Version': adapter.newVersion,
|
|
1948
|
+
'Installed Version': adapter.oldVersion,
|
|
1949
|
+
});
|
|
1950
|
+
}
|
|
1951
|
+
this.countAdapterUpdates = this.listAdapterUpdates.length;
|
|
1952
|
+
await this.writeAdapterUpdatesDPs();
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
/**
|
|
1956
|
+
* write datapoints for adapter with updates
|
|
1957
|
+
*/
|
|
1958
|
+
async writeAdapterUpdatesDPs() {
|
|
1959
|
+
// Write Datapoints for counts
|
|
1960
|
+
await this.setStateAsync(`adapterAndInstances.countAdapterUpdates`, { val: this.countAdapterUpdates, ack: true });
|
|
1961
|
+
|
|
1962
|
+
// list deactivated instances
|
|
1963
|
+
if (this.countAdapterUpdates === 0) {
|
|
1964
|
+
this.listAdapterUpdates = [{ Adapter: '--none--', 'Available Version': '', 'Installed Version': '' }];
|
|
1965
|
+
}
|
|
1966
|
+
await this.setStateAsync(`adapterAndInstances.listAdapterUpdates`, { val: JSON.stringify(this.listAdapterUpdates), ack: true });
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
/**
|
|
1970
|
+
* create instanceList
|
|
1971
|
+
*/
|
|
1972
|
+
async createInstanceList() {
|
|
1973
|
+
this.listAllInstances = [];
|
|
1974
|
+
this.listDeactivatedInstances = [];
|
|
1975
|
+
this.listErrorInstanceRaw = [];
|
|
1976
|
+
this.listErrorInstance = [];
|
|
1977
|
+
|
|
1978
|
+
for (const instance of this.listInstanceRaw) {
|
|
1979
|
+
// fill raw list
|
|
1980
|
+
if (instance.isAlive && !instance.isHealthy) {
|
|
1981
|
+
this.listErrorInstanceRaw.push({
|
|
1982
|
+
Adapter: instance.Adapter,
|
|
1983
|
+
Instance: instance.InstanceName,
|
|
1984
|
+
Mode: instance.instanceMode,
|
|
1985
|
+
Status: instance.status,
|
|
1986
|
+
});
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
if (this.blacklistInstancesLists.includes(instance.instanceAlivePath)) continue;
|
|
1990
|
+
this.listAllInstances.push({
|
|
1991
|
+
Adapter: instance.Adapter,
|
|
1992
|
+
Instance: instance.InstanceName,
|
|
1993
|
+
Mode: instance.instanceMode,
|
|
1994
|
+
Schedule: instance.schedule,
|
|
1995
|
+
Version: instance.adapterVersion,
|
|
1996
|
+
Status: instance.status,
|
|
1997
|
+
});
|
|
1998
|
+
if (!instance.isAlive) {
|
|
1999
|
+
this.listDeactivatedInstances.push({
|
|
2000
|
+
Adapter: instance.Adapter,
|
|
2001
|
+
Instance: instance.InstanceName,
|
|
2002
|
+
Status: instance.status,
|
|
2003
|
+
});
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
// fill List for User
|
|
2007
|
+
if (instance.isAlive && !instance.isHealthy) {
|
|
2008
|
+
this.listErrorInstance.push({
|
|
2009
|
+
Adapter: instance.Adapter,
|
|
2010
|
+
Instance: instance.InstanceName,
|
|
2011
|
+
Mode: instance.instanceMode,
|
|
2012
|
+
Status: instance.status,
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
await this.countInstances();
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
/**
|
|
2020
|
+
* count instanceList
|
|
2021
|
+
*/
|
|
2022
|
+
async countInstances() {
|
|
2023
|
+
this.countAllInstances = 0;
|
|
2024
|
+
this.countDeactivatedInstances = 0;
|
|
2025
|
+
this.countErrorInstance = 0;
|
|
2026
|
+
|
|
2027
|
+
this.countAllInstances = this.listAllInstances.length;
|
|
2028
|
+
this.countDeactivatedInstances = this.listDeactivatedInstances.length;
|
|
2029
|
+
this.countErrorInstance = this.listErrorInstance.length;
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
/**
|
|
2033
|
+
* write datapoints for instances list and counts
|
|
2034
|
+
*/
|
|
2035
|
+
async writeInstanceDPs() {
|
|
2036
|
+
// Write Datapoints for counts
|
|
2037
|
+
await this.setStateAsync(`adapterAndInstances.countAllInstances`, { val: this.countAllInstances, ack: true });
|
|
2038
|
+
await this.setStateAsync(`adapterAndInstances.countDeactivatedInstances`, { val: this.countDeactivatedInstances, ack: true });
|
|
2039
|
+
|
|
2040
|
+
// List all instances
|
|
2041
|
+
await this.setStateAsync(`adapterAndInstances.listAllInstances`, { val: JSON.stringify(this.listAllInstances), ack: true });
|
|
2042
|
+
|
|
2043
|
+
// list deactivated instances
|
|
2044
|
+
if (this.countDeactivatedInstances === 0) {
|
|
2045
|
+
this.listDeactivatedInstances = [{ Instance: '--none--', Version: '', Status: '' }];
|
|
2046
|
+
}
|
|
2047
|
+
await this.setStateAsync(`adapterAndInstances.listDeactivatedInstances`, { val: JSON.stringify(this.listDeactivatedInstances), ack: true });
|
|
2048
|
+
await this.setStateAsync(`adapterAndInstances.countDeactivatedInstances`, { val: this.countDeactivatedInstances, ack: true });
|
|
2049
|
+
|
|
2050
|
+
// list error instances
|
|
2051
|
+
if (this.countErrorInstance === 0) {
|
|
2052
|
+
this.listErrorInstance = [{ Instance: '--none--', Mode: '', Status: '' }];
|
|
2053
|
+
}
|
|
2054
|
+
await this.setStateAsync(`adapterAndInstances.listInstancesError`, { val: JSON.stringify(this.listErrorInstance), ack: true });
|
|
2055
|
+
await this.setStateAsync(`adapterAndInstances.countInstancesError`, { val: this.countErrorInstance, ack: true });
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
/**
|
|
2059
|
+
* create Datapoints for Instances
|
|
2060
|
+
*/
|
|
2061
|
+
async createDPsForInstances() {
|
|
2062
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances`, {
|
|
2063
|
+
type: 'channel',
|
|
2064
|
+
common: {
|
|
2065
|
+
name: {
|
|
2066
|
+
en: 'Adapter and Instances',
|
|
2067
|
+
de: 'Adapter und Instanzen',
|
|
2068
|
+
ru: 'Адаптер и Instances',
|
|
2069
|
+
pt: 'Adaptador e instâncias',
|
|
2070
|
+
nl: 'Adapter en Instance',
|
|
2071
|
+
fr: 'Adaptateur et instances',
|
|
2072
|
+
it: 'Adattatore e istanze',
|
|
2073
|
+
es: 'Adaptador e instalaciones',
|
|
2074
|
+
pl: 'Adapter and Instances',
|
|
2075
|
+
uk: 'Адаптер та інстанції',
|
|
2076
|
+
'zh-cn': '道歉和案',
|
|
2077
|
+
},
|
|
2078
|
+
},
|
|
2079
|
+
native: {},
|
|
2080
|
+
});
|
|
2081
|
+
|
|
2082
|
+
// Instances
|
|
2083
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.listAllInstances`, {
|
|
2084
|
+
type: 'state',
|
|
2085
|
+
common: {
|
|
2086
|
+
name: {
|
|
2087
|
+
en: 'JSON List of all instances',
|
|
2088
|
+
de: 'JSON Liste aller Instanzen',
|
|
2089
|
+
ru: 'ДЖСОН Список всех инстанций',
|
|
2090
|
+
pt: 'J. Lista de todas as instâncias',
|
|
2091
|
+
nl: 'JSON List van alle instanties',
|
|
2092
|
+
fr: 'JSON Liste de tous les cas',
|
|
2093
|
+
it: 'JSON Elenco di tutte le istanze',
|
|
2094
|
+
es: 'JSON Lista de todos los casos',
|
|
2095
|
+
pl: 'JSON Lista wszystkich instancji',
|
|
2096
|
+
uk: 'Сонце Список всіх екземплярів',
|
|
2097
|
+
'zh-cn': '附 件 所有事例一览表',
|
|
2098
|
+
},
|
|
2099
|
+
type: 'array',
|
|
2100
|
+
role: 'json',
|
|
2101
|
+
read: true,
|
|
2102
|
+
write: false,
|
|
2103
|
+
},
|
|
2104
|
+
native: {},
|
|
2105
|
+
});
|
|
2106
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.countAllInstances`, {
|
|
2107
|
+
type: 'state',
|
|
2108
|
+
common: {
|
|
2109
|
+
name: {
|
|
2110
|
+
en: 'Number of all instances',
|
|
2111
|
+
de: 'Anzahl aller Instanzen',
|
|
2112
|
+
ru: 'Количество всех инстанций',
|
|
2113
|
+
pt: 'Número de todas as instâncias',
|
|
2114
|
+
nl: 'Nummer van alle gevallen',
|
|
2115
|
+
fr: 'Nombre de cas',
|
|
2116
|
+
it: 'Numero di tutte le istanze',
|
|
2117
|
+
es: 'Número de casos',
|
|
2118
|
+
pl: 'Liczba wszystkich instancji',
|
|
2119
|
+
uk: 'Кількість всіх екземплярів',
|
|
2120
|
+
'zh-cn': '各类案件数目',
|
|
2121
|
+
},
|
|
2122
|
+
type: 'number',
|
|
2123
|
+
role: 'value',
|
|
2124
|
+
read: true,
|
|
2125
|
+
write: false,
|
|
2126
|
+
},
|
|
2127
|
+
native: {},
|
|
2128
|
+
});
|
|
2129
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.listDeactivatedInstances`, {
|
|
2130
|
+
type: 'state',
|
|
2131
|
+
common: {
|
|
2132
|
+
name: {
|
|
2133
|
+
en: 'JSON List of deactivated instances',
|
|
2134
|
+
de: 'JSON Liste der deaktivierten Instanzen',
|
|
2135
|
+
ru: 'ДЖСОН Список деактивированных инстанций',
|
|
2136
|
+
pt: 'J. Lista de instâncias desativadas',
|
|
2137
|
+
nl: 'JSON List van gedeactiveerde instanties',
|
|
2138
|
+
fr: 'JSON Liste des cas désactivés',
|
|
2139
|
+
it: 'JSON Elenco delle istanze disattivate',
|
|
2140
|
+
es: 'JSON Lista de casos desactivados',
|
|
2141
|
+
pl: 'JSON Lista przypadków deaktywowanych',
|
|
2142
|
+
uk: 'Сонце Перелік деактивованих екземплярів',
|
|
2143
|
+
'zh-cn': '附 件 被动事例清单',
|
|
2144
|
+
},
|
|
2145
|
+
type: 'array',
|
|
2146
|
+
role: 'json',
|
|
2147
|
+
read: true,
|
|
2148
|
+
write: false,
|
|
2149
|
+
},
|
|
2150
|
+
native: {},
|
|
2151
|
+
});
|
|
2152
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.countDeactivatedInstances`, {
|
|
2153
|
+
type: 'state',
|
|
2154
|
+
common: {
|
|
2155
|
+
name: {
|
|
2156
|
+
en: 'Number of deactivated instances',
|
|
2157
|
+
de: 'Anzahl deaktivierter Instanzen',
|
|
2158
|
+
ru: 'Количество деактивированных инстанций',
|
|
2159
|
+
pt: 'Número de instâncias desativadas',
|
|
2160
|
+
nl: 'Nummer van gedeactiveerde instanties',
|
|
2161
|
+
fr: 'Nombre de cas désactivés',
|
|
2162
|
+
it: 'Numero di istanze disattivate',
|
|
2163
|
+
es: 'Número de casos desactivados',
|
|
2164
|
+
pl: 'Liczba deaktywowanych instancji',
|
|
2165
|
+
uk: 'Кількість деактивованих екземплярів',
|
|
2166
|
+
'zh-cn': 'A. 递解事件的数目',
|
|
2167
|
+
},
|
|
2168
|
+
type: 'number',
|
|
2169
|
+
role: 'value',
|
|
2170
|
+
read: true,
|
|
2171
|
+
write: false,
|
|
2172
|
+
},
|
|
2173
|
+
native: {},
|
|
2174
|
+
});
|
|
2175
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.listInstancesError`, {
|
|
2176
|
+
type: 'state',
|
|
2177
|
+
common: {
|
|
2178
|
+
name: {
|
|
2179
|
+
en: 'JSON list of instances with error',
|
|
2180
|
+
de: 'JSON-Liste von Instanzen mit Fehler',
|
|
2181
|
+
ru: 'JSON список инстанций с ошибкой',
|
|
2182
|
+
pt: 'Lista de instâncias JSON com erro',
|
|
2183
|
+
nl: 'JSON lijst met fouten',
|
|
2184
|
+
fr: 'Liste des instances avec erreur',
|
|
2185
|
+
it: 'Elenco JSON delle istanze con errore',
|
|
2186
|
+
es: 'JSON lista de casos con error',
|
|
2187
|
+
pl: 'Lista błędów JSON',
|
|
2188
|
+
uk: 'JSON список екземплярів з помилкою',
|
|
2189
|
+
'zh-cn': '联合工作组办公室错误事件清单',
|
|
2190
|
+
},
|
|
2191
|
+
type: 'array',
|
|
2192
|
+
role: 'json',
|
|
2193
|
+
read: true,
|
|
2194
|
+
write: false,
|
|
2195
|
+
},
|
|
2196
|
+
native: {},
|
|
2197
|
+
});
|
|
2198
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.countInstancesError`, {
|
|
2199
|
+
type: 'state',
|
|
2200
|
+
common: {
|
|
2201
|
+
name: {
|
|
2202
|
+
en: 'Count of instances with error',
|
|
2203
|
+
de: 'Anzahl der Instanzen mit Fehler',
|
|
2204
|
+
ru: 'Количество инстанций с ошибкой',
|
|
2205
|
+
pt: 'Contagem de instâncias com erro',
|
|
2206
|
+
nl: 'Graaf van instoringen met fouten',
|
|
2207
|
+
fr: 'Nombre de cas avec erreur',
|
|
2208
|
+
it: 'Conteggio di istanze con errore',
|
|
2209
|
+
es: 'Cuenta de casos con error',
|
|
2210
|
+
pl: 'Liczba przykładów w przypadku błędów',
|
|
2211
|
+
uk: 'Кількість екземплярів з помилкою',
|
|
2212
|
+
'zh-cn': '发生错误的情况',
|
|
2213
|
+
},
|
|
2214
|
+
type: 'number',
|
|
2215
|
+
role: 'value',
|
|
2216
|
+
read: true,
|
|
2217
|
+
write: false,
|
|
2218
|
+
},
|
|
2219
|
+
native: {},
|
|
2220
|
+
});
|
|
2221
|
+
|
|
2222
|
+
// Adapter
|
|
2223
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.listAdapterUpdates`, {
|
|
2224
|
+
type: 'state',
|
|
2225
|
+
common: {
|
|
2226
|
+
name: {
|
|
2227
|
+
en: 'JSON list of adapters with available updates',
|
|
2228
|
+
de: 'JSON-Liste der Adapter mit verfügbaren Updates',
|
|
2229
|
+
ru: 'JSON список адаптеров с доступными обновлениями',
|
|
2230
|
+
pt: 'Lista de adaptadores JSON com atualizações disponíveis',
|
|
2231
|
+
nl: 'JSON lijst met beschikbare updates',
|
|
2232
|
+
fr: 'Liste JSON des adaptateurs avec mises à jour disponibles',
|
|
2233
|
+
it: 'Elenco di adattatori JSON con aggiornamenti disponibili',
|
|
2234
|
+
es: 'JSON lista de adaptadores con actualizaciones disponibles',
|
|
2235
|
+
pl: 'JSON lista adapterów z dostępnymi aktualizacjami',
|
|
2236
|
+
uk: 'JSON список адаптерів з доступними оновленнями',
|
|
2237
|
+
'zh-cn': '附录A',
|
|
2238
|
+
},
|
|
2239
|
+
type: 'array',
|
|
2240
|
+
role: 'json',
|
|
2241
|
+
read: true,
|
|
2242
|
+
write: false,
|
|
2243
|
+
},
|
|
2244
|
+
native: {},
|
|
2245
|
+
});
|
|
2246
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.countAdapterUpdates`, {
|
|
2247
|
+
type: 'state',
|
|
2248
|
+
common: {
|
|
2249
|
+
name: {
|
|
2250
|
+
en: 'Number of adapters with available updates',
|
|
2251
|
+
de: 'Anzahl der Adapter mit verfügbaren Updates',
|
|
2252
|
+
ru: 'Количество адаптеров с доступными обновлениями',
|
|
2253
|
+
pt: 'Número de adaptadores com atualizações disponíveis',
|
|
2254
|
+
nl: 'Nummer van adapters met beschikbare updates',
|
|
2255
|
+
fr: "Nombre d'adaptateurs avec mises à jour disponibles",
|
|
2256
|
+
it: 'Numero di adattatori con aggiornamenti disponibili',
|
|
2257
|
+
es: 'Número de adaptadores con actualizaciones disponibles',
|
|
2258
|
+
pl: 'Liczba adapterów z dostępną aktualizacją',
|
|
2259
|
+
uk: 'Кількість адаптерів з доступними оновленнями',
|
|
2260
|
+
'zh-cn': '更新的适应者人数',
|
|
2261
|
+
},
|
|
2262
|
+
type: 'number',
|
|
2263
|
+
role: 'value',
|
|
2264
|
+
read: true,
|
|
2265
|
+
write: false,
|
|
2266
|
+
},
|
|
2267
|
+
native: {},
|
|
2268
|
+
});
|
|
2269
|
+
}
|
|
2270
|
+
|
|
1584
2271
|
/*=============================================
|
|
1585
2272
|
= functions to send notifications =
|
|
1586
2273
|
=============================================*/
|
|
@@ -1731,6 +2418,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1731
2418
|
}
|
|
1732
2419
|
} // <-- End of sendNotification function
|
|
1733
2420
|
|
|
2421
|
+
/*---------- Battery notifications ----------*/
|
|
1734
2422
|
/**
|
|
1735
2423
|
* send shedule message for low battery devices
|
|
1736
2424
|
*/
|
|
@@ -1814,6 +2502,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1814
2502
|
this.log.debug(`Finished the function: ${this.sendLowBatNoticiation.name}`);
|
|
1815
2503
|
}
|
|
1816
2504
|
|
|
2505
|
+
/*---------- Offline/Online notifications ----------*/
|
|
1817
2506
|
/**
|
|
1818
2507
|
* send message if an device is offline
|
|
1819
2508
|
* @param {string} deviceName
|
|
@@ -1905,6 +2594,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1905
2594
|
}
|
|
1906
2595
|
} //<--End of daily offline notification
|
|
1907
2596
|
|
|
2597
|
+
/*---------- Device Updates notifications ----------*/
|
|
1908
2598
|
/**
|
|
1909
2599
|
* check if device updates are available and send notification
|
|
1910
2600
|
* @param {string} deviceName
|
|
@@ -1937,7 +2627,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1937
2627
|
/**
|
|
1938
2628
|
* send shedule message with offline devices
|
|
1939
2629
|
*/
|
|
1940
|
-
async
|
|
2630
|
+
async sendDeviceUpdateNotificationsShedule() {
|
|
1941
2631
|
const time = this.config.checkSendUpgradeTime.split(':');
|
|
1942
2632
|
|
|
1943
2633
|
const checkDays = []; // list of selected days
|
|
@@ -1959,6 +2649,91 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1959
2649
|
return; // cancel function if no day is selected
|
|
1960
2650
|
}
|
|
1961
2651
|
|
|
2652
|
+
if (!isUnloaded) {
|
|
2653
|
+
const cron = '10 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2654
|
+
schedule.scheduleJob(cron, () => {
|
|
2655
|
+
try {
|
|
2656
|
+
let deviceList = '';
|
|
2657
|
+
|
|
2658
|
+
for (const id of this.upgradableDevicesRaw) {
|
|
2659
|
+
if (!this.blacklistNotify.includes(id.Path)) {
|
|
2660
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2661
|
+
deviceList = `${deviceList}\n${id.Device}`;
|
|
2662
|
+
} else {
|
|
2663
|
+
deviceList = `${deviceList}\n${id.Adapter}: ${id.Device}`;
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
if (deviceList.length > 0) {
|
|
2668
|
+
this.log.info(`Geräte Upgrade: ${deviceList}`);
|
|
2669
|
+
this.setStateAsync('lastNotification', `Geräte Upgrade: ${deviceList}`, true);
|
|
2670
|
+
|
|
2671
|
+
this.sendNotification(`Geräte Upgrade:\n${deviceList}`);
|
|
2672
|
+
}
|
|
2673
|
+
} catch (error) {
|
|
2674
|
+
this.errorReporting('[sendUpgradeNotificationsShedule]', error);
|
|
2675
|
+
}
|
|
2676
|
+
});
|
|
2677
|
+
}
|
|
2678
|
+
} //<--End of daily device updates notification
|
|
2679
|
+
|
|
2680
|
+
/*---------- Adapter Updates notifications ----------*/
|
|
2681
|
+
/**
|
|
2682
|
+
* check if adapter updates are available and send notification
|
|
2683
|
+
* @param {string} id
|
|
2684
|
+
* @param {ioBroker.State | null | undefined} state
|
|
2685
|
+
*/
|
|
2686
|
+
async sendAdapterUpdatesNotification(id, state) {
|
|
2687
|
+
this.log.debug(`Start the function: ${this.sendAdapterUpdatesNotification.name}`);
|
|
2688
|
+
|
|
2689
|
+
try {
|
|
2690
|
+
if (state && state !== undefined) {
|
|
2691
|
+
const list = await this.parseData(state.val);
|
|
2692
|
+
let msg = '';
|
|
2693
|
+
let adapterList = '';
|
|
2694
|
+
|
|
2695
|
+
for (const [id] of Object.entries(list)) {
|
|
2696
|
+
adapterList = `${adapterList}\n${this.capitalize(id)} - Version: ${list[id].availableVersion}`;
|
|
2697
|
+
}
|
|
2698
|
+
if (adapterList.length !== 0) {
|
|
2699
|
+
msg = `Neue Adapter Updates vorhanden: \n`;
|
|
2700
|
+
|
|
2701
|
+
this.log.info(msg + adapterList);
|
|
2702
|
+
await this.setStateAsync('lastNotification', msg + adapterList, true);
|
|
2703
|
+
await this.sendNotification(msg + adapterList);
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
} catch (error) {
|
|
2707
|
+
this.errorReporting('[sendAdapterUpdatesNotification]', error);
|
|
2708
|
+
}
|
|
2709
|
+
this.log.debug(`Finished the function: ${this.sendAdapterUpdatesNotification.name}`);
|
|
2710
|
+
}
|
|
2711
|
+
|
|
2712
|
+
/**
|
|
2713
|
+
* send shedule message with list of updatable adapters
|
|
2714
|
+
*/
|
|
2715
|
+
async sendAdapterUpdatesNotificatioShedule() {
|
|
2716
|
+
const time = this.config.checkSendAdapterUpdateTime.split(':');
|
|
2717
|
+
|
|
2718
|
+
const checkDays = []; // list of selected days
|
|
2719
|
+
|
|
2720
|
+
// push the selected days in list
|
|
2721
|
+
if (this.config.checkAdapterUpdateMonday) checkDays.push(1);
|
|
2722
|
+
if (this.config.checkAdapterUpdateTuesday) checkDays.push(2);
|
|
2723
|
+
if (this.config.checkAdapterUpdateWednesday) checkDays.push(3);
|
|
2724
|
+
if (this.config.checkAdapterUpdateThursday) checkDays.push(4);
|
|
2725
|
+
if (this.config.checkAdapterUpdateFriday) checkDays.push(5);
|
|
2726
|
+
if (this.config.checkAdapterUpdateSaturday) checkDays.push(6);
|
|
2727
|
+
if (this.config.checkAdapterUpdateSunday) checkDays.push(0);
|
|
2728
|
+
|
|
2729
|
+
if (checkDays.length >= 1) {
|
|
2730
|
+
// check if an day is selected
|
|
2731
|
+
this.log.debug(`Number of selected days for daily adapter update message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2732
|
+
} else {
|
|
2733
|
+
this.log.warn(`No days selected for daily adapter update message. Please check the instance configuration!`);
|
|
2734
|
+
return; // cancel function if no day is selected
|
|
2735
|
+
}
|
|
2736
|
+
|
|
1962
2737
|
if (!isUnloaded) {
|
|
1963
2738
|
const cron = '10 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
1964
2739
|
schedule.scheduleJob(cron, () => {
|
|
@@ -1987,6 +2762,81 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1987
2762
|
}
|
|
1988
2763
|
} //<--End of daily offline notification
|
|
1989
2764
|
|
|
2765
|
+
/*---------- Instance error notifications ----------*/
|
|
2766
|
+
/**
|
|
2767
|
+
* check if device updates are available and send notification
|
|
2768
|
+
* @param {string} instanceName
|
|
2769
|
+
* @param {string} error
|
|
2770
|
+
**/
|
|
2771
|
+
async sendInstanceErrorNotification(instanceName, error) {
|
|
2772
|
+
this.log.debug(`Start the function: ${this.sendInstanceErrorNotification.name}`);
|
|
2773
|
+
|
|
2774
|
+
try {
|
|
2775
|
+
let msg = '';
|
|
2776
|
+
let instanceList = '';
|
|
2777
|
+
|
|
2778
|
+
instanceList = `${instanceList}\n${instanceName}: ${error}`;
|
|
2779
|
+
|
|
2780
|
+
msg = `Fehler einer Instanz entdeckt: \n`;
|
|
2781
|
+
|
|
2782
|
+
this.log.info(msg + instanceList);
|
|
2783
|
+
await this.setStateAsync('lastNotification', msg + instanceList, true);
|
|
2784
|
+
await this.sendNotification(msg + instanceList);
|
|
2785
|
+
} catch (error) {
|
|
2786
|
+
this.errorReporting('[sendInstanceErrorNotification]', error);
|
|
2787
|
+
}
|
|
2788
|
+
this.log.debug(`Finished the function: ${this.sendInstanceErrorNotification.name}`);
|
|
2789
|
+
}
|
|
2790
|
+
|
|
2791
|
+
/**
|
|
2792
|
+
* send shedule message with offline devices
|
|
2793
|
+
*/
|
|
2794
|
+
async sendInstanceErrorNotificationShedule() {
|
|
2795
|
+
const time = this.config.checkSendInstanceFailedTime.split(':');
|
|
2796
|
+
|
|
2797
|
+
const checkDays = []; // list of selected days
|
|
2798
|
+
|
|
2799
|
+
// push the selected days in list
|
|
2800
|
+
if (this.config.checkFailedInstancesMonday) checkDays.push(1);
|
|
2801
|
+
if (this.config.checkFailedInstancesTuesday) checkDays.push(2);
|
|
2802
|
+
if (this.config.checkFailedInstancesWednesday) checkDays.push(3);
|
|
2803
|
+
if (this.config.checkFailedInstancesThursday) checkDays.push(4);
|
|
2804
|
+
if (this.config.checkFailedInstancesFriday) checkDays.push(5);
|
|
2805
|
+
if (this.config.checkFailedInstancesSaturday) checkDays.push(6);
|
|
2806
|
+
if (this.config.checkFailedInstancesSunday) checkDays.push(0);
|
|
2807
|
+
|
|
2808
|
+
if (checkDays.length >= 1) {
|
|
2809
|
+
// check if an day is selected
|
|
2810
|
+
this.log.debug(`Number of selected days for daily instance error message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2811
|
+
} else {
|
|
2812
|
+
this.log.warn(`No days selected for daily instance error message. Please check the instance configuration!`);
|
|
2813
|
+
return; // cancel function if no day is selected
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
if (!isUnloaded) {
|
|
2817
|
+
const cron = '10 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2818
|
+
schedule.scheduleJob(cron, () => {
|
|
2819
|
+
try {
|
|
2820
|
+
let instanceList = '';
|
|
2821
|
+
|
|
2822
|
+
for (const id of this.listErrorInstanceRaw) {
|
|
2823
|
+
if (!this.blacklistInstancesNotify.includes(id.instanceAlivePath)) {
|
|
2824
|
+
instanceList = `${instanceList}\n${id.Instance}: ${id.Status}`;
|
|
2825
|
+
}
|
|
2826
|
+
}
|
|
2827
|
+
if (instanceList.length > 0) {
|
|
2828
|
+
this.log.info(`Instanz Fehler: ${instanceList}`);
|
|
2829
|
+
this.setStateAsync('lastNotification', `Instanz Fehler: ${instanceList}`, true);
|
|
2830
|
+
|
|
2831
|
+
this.sendNotification(`Instanz Fehler:\n${instanceList}`);
|
|
2832
|
+
}
|
|
2833
|
+
} catch (error) {
|
|
2834
|
+
this.errorReporting('[sendInstanceErrorNotificationShedule]', error);
|
|
2835
|
+
}
|
|
2836
|
+
});
|
|
2837
|
+
}
|
|
2838
|
+
} //<--End of daily device updates notification
|
|
2839
|
+
|
|
1990
2840
|
/*=============================================
|
|
1991
2841
|
= functions to create html lists =
|
|
1992
2842
|
=============================================*/
|
|
@@ -2112,7 +2962,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2112
2962
|
* @param {object} adptName - Adaptername of devices
|
|
2113
2963
|
*/
|
|
2114
2964
|
async createDPsForEachAdapter(adptName) {
|
|
2115
|
-
await this.setObjectNotExistsAsync(
|
|
2965
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}`, {
|
|
2116
2966
|
type: 'channel',
|
|
2117
2967
|
common: {
|
|
2118
2968
|
name: adptName,
|
|
@@ -2120,7 +2970,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2120
2970
|
native: {},
|
|
2121
2971
|
});
|
|
2122
2972
|
|
|
2123
|
-
await this.setObjectNotExistsAsync(
|
|
2973
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.offlineCount`, {
|
|
2124
2974
|
type: 'state',
|
|
2125
2975
|
common: {
|
|
2126
2976
|
name: {
|
|
@@ -2143,7 +2993,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2143
2993
|
native: {},
|
|
2144
2994
|
});
|
|
2145
2995
|
|
|
2146
|
-
await this.setObjectNotExistsAsync(
|
|
2996
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.offlineList`, {
|
|
2147
2997
|
type: 'state',
|
|
2148
2998
|
common: {
|
|
2149
2999
|
name: {
|
|
@@ -2166,7 +3016,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2166
3016
|
native: {},
|
|
2167
3017
|
});
|
|
2168
3018
|
|
|
2169
|
-
await this.setObjectNotExistsAsync(
|
|
3019
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.oneDeviceOffline`, {
|
|
2170
3020
|
type: 'state',
|
|
2171
3021
|
common: {
|
|
2172
3022
|
name: {
|
|
@@ -2191,7 +3041,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2191
3041
|
native: {},
|
|
2192
3042
|
});
|
|
2193
3043
|
|
|
2194
|
-
await this.setObjectNotExistsAsync(
|
|
3044
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.listAll`, {
|
|
2195
3045
|
type: 'state',
|
|
2196
3046
|
common: {
|
|
2197
3047
|
name: {
|
|
@@ -2214,7 +3064,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2214
3064
|
native: {},
|
|
2215
3065
|
});
|
|
2216
3066
|
|
|
2217
|
-
await this.setObjectNotExistsAsync(
|
|
3067
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.linkQualityList`, {
|
|
2218
3068
|
type: 'state',
|
|
2219
3069
|
common: {
|
|
2220
3070
|
name: {
|
|
@@ -2237,7 +3087,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2237
3087
|
native: {},
|
|
2238
3088
|
});
|
|
2239
3089
|
|
|
2240
|
-
await this.setObjectNotExistsAsync(
|
|
3090
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.countAll`, {
|
|
2241
3091
|
type: 'state',
|
|
2242
3092
|
common: {
|
|
2243
3093
|
name: {
|
|
@@ -2260,7 +3110,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2260
3110
|
native: {},
|
|
2261
3111
|
});
|
|
2262
3112
|
|
|
2263
|
-
await this.setObjectNotExistsAsync(
|
|
3113
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.batteryList`, {
|
|
2264
3114
|
type: 'state',
|
|
2265
3115
|
common: {
|
|
2266
3116
|
name: {
|
|
@@ -2283,7 +3133,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2283
3133
|
native: {},
|
|
2284
3134
|
});
|
|
2285
3135
|
|
|
2286
|
-
await this.setObjectNotExistsAsync(
|
|
3136
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.lowBatteryList`, {
|
|
2287
3137
|
type: 'state',
|
|
2288
3138
|
common: {
|
|
2289
3139
|
name: {
|
|
@@ -2306,7 +3156,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2306
3156
|
native: {},
|
|
2307
3157
|
});
|
|
2308
3158
|
|
|
2309
|
-
await this.setObjectNotExistsAsync(
|
|
3159
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.lowBatteryCount`, {
|
|
2310
3160
|
type: 'state',
|
|
2311
3161
|
common: {
|
|
2312
3162
|
name: {
|
|
@@ -2329,7 +3179,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2329
3179
|
native: {},
|
|
2330
3180
|
});
|
|
2331
3181
|
|
|
2332
|
-
await this.setObjectNotExistsAsync(
|
|
3182
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.oneDeviceLowBat`, {
|
|
2333
3183
|
type: 'state',
|
|
2334
3184
|
common: {
|
|
2335
3185
|
name: {
|
|
@@ -2354,7 +3204,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2354
3204
|
native: {},
|
|
2355
3205
|
});
|
|
2356
3206
|
|
|
2357
|
-
await this.setObjectNotExistsAsync(
|
|
3207
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.batteryCount`, {
|
|
2358
3208
|
type: 'state',
|
|
2359
3209
|
common: {
|
|
2360
3210
|
name: {
|
|
@@ -2377,7 +3227,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2377
3227
|
native: {},
|
|
2378
3228
|
});
|
|
2379
3229
|
|
|
2380
|
-
await this.setObjectNotExistsAsync(
|
|
3230
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.upgradableCount`, {
|
|
2381
3231
|
type: 'state',
|
|
2382
3232
|
common: {
|
|
2383
3233
|
name: {
|
|
@@ -2401,7 +3251,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2401
3251
|
native: {},
|
|
2402
3252
|
});
|
|
2403
3253
|
|
|
2404
|
-
await this.setObjectNotExistsAsync(
|
|
3254
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.upgradableList`, {
|
|
2405
3255
|
type: 'state',
|
|
2406
3256
|
common: {
|
|
2407
3257
|
name: {
|
|
@@ -2425,7 +3275,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2425
3275
|
native: {},
|
|
2426
3276
|
});
|
|
2427
3277
|
|
|
2428
|
-
await this.setObjectNotExistsAsync(
|
|
3278
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.oneDeviceUpdatable`, {
|
|
2429
3279
|
type: 'state',
|
|
2430
3280
|
common: {
|
|
2431
3281
|
name: {
|
|
@@ -2463,7 +3313,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2463
3313
|
dpSubFolder = '';
|
|
2464
3314
|
}
|
|
2465
3315
|
|
|
2466
|
-
await this.setObjectNotExistsAsync(
|
|
3316
|
+
await this.setObjectNotExistsAsync(`devices.${dpSubFolder}offlineListHTML`, {
|
|
2467
3317
|
type: 'state',
|
|
2468
3318
|
common: {
|
|
2469
3319
|
name: {
|
|
@@ -2486,7 +3336,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2486
3336
|
native: {},
|
|
2487
3337
|
});
|
|
2488
3338
|
|
|
2489
|
-
await this.setObjectNotExistsAsync(
|
|
3339
|
+
await this.setObjectNotExistsAsync(`devices.${dpSubFolder}linkQualityListHTML`, {
|
|
2490
3340
|
type: 'state',
|
|
2491
3341
|
common: {
|
|
2492
3342
|
name: {
|
|
@@ -2509,7 +3359,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2509
3359
|
native: {},
|
|
2510
3360
|
});
|
|
2511
3361
|
|
|
2512
|
-
await this.setObjectNotExistsAsync(
|
|
3362
|
+
await this.setObjectNotExistsAsync(`devices.${dpSubFolder}batteryListHTML`, {
|
|
2513
3363
|
type: 'state',
|
|
2514
3364
|
common: {
|
|
2515
3365
|
name: {
|
|
@@ -2532,7 +3382,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2532
3382
|
native: {},
|
|
2533
3383
|
});
|
|
2534
3384
|
|
|
2535
|
-
await this.setObjectNotExistsAsync(
|
|
3385
|
+
await this.setObjectNotExistsAsync(`devices.${dpSubFolder}lowBatteryListHTML`, {
|
|
2536
3386
|
type: 'state',
|
|
2537
3387
|
common: {
|
|
2538
3388
|
name: {
|
|
@@ -2616,6 +3466,32 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2616
3466
|
return {};
|
|
2617
3467
|
}
|
|
2618
3468
|
|
|
3469
|
+
/**
|
|
3470
|
+
* @param {number} time
|
|
3471
|
+
*/
|
|
3472
|
+
async wait(time) {
|
|
3473
|
+
return new Promise((resolve) => {
|
|
3474
|
+
setTimeout(resolve, time);
|
|
3475
|
+
});
|
|
3476
|
+
}
|
|
3477
|
+
|
|
3478
|
+
/**
|
|
3479
|
+
* Get previous run of cron job schedule
|
|
3480
|
+
* Requires cron-parser!
|
|
3481
|
+
* Inspired by https://stackoverflow.com/questions/68134104/
|
|
3482
|
+
* @param {string} lastCronRun
|
|
3483
|
+
*/
|
|
3484
|
+
async getPreviousCronRun(lastCronRun) {
|
|
3485
|
+
try {
|
|
3486
|
+
const interval = cronParser.parseExpression(lastCronRun);
|
|
3487
|
+
const previous = interval.prev();
|
|
3488
|
+
return Math.floor(Date.now() - previous.getTime()); // in ms
|
|
3489
|
+
} catch (error) {
|
|
3490
|
+
this.log.warn(error);
|
|
3491
|
+
return;
|
|
3492
|
+
}
|
|
3493
|
+
}
|
|
3494
|
+
|
|
2619
3495
|
/**
|
|
2620
3496
|
* @param {string} codePart - Message Prefix
|
|
2621
3497
|
* @param {object} error - Sentry message
|