iobroker.device-watcher 2.4.1 → 2.6.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 +17 -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 +274 -13
- package/io-package.json +174 -88
- package/lib/arrApart.js +9 -0
- package/main.js +1517 -695
- package/package.json +7 -6
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,25 +24,41 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
23
24
|
useFormatDate: true,
|
|
24
25
|
});
|
|
25
26
|
|
|
27
|
+
// instances and adapters
|
|
28
|
+
// raw arrays
|
|
29
|
+
this.listInstanceRaw = new Map();
|
|
30
|
+
this.adapterUpdatesJsonRaw = [];
|
|
31
|
+
this.listErrorInstanceRaw = [];
|
|
32
|
+
|
|
33
|
+
// user arrays
|
|
34
|
+
this.listAllInstances = [];
|
|
35
|
+
this.listDeactivatedInstances = [];
|
|
36
|
+
this.listAdapterUpdates = [];
|
|
37
|
+
this.listErrorInstance = [];
|
|
38
|
+
|
|
39
|
+
//counts
|
|
40
|
+
this.countAllInstances = 0;
|
|
41
|
+
this.countDeactivatedInstances = 0;
|
|
42
|
+
this.countAdapterUpdates = 0;
|
|
43
|
+
this.countErrorInstance = 0;
|
|
44
|
+
|
|
45
|
+
// devices
|
|
46
|
+
// raw arrays
|
|
47
|
+
this.listAllDevicesRaw = new Map();
|
|
48
|
+
this.batteryLowPoweredRaw = [];
|
|
49
|
+
this.offlineDevicesRaw = [];
|
|
50
|
+
this.upgradableDevicesRaw = [];
|
|
51
|
+
|
|
26
52
|
// arrays
|
|
27
53
|
this.offlineDevices = [];
|
|
28
54
|
this.linkQualityDevices = [];
|
|
29
55
|
this.batteryPowered = [];
|
|
30
56
|
this.batteryLowPowered = [];
|
|
31
57
|
this.listAllDevices = [];
|
|
32
|
-
this.blacklistLists = [];
|
|
33
|
-
this.blacklistAdapterLists = [];
|
|
34
|
-
this.blacklistNotify = [];
|
|
35
58
|
this.selAdapter = [];
|
|
36
59
|
this.adapterSelected = [];
|
|
37
60
|
this.upgradableList = [];
|
|
38
61
|
|
|
39
|
-
// raw arrays
|
|
40
|
-
this.listAllDevicesRaw = [];
|
|
41
|
-
this.batteryLowPoweredRaw = [];
|
|
42
|
-
this.offlineDevicesRaw = [];
|
|
43
|
-
this.upgradableDevicesRaw = [];
|
|
44
|
-
|
|
45
62
|
// counts
|
|
46
63
|
this.offlineDevicesCount = 0;
|
|
47
64
|
this.deviceCounter = 0;
|
|
@@ -50,12 +67,22 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
50
67
|
this.lowBatteryPoweredCount = 0;
|
|
51
68
|
this.upgradableDevicesCount = 0;
|
|
52
69
|
|
|
70
|
+
// Blacklist
|
|
71
|
+
// Instances
|
|
72
|
+
this.blacklistInstancesLists = [];
|
|
73
|
+
this.blacklistInstancesNotify = [];
|
|
74
|
+
|
|
75
|
+
// Devices
|
|
76
|
+
this.blacklistLists = [];
|
|
77
|
+
this.blacklistAdapterLists = [];
|
|
78
|
+
this.blacklistNotify = [];
|
|
79
|
+
|
|
53
80
|
// Interval timer
|
|
54
81
|
this.refreshDataTimeout = null;
|
|
55
82
|
|
|
56
83
|
this.on('ready', this.onReady.bind(this));
|
|
57
84
|
this.on('stateChange', this.onStateChange.bind(this));
|
|
58
|
-
|
|
85
|
+
this.on('objectChange', this.onObjectChange.bind(this));
|
|
59
86
|
this.on('message', this.onMessage.bind(this));
|
|
60
87
|
this.on('unload', this.onUnload.bind(this));
|
|
61
88
|
}
|
|
@@ -104,6 +131,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
104
131
|
nukiExt: this.config.nukiExtDevices,
|
|
105
132
|
nut: this.config.nutDevices,
|
|
106
133
|
ping: this.config.pingDevices,
|
|
134
|
+
proxmox: this.config.proxmoxDevices,
|
|
107
135
|
roomba: this.config.roombaDevices,
|
|
108
136
|
shelly: this.config.shellyDevices,
|
|
109
137
|
smartgarden: this.config.smartgardenDevices,
|
|
@@ -155,6 +183,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
155
183
|
nukiExt: this.config.nukiextendMaxMinutes,
|
|
156
184
|
nut: this.config.nutMaxMinutes,
|
|
157
185
|
ping: this.config.pingMaxMinutes,
|
|
186
|
+
proxmox: this.config.proxmoxMaxMinutes,
|
|
158
187
|
roomba: this.config.roombaMaxMinutes,
|
|
159
188
|
shelly: this.config.shellyMaxMinutes,
|
|
160
189
|
smartgarden: this.config.smartgardenMaxMinutes,
|
|
@@ -192,19 +221,23 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
192
221
|
}
|
|
193
222
|
|
|
194
223
|
//create Blacklist
|
|
195
|
-
|
|
196
|
-
await this.createBlacklist();
|
|
197
|
-
} catch (error) {
|
|
198
|
-
this.errorReporting('[onReady - create blacklist]', error);
|
|
199
|
-
}
|
|
224
|
+
await this.createBlacklist();
|
|
200
225
|
|
|
201
|
-
//create
|
|
202
|
-
|
|
226
|
+
//create datapoints for each adapter if selected
|
|
227
|
+
for (const [id] of Object.entries(arrApart)) {
|
|
203
228
|
try {
|
|
204
|
-
|
|
205
|
-
|
|
229
|
+
if (!this.createOwnFolder) {
|
|
230
|
+
await this.deleteDPsForEachAdapter(id);
|
|
231
|
+
await this.deleteHtmlListDatapoints(id);
|
|
232
|
+
} else {
|
|
233
|
+
if (this.configSetAdapter && this.configSetAdapter[id]) {
|
|
206
234
|
await this.createDPsForEachAdapter(id);
|
|
207
|
-
|
|
235
|
+
// create HTML list datapoints
|
|
236
|
+
if (!this.createHtmlList) {
|
|
237
|
+
await this.deleteHtmlListDatapoints(id);
|
|
238
|
+
} else {
|
|
239
|
+
await this.createHtmlListDatapoints(id);
|
|
240
|
+
}
|
|
208
241
|
this.log.debug(`Created datapoints for ${this.capitalize(id)}`);
|
|
209
242
|
}
|
|
210
243
|
}
|
|
@@ -214,28 +247,84 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
214
247
|
}
|
|
215
248
|
|
|
216
249
|
// create HTML list datapoints
|
|
217
|
-
if (this.createHtmlList)
|
|
250
|
+
if (!this.createHtmlList) {
|
|
251
|
+
await this.deleteHtmlListDatapoints();
|
|
252
|
+
} else {
|
|
253
|
+
await this.createHtmlListDatapoints();
|
|
254
|
+
}
|
|
218
255
|
|
|
219
|
-
//read data first at start
|
|
256
|
+
// read data first at start
|
|
257
|
+
// devices
|
|
220
258
|
await this.main();
|
|
221
259
|
|
|
260
|
+
// instances and adapters
|
|
261
|
+
if (!this.config.checkAdapterInstances) {
|
|
262
|
+
await this.deleteDPsForInstances();
|
|
263
|
+
} else {
|
|
264
|
+
// instances
|
|
265
|
+
await this.createDPsForInstances();
|
|
266
|
+
await this.getAllInstanceData();
|
|
267
|
+
// adapter updates
|
|
268
|
+
await this.createAdapterUpdateData();
|
|
269
|
+
}
|
|
270
|
+
|
|
222
271
|
// update last contact data in interval
|
|
223
272
|
await this.refreshData();
|
|
224
273
|
|
|
225
274
|
// send overview for low battery devices
|
|
226
|
-
if (this.config.checkSendBatteryMsgDaily)
|
|
275
|
+
if (this.config.checkSendBatteryMsgDaily) this.sendScheduleNotifications('lowBatteryDevices');
|
|
227
276
|
|
|
228
277
|
// send overview of offline devices
|
|
229
|
-
if (this.config.checkSendOfflineMsgDaily)
|
|
278
|
+
if (this.config.checkSendOfflineMsgDaily) this.sendScheduleNotifications('offlineDevices');
|
|
230
279
|
|
|
231
280
|
// send overview of upgradeable devices
|
|
232
|
-
if (this.config.checkSendUpgradeMsgDaily)
|
|
281
|
+
if (this.config.checkSendUpgradeMsgDaily) this.sendScheduleNotifications('updateDevices');
|
|
282
|
+
|
|
283
|
+
// send overview of updatable adapters
|
|
284
|
+
if (this.config.checkSendAdapterUpdateMsgDaily) this.sendScheduleNotifications('updateAdapter');
|
|
285
|
+
|
|
286
|
+
// send overview of instances with error
|
|
287
|
+
if (this.config.checkSendInstanceFailedDaily) this.sendScheduleNotifications('errorInstance');
|
|
233
288
|
} catch (error) {
|
|
234
289
|
this.errorReporting('[onReady]', error);
|
|
235
290
|
this.terminate ? this.terminate(15) : process.exit(15);
|
|
236
291
|
}
|
|
237
292
|
} // <-- onReady end
|
|
238
293
|
|
|
294
|
+
// If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.
|
|
295
|
+
// You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`.
|
|
296
|
+
//
|
|
297
|
+
/**
|
|
298
|
+
* Is called if a subscribed object changes
|
|
299
|
+
* @param {string} id
|
|
300
|
+
* @param {ioBroker.Object | null | undefined} obj
|
|
301
|
+
*/
|
|
302
|
+
async onObjectChange(id, obj) {
|
|
303
|
+
if (obj) {
|
|
304
|
+
// The object was changed
|
|
305
|
+
//this.log.warn(`object ${id} changed: ${JSON.stringify(obj)}`);
|
|
306
|
+
|
|
307
|
+
//read new instance data and add it to the lists
|
|
308
|
+
await this.getInstanceData(id);
|
|
309
|
+
|
|
310
|
+
//read devices data and renew the lists
|
|
311
|
+
await this.main();
|
|
312
|
+
} else {
|
|
313
|
+
// The object was deleted
|
|
314
|
+
//this.log.warn(`object ${id} deleted`);
|
|
315
|
+
|
|
316
|
+
// delete instance data in map
|
|
317
|
+
this.listInstanceRaw.delete(id);
|
|
318
|
+
|
|
319
|
+
// delete device data in map
|
|
320
|
+
this.listAllDevicesRaw.delete(id);
|
|
321
|
+
|
|
322
|
+
//unsubscribe of Objects and states
|
|
323
|
+
this.unsubscribeForeignObjects(id);
|
|
324
|
+
this.unsubscribeForeignStates(id);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
239
328
|
/**
|
|
240
329
|
* Is called if a subscribed state changes
|
|
241
330
|
* @param {string} id
|
|
@@ -244,124 +333,196 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
244
333
|
async onStateChange(id, state) {
|
|
245
334
|
// Admin JSON for Adapter updates
|
|
246
335
|
if (id && state) {
|
|
247
|
-
this.log.debug(`State changed: ${id} changed ${state.val}`);
|
|
336
|
+
// this.log.debug(`State changed: ${id} changed ${state.val}`);
|
|
248
337
|
let batteryData;
|
|
249
338
|
let oldLowBatState;
|
|
250
339
|
let contactData;
|
|
251
340
|
let oldStatus;
|
|
252
341
|
let isLowBatValue;
|
|
253
|
-
let
|
|
254
|
-
|
|
342
|
+
let instanceStatusRaw;
|
|
343
|
+
let oldInstanceHostState;
|
|
344
|
+
let oldInstanceDeviceState;
|
|
345
|
+
|
|
346
|
+
for (const adapter of this.adapterUpdatesJsonRaw) {
|
|
347
|
+
switch (id) {
|
|
348
|
+
case adapter.Path:
|
|
349
|
+
await this.getAdapterUpdateData(id);
|
|
350
|
+
await this.createAdapterUpdateList();
|
|
351
|
+
if (this.config.checkSendAdapterUpdateMsg) {
|
|
352
|
+
await this.sendStateNotifications('updateAdapter', null);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
255
356
|
|
|
256
|
-
|
|
257
|
-
|
|
357
|
+
for (const [instance, instanceData] of this.listInstanceRaw) {
|
|
358
|
+
switch (id) {
|
|
359
|
+
case instanceData.instanceAlivePath:
|
|
360
|
+
if (state.val !== instanceData.isAlive) {
|
|
361
|
+
instanceStatusRaw = await this.setInstanceStatus(
|
|
362
|
+
instanceData.instanceMode,
|
|
363
|
+
instanceData.schedule,
|
|
364
|
+
instanceData.instanceAlivePath,
|
|
365
|
+
instanceData.connectedHostPath,
|
|
366
|
+
instanceData.connectedDevicePath,
|
|
367
|
+
);
|
|
368
|
+
instanceData.isAlive = instanceStatusRaw[1];
|
|
369
|
+
instanceData.status = instanceStatusRaw[0];
|
|
370
|
+
instanceData.isHealthy = instanceStatusRaw[2];
|
|
371
|
+
}
|
|
372
|
+
break;
|
|
373
|
+
case instanceData.connectedHostPath:
|
|
374
|
+
oldInstanceHostState = instanceData.isConnectedHost;
|
|
375
|
+
instanceData.isConnectedHost = state.val;
|
|
376
|
+
if (oldInstanceHostState !== instanceData.isConnectedHost) {
|
|
377
|
+
instanceStatusRaw = await this.setInstanceStatus(
|
|
378
|
+
instanceData.instanceMode,
|
|
379
|
+
instanceData.schedule,
|
|
380
|
+
instanceData.instanceAlivePath,
|
|
381
|
+
instanceData.connectedHostPath,
|
|
382
|
+
instanceData.connectedDevicePath,
|
|
383
|
+
);
|
|
384
|
+
instanceData.isAlive = instanceStatusRaw[1];
|
|
385
|
+
instanceData.status = instanceStatusRaw[0];
|
|
386
|
+
instanceData.isHealthy = instanceStatusRaw[2];
|
|
387
|
+
|
|
388
|
+
if (!instanceData.isAlive) continue;
|
|
389
|
+
if (this.config.checkSendInstanceFailedMsg && !this.blacklistInstancesNotify.includes(instanceData.instanceAlivePath)) {
|
|
390
|
+
if (!instanceData.isHealthy) {
|
|
391
|
+
await this.sendStateNotifications('errorInstance', instance);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
break;
|
|
396
|
+
case instanceData.connectedDevicePath:
|
|
397
|
+
oldInstanceDeviceState = instanceData.isConnectedDevice;
|
|
398
|
+
instanceData.isConnectedDevice = state.val;
|
|
399
|
+
if (oldInstanceDeviceState !== instanceData.isConnectedDevice) {
|
|
400
|
+
instanceStatusRaw = await this.setInstanceStatus(
|
|
401
|
+
instanceData.instanceMode,
|
|
402
|
+
instanceData.schedule,
|
|
403
|
+
instanceData.instanceAlivePath,
|
|
404
|
+
instanceData.connectedHostPath,
|
|
405
|
+
instanceData.connectedDevicePath,
|
|
406
|
+
);
|
|
407
|
+
instanceData.isAlive = instanceStatusRaw[1];
|
|
408
|
+
instanceData.status = instanceStatusRaw[0];
|
|
409
|
+
instanceData.isHealthy = instanceStatusRaw[2];
|
|
410
|
+
|
|
411
|
+
if (!instanceData.isAlive) continue;
|
|
412
|
+
if (this.config.checkSendInstanceFailedMsg && !this.blacklistInstancesNotify.includes(instanceData.instanceAlivePath)) {
|
|
413
|
+
if (!instanceData.isHealthy) {
|
|
414
|
+
await this.sendStateNotifications('errorInstance', instance);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
258
421
|
|
|
259
|
-
for (const device of this.listAllDevicesRaw) {
|
|
422
|
+
for (const [device, deviceData] of this.listAllDevicesRaw) {
|
|
260
423
|
// On statechange update available datapoint
|
|
261
424
|
switch (id) {
|
|
262
|
-
case
|
|
263
|
-
if (state.val !==
|
|
264
|
-
|
|
425
|
+
case deviceData.instanceDeviceConnectionDP:
|
|
426
|
+
if (state.val !== deviceData.instancedeviceConnected) {
|
|
427
|
+
deviceData.instancedeviceConnected = state.val;
|
|
265
428
|
}
|
|
266
429
|
break;
|
|
267
430
|
|
|
268
|
-
case
|
|
269
|
-
if (state.val !==
|
|
270
|
-
|
|
431
|
+
case deviceData.UpdateDP:
|
|
432
|
+
if (state.val !== deviceData.Upgradable) {
|
|
433
|
+
deviceData.Upgradable = state.val;
|
|
271
434
|
if (state.val) {
|
|
272
|
-
if (!this.blacklistNotify.includes(
|
|
273
|
-
await this.
|
|
435
|
+
if (this.config.checkSendDeviceUpgrade && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
436
|
+
await this.sendStateNotifications('updateDevice', device);
|
|
274
437
|
}
|
|
275
438
|
}
|
|
276
439
|
}
|
|
277
440
|
break;
|
|
278
441
|
|
|
279
|
-
case
|
|
280
|
-
|
|
442
|
+
case deviceData.SignalStrengthDP:
|
|
443
|
+
deviceData.SignalStrength = await this.calculateSignalStrength(state, deviceData.adapterID);
|
|
281
444
|
break;
|
|
282
445
|
|
|
283
|
-
case
|
|
284
|
-
if (
|
|
285
|
-
oldLowBatState =
|
|
286
|
-
batteryData = await this.getBatteryData(state.val, oldLowBatState,
|
|
446
|
+
case deviceData.batteryDP:
|
|
447
|
+
if (deviceData.isBatteryDevice) {
|
|
448
|
+
oldLowBatState = deviceData.LowBat;
|
|
449
|
+
batteryData = await this.getBatteryData(state.val, oldLowBatState, deviceData.adapterID);
|
|
287
450
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
if (
|
|
291
|
-
isLowBatValue = await this.getInitValue(
|
|
451
|
+
deviceData.Battery = batteryData[0];
|
|
452
|
+
deviceData.BatteryRaw = batteryData[2];
|
|
453
|
+
if (deviceData.LowBatDP !== 'none') {
|
|
454
|
+
isLowBatValue = await this.getInitValue(deviceData.LowBatDP);
|
|
292
455
|
} else {
|
|
293
456
|
isLowBatValue = undefined;
|
|
294
457
|
}
|
|
295
|
-
|
|
458
|
+
deviceData.LowBat = await this.setLowbatIndicator(state.val, isLowBatValue, deviceData.faultReport, deviceData.adapterID);
|
|
296
459
|
|
|
297
|
-
if (
|
|
298
|
-
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(
|
|
299
|
-
await this.
|
|
460
|
+
if (deviceData.LowBat && oldLowBatState !== deviceData.LowBat) {
|
|
461
|
+
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
462
|
+
await this.sendStateNotifications('lowBatDevice', device);
|
|
300
463
|
}
|
|
301
464
|
}
|
|
302
465
|
}
|
|
303
466
|
break;
|
|
304
467
|
|
|
305
|
-
case
|
|
306
|
-
if (
|
|
307
|
-
oldLowBatState =
|
|
308
|
-
batteryData = await this.getBatteryData(
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (
|
|
314
|
-
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(
|
|
315
|
-
await this.
|
|
468
|
+
case deviceData.LowBatDP:
|
|
469
|
+
if (deviceData.isBatteryDevice) {
|
|
470
|
+
oldLowBatState = deviceData.LowBat;
|
|
471
|
+
batteryData = await this.getBatteryData(deviceData.BatteryRaw, state.val, deviceData.adapterID);
|
|
472
|
+
deviceData.Battery = batteryData[0];
|
|
473
|
+
deviceData.BatteryRaw = batteryData[2];
|
|
474
|
+
deviceData.LowBat = await this.setLowbatIndicator(deviceData.BatteryRaw, state.val, deviceData.faultReport, deviceData.adapterID);
|
|
475
|
+
|
|
476
|
+
if (deviceData.LowBat && oldLowBatState !== deviceData.LowBat) {
|
|
477
|
+
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
478
|
+
await this.sendStateNotifications('lowBatDevice', device);
|
|
316
479
|
}
|
|
317
480
|
}
|
|
318
481
|
}
|
|
319
482
|
break;
|
|
320
483
|
|
|
321
|
-
case
|
|
322
|
-
if (
|
|
323
|
-
oldLowBatState =
|
|
324
|
-
batteryData = await this.getBatteryData(
|
|
484
|
+
case deviceData.faultReportDP:
|
|
485
|
+
if (deviceData.isBatteryDevice) {
|
|
486
|
+
oldLowBatState = deviceData.LowBat;
|
|
487
|
+
batteryData = await this.getBatteryData(deviceData.BatteryRaw, oldLowBatState, deviceData.adapterID);
|
|
325
488
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
489
|
+
deviceData.Battery = batteryData[0];
|
|
490
|
+
deviceData.BatteryRaw = batteryData[2];
|
|
491
|
+
deviceData.LowBat = await this.setLowbatIndicator(deviceData.BatteryRaw, undefined, state.val, deviceData.adapterID);
|
|
329
492
|
|
|
330
|
-
if (
|
|
331
|
-
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(
|
|
332
|
-
await this.
|
|
493
|
+
if (deviceData.LowBat && oldLowBatState !== deviceData.LowBat) {
|
|
494
|
+
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
495
|
+
await this.sendStateNotifications('lowBatDevice', device);
|
|
333
496
|
}
|
|
334
497
|
}
|
|
335
498
|
}
|
|
336
499
|
break;
|
|
337
500
|
|
|
338
|
-
case
|
|
339
|
-
oldStatus =
|
|
340
|
-
|
|
501
|
+
case deviceData.UnreachDP:
|
|
502
|
+
oldStatus = deviceData.Status;
|
|
503
|
+
deviceData.UnreachState = await this.getInitValue(deviceData.UnreachDP);
|
|
341
504
|
contactData = await this.getOnlineState(
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
505
|
+
deviceData.timeSelector,
|
|
506
|
+
deviceData.adapterID,
|
|
507
|
+
deviceData.UnreachDP,
|
|
508
|
+
deviceData.SignalStrength,
|
|
509
|
+
deviceData.UnreachState,
|
|
510
|
+
deviceData.DeviceStateSelectorDP,
|
|
511
|
+
deviceData.rssiPeerSelectorDP,
|
|
349
512
|
);
|
|
350
513
|
if (contactData !== undefined) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
514
|
+
deviceData.LastContact = contactData[0];
|
|
515
|
+
deviceData.Status = contactData[1];
|
|
516
|
+
deviceData.SignalStrength = contactData[2];
|
|
354
517
|
}
|
|
355
|
-
if (
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
if (
|
|
359
|
-
await this.
|
|
518
|
+
if (this.config.checkSendOfflineMsg && oldStatus !== deviceData.Status && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
519
|
+
if (deviceData.instanceDeviceConnectionDP !== undefined) {
|
|
520
|
+
// check if the generally deviceData connected state is for a while true
|
|
521
|
+
if (await this.getTimestampConnectionDP(deviceData.instanceDeviceConnectionDP, 20000)) {
|
|
522
|
+
await this.sendStateNotifications('onlineStateDevice', device);
|
|
360
523
|
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
if (this.config.checkSendOfflineMsg && oldStatus !== device.Status && !this.blacklistNotify.includes(device.Path)) {
|
|
364
|
-
await this.sendOfflineNotifications(device.Device, device.Adapter, device.Status, device.LastContact);
|
|
524
|
+
} else {
|
|
525
|
+
await this.sendStateNotifications('onlineStateDevice', device);
|
|
365
526
|
}
|
|
366
527
|
}
|
|
367
528
|
break;
|
|
@@ -375,23 +536,23 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
375
536
|
*/
|
|
376
537
|
onMessage(obj) {
|
|
377
538
|
const devices = [];
|
|
378
|
-
|
|
379
|
-
let
|
|
539
|
+
const instances = [];
|
|
540
|
+
let countDevices = 0;
|
|
541
|
+
let countInstances = 0;
|
|
380
542
|
|
|
381
543
|
switch (obj.command) {
|
|
382
544
|
case 'devicesList':
|
|
383
545
|
if (obj.message) {
|
|
384
546
|
try {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
path: result[element].Path,
|
|
547
|
+
for (const deviceData of this.listAllDevicesRaw.values()) {
|
|
548
|
+
const label = `${deviceData.Adapter}: ${deviceData.Device}`;
|
|
549
|
+
const valueObjectDevices = {
|
|
550
|
+
deviceName: deviceData.Device,
|
|
551
|
+
adapter: deviceData.Adapter,
|
|
552
|
+
path: deviceData.Path,
|
|
392
553
|
};
|
|
393
|
-
devices[
|
|
394
|
-
|
|
554
|
+
devices[countDevices] = { label: label, value: JSON.stringify(valueObjectDevices) };
|
|
555
|
+
countDevices++;
|
|
395
556
|
}
|
|
396
557
|
const sortDevices = devices.slice(0);
|
|
397
558
|
sortDevices.sort(function (a, b) {
|
|
@@ -407,6 +568,34 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
407
568
|
this.sendTo(obj.from, obj.command, obj.callback);
|
|
408
569
|
}
|
|
409
570
|
break;
|
|
571
|
+
|
|
572
|
+
case 'instancesList':
|
|
573
|
+
if (obj.message) {
|
|
574
|
+
try {
|
|
575
|
+
for (const instanceData of this.listInstanceRaw.values()) {
|
|
576
|
+
const label = `${instanceData.Adapter}: ${instanceData.InstanceName}`;
|
|
577
|
+
const valueObjectInstances = {
|
|
578
|
+
adapter: instanceData.Adapter,
|
|
579
|
+
instanceName: instanceData.InstanceName,
|
|
580
|
+
path: instanceData.instanceAlivePath,
|
|
581
|
+
};
|
|
582
|
+
instances[countInstances] = { label: label, value: JSON.stringify(valueObjectInstances) };
|
|
583
|
+
countInstances++;
|
|
584
|
+
}
|
|
585
|
+
const sortInstances = instances.slice(0);
|
|
586
|
+
sortInstances.sort(function (a, b) {
|
|
587
|
+
const x = a.label;
|
|
588
|
+
const y = b.label;
|
|
589
|
+
return x < y ? -1 : x > y ? 1 : 0;
|
|
590
|
+
});
|
|
591
|
+
this.sendTo(obj.from, obj.command, sortInstances, obj.callback);
|
|
592
|
+
} catch (error) {
|
|
593
|
+
this.sendTo(obj.from, obj.command, obj.callback);
|
|
594
|
+
}
|
|
595
|
+
} else {
|
|
596
|
+
this.sendTo(obj.from, obj.command, obj.callback);
|
|
597
|
+
}
|
|
598
|
+
break;
|
|
410
599
|
}
|
|
411
600
|
}
|
|
412
601
|
|
|
@@ -418,7 +607,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
418
607
|
|
|
419
608
|
// fill counts and lists of all selected adapter
|
|
420
609
|
try {
|
|
421
|
-
|
|
610
|
+
for (let i = 0; i < this.selAdapter.length; i++) {
|
|
611
|
+
await this.createData(i);
|
|
612
|
+
await this.createLists();
|
|
613
|
+
}
|
|
614
|
+
await this.writeDatapoints(); // fill the datapoints
|
|
422
615
|
this.log.debug(`Created and filled data for all adapters`);
|
|
423
616
|
} catch (error) {
|
|
424
617
|
this.errorReporting('[main - create data of all adapter]', error);
|
|
@@ -428,8 +621,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
428
621
|
if (this.createOwnFolder) {
|
|
429
622
|
try {
|
|
430
623
|
for (const [id] of Object.entries(arrApart)) {
|
|
431
|
-
if (this.configSetAdapter
|
|
432
|
-
|
|
624
|
+
if (this.configSetAdapter && this.configSetAdapter[id]) {
|
|
625
|
+
for (const deviceData of this.listAllDevicesRaw.values()) {
|
|
626
|
+
// list device only if selected adapter matched with device
|
|
627
|
+
if (!deviceData.adapterID.includes(id)) continue;
|
|
628
|
+
await this.createLists(id);
|
|
629
|
+
}
|
|
630
|
+
await this.writeDatapoints(id); // fill the datapoints
|
|
433
631
|
this.log.debug(`Created and filled data for ${this.capitalize(id)}`);
|
|
434
632
|
}
|
|
435
633
|
}
|
|
@@ -454,7 +652,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
454
652
|
|
|
455
653
|
if (this.createOwnFolder) {
|
|
456
654
|
for (const [id] of Object.entries(arrApart)) {
|
|
457
|
-
if (this.configSetAdapter
|
|
655
|
+
if (this.configSetAdapter && this.configSetAdapter[id]) {
|
|
458
656
|
await this.createLists(id);
|
|
459
657
|
await this.writeDatapoints(id);
|
|
460
658
|
this.log.debug(`Created and filled data for ${this.capitalize(id)}`);
|
|
@@ -462,6 +660,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
462
660
|
}
|
|
463
661
|
}
|
|
464
662
|
|
|
663
|
+
if (this.config.checkAdapterInstances) {
|
|
664
|
+
await this.createInstanceList();
|
|
665
|
+
await this.writeInstanceDPs();
|
|
666
|
+
}
|
|
667
|
+
|
|
465
668
|
// Clear existing timeout
|
|
466
669
|
if (this.refreshDataTimeout) {
|
|
467
670
|
this.log.debug('clearing old refresh timeout');
|
|
@@ -485,11 +688,12 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
485
688
|
async createBlacklist() {
|
|
486
689
|
this.log.debug(`Function started: ${this.createBlacklist.name}`);
|
|
487
690
|
|
|
691
|
+
// DEVICES
|
|
488
692
|
const myBlacklist = this.config.tableBlacklist;
|
|
489
693
|
|
|
490
694
|
for (const i in myBlacklist) {
|
|
491
695
|
try {
|
|
492
|
-
const blacklistParse =
|
|
696
|
+
const blacklistParse = this.parseData(myBlacklist[i].devices);
|
|
493
697
|
// push devices in list to ignor device in lists
|
|
494
698
|
if (myBlacklist[i].checkIgnorLists) {
|
|
495
699
|
this.blacklistLists.push(blacklistParse.path);
|
|
@@ -508,7 +712,29 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
508
712
|
|
|
509
713
|
if (this.blacklistLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistLists}`);
|
|
510
714
|
if (this.blacklistAdapterLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistAdapterLists}`);
|
|
511
|
-
if (this.blacklistNotify.length >= 1) this.log.info(`Found items on blacklist for
|
|
715
|
+
if (this.blacklistNotify.length >= 1) this.log.info(`Found items on blacklist for notifications: ${this.blacklistNotify}`);
|
|
716
|
+
|
|
717
|
+
// INSTANCES
|
|
718
|
+
const myBlacklistInstances = this.config.tableBlacklistInstances;
|
|
719
|
+
|
|
720
|
+
for (const i in myBlacklistInstances) {
|
|
721
|
+
try {
|
|
722
|
+
const blacklistParse = this.parseData(myBlacklistInstances[i].instances);
|
|
723
|
+
// push devices in list to ignor device in lists
|
|
724
|
+
if (myBlacklistInstances[i].checkIgnorLists) {
|
|
725
|
+
this.blacklistInstancesLists.push(blacklistParse.path);
|
|
726
|
+
}
|
|
727
|
+
// push devices in list to ignor device in notifications
|
|
728
|
+
if (myBlacklistInstances[i].checkIgnorNotify) {
|
|
729
|
+
this.blacklistInstancesNotify.push(blacklistParse.path);
|
|
730
|
+
}
|
|
731
|
+
} catch (error) {
|
|
732
|
+
this.errorReporting('[createBlacklist]', error);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
if (this.blacklistInstancesLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistInstancesLists}`);
|
|
737
|
+
if (this.blacklistInstancesNotify.length >= 1) this.log.info(`Found items on blacklist for notifications: ${this.blacklistInstancesNotify}`);
|
|
512
738
|
|
|
513
739
|
this.log.debug(`Function finished: ${this.createBlacklist.name}`);
|
|
514
740
|
}
|
|
@@ -529,6 +755,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
529
755
|
const instanceDeviceConnectionDP = `${instance}.info.connection`;
|
|
530
756
|
const instancedeviceConnected = await this.getInitValue(instanceDeviceConnectionDP);
|
|
531
757
|
this.subscribeForeignStates(instanceDeviceConnectionDP);
|
|
758
|
+
this.subscribeForeignObjectsAsync(`${this.selAdapter[i].Selektor}`);
|
|
532
759
|
|
|
533
760
|
/*=============================================
|
|
534
761
|
= Get device name =
|
|
@@ -546,6 +773,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
546
773
|
const currDeviceString = id.slice(0, id.lastIndexOf('.') + 1 - 1);
|
|
547
774
|
const shortCurrDeviceString = currDeviceString.slice(0, currDeviceString.lastIndexOf('.') + 1 - 1);
|
|
548
775
|
|
|
776
|
+
// subscribe to object device path
|
|
777
|
+
this.subscribeForeignObjectsAsync(currDeviceString);
|
|
778
|
+
|
|
549
779
|
/*=============================================
|
|
550
780
|
= Get signal strength =
|
|
551
781
|
=============================================*/
|
|
@@ -672,8 +902,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
672
902
|
}
|
|
673
903
|
|
|
674
904
|
/*=============================================
|
|
675
|
-
|
|
676
|
-
|
|
905
|
+
= Get update data =
|
|
906
|
+
=============================================*/
|
|
677
907
|
const deviceUpdateDP = currDeviceString + this.selAdapter[i].upgrade;
|
|
678
908
|
let isUpgradable;
|
|
679
909
|
|
|
@@ -692,41 +922,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
692
922
|
/*=============================================
|
|
693
923
|
= Fill Raw Lists =
|
|
694
924
|
=============================================*/
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
if (this.listOnlyBattery) {
|
|
698
|
-
if (isBatteryDevice) {
|
|
699
|
-
this.listAllDevicesRaw.push({
|
|
700
|
-
Path: id,
|
|
701
|
-
instanceDeviceConnectionDP: instanceDeviceConnectionDP,
|
|
702
|
-
instancedeviceConnected: instancedeviceConnected,
|
|
703
|
-
Device: deviceName,
|
|
704
|
-
adapterID: adapterID,
|
|
705
|
-
Adapter: adapter,
|
|
706
|
-
timeSelector: timeSelector,
|
|
707
|
-
isBatteryDevice: isBatteryDevice,
|
|
708
|
-
Battery: batteryHealth,
|
|
709
|
-
BatteryRaw: batteryHealthRaw,
|
|
710
|
-
batteryDP: deviceBatteryStateDP,
|
|
711
|
-
LowBat: lowBatIndicator,
|
|
712
|
-
LowBatDP: isLowBatDP,
|
|
713
|
-
faultReport: faultReportingState,
|
|
714
|
-
faultReportDP: faultReportingDP,
|
|
715
|
-
SignalStrengthDP: deviceQualityDP,
|
|
716
|
-
SignalStrength: linkQuality,
|
|
717
|
-
UnreachState: deviceUnreachState,
|
|
718
|
-
UnreachDP: unreachDP,
|
|
719
|
-
DeviceStateSelectorDP: deviceStateSelectorDP,
|
|
720
|
-
rssiPeerSelectorDP: rssiPeerSelectorDP,
|
|
721
|
-
LastContact: lastContactString,
|
|
722
|
-
Status: deviceState,
|
|
723
|
-
UpdateDP: deviceUpdateDP,
|
|
724
|
-
Upgradable: isUpgradable,
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
} else {
|
|
728
|
-
/* Add all devices */
|
|
729
|
-
this.listAllDevicesRaw.push({
|
|
925
|
+
const setupList = () => {
|
|
926
|
+
this.listAllDevicesRaw.set(currDeviceString, {
|
|
730
927
|
Path: id,
|
|
731
928
|
instanceDeviceConnectionDP: instanceDeviceConnectionDP,
|
|
732
929
|
instancedeviceConnected: instancedeviceConnected,
|
|
@@ -753,6 +950,15 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
753
950
|
UpdateDP: deviceUpdateDP,
|
|
754
951
|
Upgradable: isUpgradable,
|
|
755
952
|
});
|
|
953
|
+
};
|
|
954
|
+
|
|
955
|
+
if (!this.listOnlyBattery) {
|
|
956
|
+
// Add all devices
|
|
957
|
+
setupList();
|
|
958
|
+
} else {
|
|
959
|
+
// Add only devices with battery in the rawlist
|
|
960
|
+
if (!isBatteryDevice) continue;
|
|
961
|
+
setupList();
|
|
756
962
|
}
|
|
757
963
|
} // <-- end of loop
|
|
758
964
|
} // <-- end of createData
|
|
@@ -1028,7 +1234,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1028
1234
|
* @param {object} selector - Selector
|
|
1029
1235
|
*/
|
|
1030
1236
|
async getLastContact(selector) {
|
|
1031
|
-
const lastContact =
|
|
1237
|
+
const lastContact = this.getTimestamp(selector);
|
|
1032
1238
|
let lastContactString;
|
|
1033
1239
|
|
|
1034
1240
|
lastContactString = this.formatDate(new Date(selector), 'hh:mm') + ' Uhr';
|
|
@@ -1061,8 +1267,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1061
1267
|
const deviceUnreachSelector = await this.getForeignStateAsync(unreachDP);
|
|
1062
1268
|
const deviceStateSelector = await this.getForeignStateAsync(deviceStateSelectorDP); // for hmrpc devices
|
|
1063
1269
|
const rssiPeerSelector = await this.getForeignStateAsync(rssiPeerSelectorDP);
|
|
1064
|
-
const lastContact =
|
|
1065
|
-
const lastDeviceUnreachStateChange = deviceUnreachSelector != undefined ?
|
|
1270
|
+
const lastContact = this.getTimestamp(deviceTimeSelector.ts);
|
|
1271
|
+
const lastDeviceUnreachStateChange = deviceUnreachSelector != undefined ? this.getTimestamp(deviceUnreachSelector.lc) : this.getTimestamp(timeSelector.ts);
|
|
1066
1272
|
// If there is no contact since user sets minutes add device in offline list
|
|
1067
1273
|
// calculate to days after 48 hours
|
|
1068
1274
|
switch (unreachDP) {
|
|
@@ -1114,6 +1320,16 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1114
1320
|
linkQuality = '0%'; // set linkQuality to nothing
|
|
1115
1321
|
}
|
|
1116
1322
|
break;
|
|
1323
|
+
case 'proxmox':
|
|
1324
|
+
if (this.configMaxMinutes[adapterID] <= 0) {
|
|
1325
|
+
if (deviceUnreachState !== 'running' && deviceUnreachState !== 'online') {
|
|
1326
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1327
|
+
}
|
|
1328
|
+
} else if (lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID] && deviceUnreachState !== 'running' && deviceUnreachState !== 'online') {
|
|
1329
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1330
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
1331
|
+
}
|
|
1332
|
+
break;
|
|
1117
1333
|
case 'hmiP':
|
|
1118
1334
|
case 'maxcube':
|
|
1119
1335
|
if (this.configMaxMinutes[adapterID] <= 0) {
|
|
@@ -1215,26 +1431,26 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1215
1431
|
* when was last contact of device
|
|
1216
1432
|
*/
|
|
1217
1433
|
async checkLastContact() {
|
|
1218
|
-
for (const device of this.listAllDevicesRaw) {
|
|
1219
|
-
if (
|
|
1220
|
-
const oldContactState =
|
|
1221
|
-
|
|
1434
|
+
for (const [device, deviceData] of this.listAllDevicesRaw) {
|
|
1435
|
+
if (deviceData.instancedeviceConnected !== false) {
|
|
1436
|
+
const oldContactState = deviceData.Status;
|
|
1437
|
+
deviceData.UnreachState = await this.getInitValue(deviceData.UnreachDP);
|
|
1222
1438
|
const contactData = await this.getOnlineState(
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1439
|
+
deviceData.timeSelector,
|
|
1440
|
+
deviceData.adapterID,
|
|
1441
|
+
deviceData.UnreachDP,
|
|
1442
|
+
deviceData.SignalStrength,
|
|
1443
|
+
deviceData.UnreachState,
|
|
1444
|
+
deviceData.DeviceStateSelectorDP,
|
|
1445
|
+
deviceData.rssiPeerSelectorDP,
|
|
1230
1446
|
);
|
|
1231
1447
|
if (contactData !== undefined) {
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1448
|
+
deviceData.LastContact = contactData[0];
|
|
1449
|
+
deviceData.Status = contactData[1];
|
|
1450
|
+
deviceData.linkQuality = contactData[2];
|
|
1235
1451
|
}
|
|
1236
|
-
if (this.config.checkSendOfflineMsg && oldContactState !==
|
|
1237
|
-
await this.
|
|
1452
|
+
if (this.config.checkSendOfflineMsg && oldContactState !== deviceData.Status && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
1453
|
+
await this.sendStateNotifications('onlineStateDevice', device);
|
|
1238
1454
|
}
|
|
1239
1455
|
}
|
|
1240
1456
|
}
|
|
@@ -1258,47 +1474,45 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1258
1474
|
adptName = '';
|
|
1259
1475
|
}
|
|
1260
1476
|
|
|
1261
|
-
for (const
|
|
1477
|
+
for (const deviceData of this.listAllDevicesRaw.values()) {
|
|
1262
1478
|
/*---------- fill raw lists ----------*/
|
|
1263
1479
|
// low bat list
|
|
1264
|
-
if (
|
|
1480
|
+
if (deviceData.LowBat && deviceData.Status !== 'Offline') {
|
|
1265
1481
|
this.batteryLowPoweredRaw.push({
|
|
1266
|
-
Path:
|
|
1267
|
-
Device:
|
|
1268
|
-
Adapter:
|
|
1269
|
-
Battery:
|
|
1482
|
+
Path: deviceData.Path,
|
|
1483
|
+
Device: deviceData.Device,
|
|
1484
|
+
Adapter: deviceData.Adapter,
|
|
1485
|
+
Battery: deviceData.Battery,
|
|
1270
1486
|
});
|
|
1271
1487
|
}
|
|
1272
1488
|
// offline raw list
|
|
1273
|
-
if (
|
|
1489
|
+
if (deviceData.Status === 'Offline') {
|
|
1274
1490
|
this.offlineDevicesRaw.push({
|
|
1275
|
-
Path:
|
|
1276
|
-
Device:
|
|
1277
|
-
Adapter:
|
|
1278
|
-
LastContact:
|
|
1491
|
+
Path: deviceData.Path,
|
|
1492
|
+
Device: deviceData.Device,
|
|
1493
|
+
Adapter: deviceData.Adapter,
|
|
1494
|
+
LastContact: deviceData.LastContact,
|
|
1279
1495
|
});
|
|
1280
1496
|
}
|
|
1281
1497
|
|
|
1282
1498
|
// upgradable raw list
|
|
1283
|
-
if (
|
|
1499
|
+
if (deviceData.Upgradable) {
|
|
1284
1500
|
this.upgradableDevicesRaw.push({
|
|
1285
|
-
Path:
|
|
1286
|
-
Device:
|
|
1287
|
-
Adapter:
|
|
1501
|
+
Path: deviceData.Path,
|
|
1502
|
+
Device: deviceData.Device,
|
|
1503
|
+
Adapter: deviceData.Adapter,
|
|
1288
1504
|
});
|
|
1289
1505
|
}
|
|
1290
1506
|
|
|
1291
|
-
if (adptName === '' && !this.blacklistLists.includes(
|
|
1292
|
-
await this.theLists(
|
|
1507
|
+
if (adptName === '' && !this.blacklistLists.includes(deviceData.Path)) {
|
|
1508
|
+
await this.theLists(deviceData);
|
|
1293
1509
|
}
|
|
1294
1510
|
|
|
1295
1511
|
if (this.config.createOwnFolder && adptName !== '') {
|
|
1296
|
-
if (
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1512
|
+
if (!deviceData.adapterID.includes(adptName)) continue;
|
|
1513
|
+
/*---------- fill user lists for each adapter ----------*/
|
|
1514
|
+
if (this.blacklistAdapterLists.includes(deviceData.Path)) continue;
|
|
1515
|
+
await this.theLists(deviceData);
|
|
1302
1516
|
}
|
|
1303
1517
|
}
|
|
1304
1518
|
await this.countDevices();
|
|
@@ -1388,47 +1602,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1388
1602
|
this.upgradableDevicesCount = this.upgradableList.length;
|
|
1389
1603
|
}
|
|
1390
1604
|
|
|
1391
|
-
/**
|
|
1392
|
-
* @param {string} adptName - Adapter name
|
|
1393
|
-
*/
|
|
1394
|
-
async createDataForEachAdapter(adptName) {
|
|
1395
|
-
// create Data for each Adapter in own lists
|
|
1396
|
-
this.log.debug(`Function started: ${this.createDataForEachAdapter.name}`);
|
|
1397
|
-
|
|
1398
|
-
try {
|
|
1399
|
-
for (const device of this.listAllDevicesRaw) {
|
|
1400
|
-
if (device.adapterID.includes(adptName)) {
|
|
1401
|
-
// list device only if selected adapter matched with device
|
|
1402
|
-
await this.createLists(adptName);
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
await this.writeDatapoints(adptName); // fill the datapoints
|
|
1406
|
-
} catch (error) {
|
|
1407
|
-
this.errorReporting('[createDataForEachAdapter]', error);
|
|
1408
|
-
}
|
|
1409
|
-
|
|
1410
|
-
this.log.debug(`Function finished: ${this.createDataForEachAdapter.name}`);
|
|
1411
|
-
} // <-- end of createDataForEachAdapter
|
|
1412
|
-
|
|
1413
|
-
/**
|
|
1414
|
-
* create Data of all selected adapter in one list
|
|
1415
|
-
*/
|
|
1416
|
-
async createDataOfAllAdapter() {
|
|
1417
|
-
this.log.debug(`Function started: ${this.createDataOfAllAdapter.name}`);
|
|
1418
|
-
|
|
1419
|
-
try {
|
|
1420
|
-
for (let i = 0; i < this.selAdapter.length; i++) {
|
|
1421
|
-
await this.createData(i);
|
|
1422
|
-
await this.createLists();
|
|
1423
|
-
}
|
|
1424
|
-
await this.writeDatapoints(); // fill the datapoints
|
|
1425
|
-
} catch (error) {
|
|
1426
|
-
this.errorReporting('[createDataOfAllAdapter]', error);
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
|
-
this.log.debug(`Function finished: ${this.createDataOfAllAdapter.name}`);
|
|
1430
|
-
} // <-- end of createDataOfAllAdapter
|
|
1431
|
-
|
|
1432
1605
|
/**
|
|
1433
1606
|
* @param {string} [adptName] - Adaptername
|
|
1434
1607
|
*/
|
|
@@ -1447,18 +1620,18 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1447
1620
|
}
|
|
1448
1621
|
|
|
1449
1622
|
// Write Datapoints for counts
|
|
1450
|
-
await this.setStateAsync(
|
|
1451
|
-
await this.setStateAsync(
|
|
1452
|
-
await this.setStateAsync(
|
|
1453
|
-
await this.setStateAsync(
|
|
1454
|
-
await this.setStateAsync(
|
|
1623
|
+
await this.setStateAsync(`devices.${dpSubFolder}offlineCount`, { val: this.offlineDevicesCount, ack: true });
|
|
1624
|
+
await this.setStateAsync(`devices.${dpSubFolder}countAll`, { val: this.deviceCounter, ack: true });
|
|
1625
|
+
await this.setStateAsync(`devices.${dpSubFolder}batteryCount`, { val: this.batteryPoweredCount, ack: true });
|
|
1626
|
+
await this.setStateAsync(`devices.${dpSubFolder}lowBatteryCount`, { val: this.lowBatteryPoweredCount, ack: true });
|
|
1627
|
+
await this.setStateAsync(`devices.${dpSubFolder}upgradableCount`, { val: this.upgradableDevicesCount, ack: true });
|
|
1455
1628
|
|
|
1456
1629
|
// List all devices
|
|
1457
1630
|
if (this.deviceCounter === 0) {
|
|
1458
1631
|
// if no device is count, write the JSON List with default value
|
|
1459
1632
|
this.listAllDevices = [{ Device: '--none--', Adapter: '', Battery: '', 'Last contact': '', 'Signal strength': '' }];
|
|
1460
1633
|
}
|
|
1461
|
-
await this.setStateAsync(
|
|
1634
|
+
await this.setStateAsync(`devices.${dpSubFolder}listAll`, { val: JSON.stringify(this.listAllDevices), ack: true });
|
|
1462
1635
|
|
|
1463
1636
|
// List link quality
|
|
1464
1637
|
if (this.linkQualityCount === 0) {
|
|
@@ -1466,7 +1639,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1466
1639
|
this.linkQualityDevices = [{ Device: '--none--', Adapter: '', 'Signal strength': '' }];
|
|
1467
1640
|
}
|
|
1468
1641
|
//write JSON list
|
|
1469
|
-
await this.setStateAsync(
|
|
1642
|
+
await this.setStateAsync(`devices.${dpSubFolder}linkQualityList`, {
|
|
1470
1643
|
val: JSON.stringify(this.linkQualityDevices),
|
|
1471
1644
|
ack: true,
|
|
1472
1645
|
});
|
|
@@ -1477,7 +1650,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1477
1650
|
this.offlineDevices = [{ Device: '--none--', Adapter: '', 'Last contact': '' }];
|
|
1478
1651
|
}
|
|
1479
1652
|
//write JSON list
|
|
1480
|
-
await this.setStateAsync(
|
|
1653
|
+
await this.setStateAsync(`devices.${dpSubFolder}offlineList`, {
|
|
1481
1654
|
val: JSON.stringify(this.offlineDevices),
|
|
1482
1655
|
ack: true,
|
|
1483
1656
|
});
|
|
@@ -1488,7 +1661,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1488
1661
|
this.upgradableList = [{ Device: '--none--', Adapter: '', 'Last contact': '' }];
|
|
1489
1662
|
}
|
|
1490
1663
|
//write JSON list
|
|
1491
|
-
await this.setStateAsync(
|
|
1664
|
+
await this.setStateAsync(`devices.${dpSubFolder}upgradableList`, {
|
|
1492
1665
|
val: JSON.stringify(this.upgradableList),
|
|
1493
1666
|
ack: true,
|
|
1494
1667
|
});
|
|
@@ -1499,7 +1672,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1499
1672
|
this.batteryPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
|
|
1500
1673
|
}
|
|
1501
1674
|
//write JSON list
|
|
1502
|
-
await this.setStateAsync(
|
|
1675
|
+
await this.setStateAsync(`devices.${dpSubFolder}batteryList`, {
|
|
1503
1676
|
val: JSON.stringify(this.batteryPowered),
|
|
1504
1677
|
ack: true,
|
|
1505
1678
|
});
|
|
@@ -1510,43 +1683,43 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1510
1683
|
this.batteryLowPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
|
|
1511
1684
|
}
|
|
1512
1685
|
//write JSON list
|
|
1513
|
-
await this.setStateAsync(
|
|
1686
|
+
await this.setStateAsync(`devices.${dpSubFolder}lowBatteryList`, {
|
|
1514
1687
|
val: JSON.stringify(this.batteryLowPowered),
|
|
1515
1688
|
ack: true,
|
|
1516
1689
|
});
|
|
1517
1690
|
|
|
1518
1691
|
// set booleans datapoints
|
|
1519
1692
|
if (this.offlineDevicesCount === 0) {
|
|
1520
|
-
await this.setStateAsync(
|
|
1693
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceOffline`, {
|
|
1521
1694
|
val: false,
|
|
1522
1695
|
ack: true,
|
|
1523
1696
|
});
|
|
1524
1697
|
} else {
|
|
1525
|
-
await this.setStateAsync(
|
|
1698
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceOffline`, {
|
|
1526
1699
|
val: true,
|
|
1527
1700
|
ack: true,
|
|
1528
1701
|
});
|
|
1529
1702
|
}
|
|
1530
1703
|
|
|
1531
1704
|
if (this.lowBatteryPoweredCount === 0) {
|
|
1532
|
-
await this.setStateAsync(
|
|
1705
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceLowBat`, {
|
|
1533
1706
|
val: false,
|
|
1534
1707
|
ack: true,
|
|
1535
1708
|
});
|
|
1536
1709
|
} else {
|
|
1537
|
-
await this.setStateAsync(
|
|
1710
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceLowBat`, {
|
|
1538
1711
|
val: true,
|
|
1539
1712
|
ack: true,
|
|
1540
1713
|
});
|
|
1541
1714
|
}
|
|
1542
1715
|
|
|
1543
1716
|
if (this.upgradableDevicesCount === 0) {
|
|
1544
|
-
await this.setStateAsync(
|
|
1717
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceUpdatable`, {
|
|
1545
1718
|
val: false,
|
|
1546
1719
|
ack: true,
|
|
1547
1720
|
});
|
|
1548
1721
|
} else {
|
|
1549
|
-
await this.setStateAsync(
|
|
1722
|
+
await this.setStateAsync(`devices.${dpSubFolder}oneDeviceUpdatable`, {
|
|
1550
1723
|
val: true,
|
|
1551
1724
|
ack: true,
|
|
1552
1725
|
});
|
|
@@ -1554,20 +1727,20 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1554
1727
|
|
|
1555
1728
|
//write HTML list
|
|
1556
1729
|
if (this.createHtmlList) {
|
|
1557
|
-
await this.setStateAsync(
|
|
1558
|
-
val: await this.
|
|
1730
|
+
await this.setStateAsync(`devices.${dpSubFolder}linkQualityListHTML`, {
|
|
1731
|
+
val: await this.createListHTML('linkQualityList', this.linkQualityDevices, this.linkQualityCount, null),
|
|
1559
1732
|
ack: true,
|
|
1560
1733
|
});
|
|
1561
|
-
await this.setStateAsync(
|
|
1562
|
-
val: await this.
|
|
1734
|
+
await this.setStateAsync(`devices.${dpSubFolder}offlineListHTML`, {
|
|
1735
|
+
val: await this.createListHTML('offlineList', this.offlineDevices, this.offlineDevicesCount, null),
|
|
1563
1736
|
ack: true,
|
|
1564
1737
|
});
|
|
1565
|
-
await this.setStateAsync(
|
|
1566
|
-
val: await this.
|
|
1738
|
+
await this.setStateAsync(`devices.${dpSubFolder}batteryListHTML`, {
|
|
1739
|
+
val: await this.createListHTML('batteryList', this.batteryPowered, this.batteryPoweredCount, false),
|
|
1567
1740
|
ack: true,
|
|
1568
1741
|
});
|
|
1569
|
-
await this.setStateAsync(
|
|
1570
|
-
val: await this.
|
|
1742
|
+
await this.setStateAsync(`devices.${dpSubFolder}lowBatteryListHTML`, {
|
|
1743
|
+
val: await this.createListHTML('batteryList', this.batteryLowPowered, this.lowBatteryPoweredCount, true),
|
|
1571
1744
|
ack: true,
|
|
1572
1745
|
});
|
|
1573
1746
|
}
|
|
@@ -1581,109 +1754,680 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1581
1754
|
this.log.debug(`Function finished: ${this.writeDatapoints.name}`);
|
|
1582
1755
|
} //<--End of writing Datapoints
|
|
1583
1756
|
|
|
1584
|
-
/*=============================================
|
|
1585
|
-
= functions to send notifications =
|
|
1586
|
-
=============================================*/
|
|
1587
|
-
|
|
1588
1757
|
/**
|
|
1589
|
-
*
|
|
1590
|
-
* @param {string} text - Text which should be send
|
|
1758
|
+
* get all Instances at start
|
|
1591
1759
|
*/
|
|
1592
|
-
async
|
|
1593
|
-
// Pushover
|
|
1760
|
+
async getAllInstanceData() {
|
|
1594
1761
|
try {
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
const pushoverAliveState = await this.getInitValue('system.adapter.' + this.config.instancePushover + '.alive');
|
|
1598
|
-
|
|
1599
|
-
if (!pushoverAliveState) {
|
|
1600
|
-
this.log.warn('Pushover instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1601
|
-
} else {
|
|
1602
|
-
await this.sendToAsync(this.config.instancePushover, 'send', {
|
|
1603
|
-
message: text,
|
|
1604
|
-
title: this.config.titlePushover,
|
|
1605
|
-
device: this.config.devicePushover,
|
|
1606
|
-
priority: this.config.prioPushover,
|
|
1607
|
-
});
|
|
1608
|
-
}
|
|
1609
|
-
}
|
|
1762
|
+
const allInstances = `system.adapter.*`;
|
|
1763
|
+
await this.getInstanceData(allInstances);
|
|
1610
1764
|
} catch (error) {
|
|
1611
|
-
this.errorReporting('[
|
|
1765
|
+
this.errorReporting('[getInstance]', error);
|
|
1612
1766
|
}
|
|
1767
|
+
}
|
|
1613
1768
|
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1769
|
+
/**
|
|
1770
|
+
* get instance data
|
|
1771
|
+
*@param {string} instanceObject
|
|
1772
|
+
*/
|
|
1773
|
+
async getInstanceData(instanceObject) {
|
|
1774
|
+
const instanceAliveDP = await this.getForeignStatesAsync(`${instanceObject}.alive`);
|
|
1619
1775
|
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
} else {
|
|
1623
|
-
await this.sendToAsync(this.config.instanceTelegram, 'send', {
|
|
1624
|
-
text: text,
|
|
1625
|
-
user: this.config.deviceTelegram,
|
|
1626
|
-
chatId: this.config.chatIdTelegram,
|
|
1627
|
-
});
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1630
|
-
} catch (error) {
|
|
1631
|
-
this.errorReporting('[sendNotification Telegram]', error);
|
|
1632
|
-
}
|
|
1776
|
+
for (const [id] of Object.entries(instanceAliveDP)) {
|
|
1777
|
+
if (!(typeof id === 'string' && id.startsWith(`system.adapter.`))) continue;
|
|
1633
1778
|
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
if (this.config.instanceWhatsapp) {
|
|
1637
|
-
//first check if instance is living
|
|
1638
|
-
const whatsappAliveState = await this.getInitValue('system.adapter.' + this.config.instanceWhatsapp + '.alive');
|
|
1779
|
+
// get instance name
|
|
1780
|
+
const instanceName = await this.getInstanceName(id);
|
|
1639
1781
|
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1782
|
+
// get instance connected to host data
|
|
1783
|
+
const instanceConnectedHostDP = `system.adapter.${instanceName}.connected`;
|
|
1784
|
+
const instanceConnectedHostVal = await this.getInitValue(instanceConnectedHostDP);
|
|
1785
|
+
|
|
1786
|
+
// get instance connected to device data
|
|
1787
|
+
const instanceConnectedDeviceDP = `${instanceName}.info.connection`;
|
|
1788
|
+
let instanceConnectedDeviceVal;
|
|
1789
|
+
if (instanceConnectedDeviceDP !== undefined && typeof instanceConnectedDeviceDP === 'boolean') {
|
|
1790
|
+
instanceConnectedDeviceVal = await this.getInitValue(instanceConnectedDeviceDP);
|
|
1791
|
+
} else {
|
|
1792
|
+
instanceConnectedDeviceVal = 'N/A';
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
// get adapter version
|
|
1796
|
+
const instanceObjectPath = `system.adapter.${instanceName}`;
|
|
1797
|
+
let adapterName;
|
|
1798
|
+
let adapterVersion;
|
|
1799
|
+
let instanceMode;
|
|
1800
|
+
let scheduleTime = 'N/A';
|
|
1801
|
+
const instanceObjectData = await this.getForeignObjectAsync(instanceObjectPath);
|
|
1802
|
+
if (instanceObjectData) {
|
|
1803
|
+
// @ts-ignore
|
|
1804
|
+
adapterName = this.capitalize(instanceObjectData.common.name);
|
|
1805
|
+
adapterVersion = instanceObjectData.common.version;
|
|
1806
|
+
instanceMode = instanceObjectData.common.mode;
|
|
1807
|
+
|
|
1808
|
+
if (instanceMode === 'schedule') {
|
|
1809
|
+
scheduleTime = instanceObjectData.common.schedule;
|
|
1647
1810
|
}
|
|
1648
1811
|
}
|
|
1649
|
-
|
|
1650
|
-
this.
|
|
1812
|
+
|
|
1813
|
+
//const adapterVersionVal = await this.getInitValue(adapterVersionDP);
|
|
1814
|
+
const instanceStatusRaw = await this.setInstanceStatus(instanceMode, scheduleTime, id, instanceConnectedHostDP, instanceConnectedDeviceDP);
|
|
1815
|
+
const isAlive = instanceStatusRaw[1];
|
|
1816
|
+
const instanceStatus = instanceStatusRaw[0];
|
|
1817
|
+
const isHealthy = instanceStatusRaw[2];
|
|
1818
|
+
|
|
1819
|
+
//subscribe to statechanges
|
|
1820
|
+
this.subscribeForeignStatesAsync(id);
|
|
1821
|
+
this.subscribeForeignStatesAsync(instanceConnectedHostDP);
|
|
1822
|
+
this.subscribeForeignStatesAsync(instanceConnectedDeviceDP);
|
|
1823
|
+
this.subscribeForeignObjectsAsync(instanceObjectPath);
|
|
1824
|
+
|
|
1825
|
+
// create raw list
|
|
1826
|
+
this.listInstanceRaw.set(instanceObjectPath, {
|
|
1827
|
+
Adapter: adapterName,
|
|
1828
|
+
InstanceName: instanceName,
|
|
1829
|
+
instanceObjectPath: instanceObjectPath,
|
|
1830
|
+
instanceAlivePath: id,
|
|
1831
|
+
instanceMode: instanceMode,
|
|
1832
|
+
schedule: scheduleTime,
|
|
1833
|
+
adapterVersion: adapterVersion,
|
|
1834
|
+
isAlive: isAlive,
|
|
1835
|
+
isHealthy: isHealthy,
|
|
1836
|
+
connectedHostPath: instanceConnectedHostDP,
|
|
1837
|
+
isConnectedHost: instanceConnectedHostVal,
|
|
1838
|
+
connectedDevicePath: instanceConnectedDeviceDP,
|
|
1839
|
+
isConnectedDevice: instanceConnectedDeviceVal,
|
|
1840
|
+
status: instanceStatus,
|
|
1841
|
+
});
|
|
1651
1842
|
}
|
|
1843
|
+
await this.createInstanceList();
|
|
1844
|
+
await this.writeInstanceDPs();
|
|
1845
|
+
}
|
|
1652
1846
|
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1847
|
+
/**
|
|
1848
|
+
* get Instances
|
|
1849
|
+
* @param {string} id - Path of alive datapoint
|
|
1850
|
+
*/
|
|
1851
|
+
async getInstanceName(id) {
|
|
1852
|
+
let instance = id;
|
|
1853
|
+
instance = instance.slice(15); // remove "system.adapter."
|
|
1854
|
+
instance = instance.slice(0, instance.lastIndexOf('.') + 1 - 1); // remove ".alive"
|
|
1855
|
+
return instance;
|
|
1856
|
+
}
|
|
1658
1857
|
|
|
1659
|
-
|
|
1660
|
-
|
|
1858
|
+
/**
|
|
1859
|
+
* set status for instance
|
|
1860
|
+
* @param {string} instanceMode
|
|
1861
|
+
* @param {string} scheduleTime
|
|
1862
|
+
* @param {object} instanceAlivePath
|
|
1863
|
+
* @param {string} hostConnectedPath
|
|
1864
|
+
* @param {string} isDeviceConnctedPath
|
|
1865
|
+
*/
|
|
1866
|
+
async setInstanceStatus(instanceMode, scheduleTime, instanceAlivePath, hostConnectedPath, isDeviceConnctedPath) {
|
|
1867
|
+
const isAliveSchedule = await this.getForeignStateAsync(instanceAlivePath);
|
|
1868
|
+
let isHostConnected = await this.getInitValue(hostConnectedPath);
|
|
1869
|
+
let isAlive = await this.getInitValue(instanceAlivePath);
|
|
1870
|
+
let isDeviceConnected = await this.getInitValue(isDeviceConnctedPath);
|
|
1871
|
+
let instanceStatusString = 'Instance deactivated';
|
|
1872
|
+
let lastUpdate;
|
|
1873
|
+
let lastCronRun;
|
|
1874
|
+
let diff;
|
|
1875
|
+
let previousCronRun = null;
|
|
1876
|
+
let isHealthy = false;
|
|
1877
|
+
|
|
1878
|
+
switch (instanceMode) {
|
|
1879
|
+
case 'schedule':
|
|
1880
|
+
if (isAliveSchedule) {
|
|
1881
|
+
lastUpdate = Math.round((Date.now() - isAliveSchedule.lc) / 1000); // Last state change in seconds
|
|
1882
|
+
previousCronRun = this.getPreviousCronRun(scheduleTime); // When was the last cron run
|
|
1883
|
+
if (previousCronRun) {
|
|
1884
|
+
lastCronRun = Math.round(previousCronRun / 1000); // change distance to last run in seconds
|
|
1885
|
+
diff = lastCronRun - lastUpdate;
|
|
1886
|
+
if (diff > -300) {
|
|
1887
|
+
// if 5 minutes difference exceeded, instance is not alive
|
|
1888
|
+
isAlive = true;
|
|
1889
|
+
isHealthy = true;
|
|
1890
|
+
instanceStatusString = 'Instanz okay';
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
break;
|
|
1895
|
+
case 'daemon':
|
|
1896
|
+
if (!isAlive) return ['Instanz deaktiviert', false, null]; // if instance is turned off
|
|
1897
|
+
if (isDeviceConnected === undefined) isDeviceConnected = true;
|
|
1898
|
+
// In case of (re)start, connection may take some time. We take 3 attempts.
|
|
1899
|
+
// Attempt 1/3 - immediately
|
|
1900
|
+
if (isHostConnected && isDeviceConnected) {
|
|
1901
|
+
isHealthy = true;
|
|
1902
|
+
instanceStatusString = 'Instanz okay';
|
|
1661
1903
|
} else {
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1904
|
+
// Attempt 2/3 - after 10 seconds
|
|
1905
|
+
await this.wait(10000);
|
|
1906
|
+
isDeviceConnected = await this.getInitValue(isDeviceConnctedPath);
|
|
1907
|
+
isHostConnected = await this.getInitValue(hostConnectedPath);
|
|
1908
|
+
|
|
1909
|
+
if (isHostConnected && isDeviceConnected) {
|
|
1910
|
+
isHealthy = true;
|
|
1911
|
+
instanceStatusString = 'Instanz okay';
|
|
1912
|
+
} else {
|
|
1913
|
+
// Attempt 3/3 - after 20 seconds in total
|
|
1914
|
+
await this.wait(10000);
|
|
1915
|
+
isDeviceConnected = await this.getInitValue(isDeviceConnctedPath);
|
|
1916
|
+
isHostConnected = await this.getInitValue(hostConnectedPath);
|
|
1917
|
+
|
|
1918
|
+
if (isHostConnected && isDeviceConnected) {
|
|
1919
|
+
isHealthy = true;
|
|
1920
|
+
instanceStatusString = 'Instanz okay';
|
|
1921
|
+
} else {
|
|
1922
|
+
if (!isDeviceConnected) {
|
|
1923
|
+
instanceStatusString = 'Nicht verbunden mit Gerät oder Dienst';
|
|
1924
|
+
isHealthy = false;
|
|
1925
|
+
} else if (!isHostConnected) {
|
|
1926
|
+
instanceStatusString = 'Nicht verbunden mit Host';
|
|
1927
|
+
isHealthy = false;
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1667
1931
|
}
|
|
1668
|
-
|
|
1669
|
-
} catch (error) {
|
|
1670
|
-
this.errorReporting('[sendNotification eMail]', error);
|
|
1932
|
+
break;
|
|
1671
1933
|
}
|
|
1672
1934
|
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
if (this.config.instanceJarvis) {
|
|
1676
|
-
//first check if instance is living
|
|
1677
|
-
const jarvisAliveState = await this.getInitValue('system.adapter.' + this.config.instanceJarvis + '.alive');
|
|
1935
|
+
return [instanceStatusString, isAlive, isHealthy];
|
|
1936
|
+
}
|
|
1678
1937
|
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1938
|
+
/**
|
|
1939
|
+
* create adapter update data
|
|
1940
|
+
*/
|
|
1941
|
+
async createAdapterUpdateData() {
|
|
1942
|
+
const adapterUpdateListDP = `admin.*.info.updatesJson`;
|
|
1943
|
+
|
|
1944
|
+
// subscribe to datapoint
|
|
1945
|
+
this.subscribeForeignStates(adapterUpdateListDP);
|
|
1946
|
+
|
|
1947
|
+
await this.getAdapterUpdateData(adapterUpdateListDP);
|
|
1948
|
+
|
|
1949
|
+
await this.createAdapterUpdateList();
|
|
1950
|
+
}
|
|
1951
|
+
|
|
1952
|
+
/**
|
|
1953
|
+
* create adapter update raw lists
|
|
1954
|
+
* @param {string} adapterUpdateListDP
|
|
1955
|
+
*/
|
|
1956
|
+
async getAdapterUpdateData(adapterUpdateListDP) {
|
|
1957
|
+
this.adapterUpdatesJsonRaw = [];
|
|
1958
|
+
const adapterUpdatesListVal = await this.getForeignStatesAsync(adapterUpdateListDP);
|
|
1959
|
+
|
|
1960
|
+
let adapterJsonList;
|
|
1961
|
+
let adapterUpdatesJsonPath;
|
|
1962
|
+
|
|
1963
|
+
for (const [id] of Object.entries(adapterUpdatesListVal)) {
|
|
1964
|
+
adapterJsonList = this.parseData(adapterUpdatesListVal[id].val);
|
|
1965
|
+
adapterUpdatesJsonPath = id;
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
for (const [id] of Object.entries(adapterJsonList)) {
|
|
1969
|
+
this.adapterUpdatesJsonRaw.push({
|
|
1970
|
+
Path: adapterUpdatesJsonPath,
|
|
1971
|
+
Adapter: this.capitalize(id),
|
|
1972
|
+
newVersion: adapterJsonList[id].availableVersion,
|
|
1973
|
+
oldVersion: adapterJsonList[id].installedVersion,
|
|
1974
|
+
});
|
|
1975
|
+
}
|
|
1976
|
+
return this.adapterUpdatesJsonRaw;
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
/**
|
|
1980
|
+
* create instanceList
|
|
1981
|
+
*/
|
|
1982
|
+
async createAdapterUpdateList() {
|
|
1983
|
+
this.listAdapterUpdates = [];
|
|
1984
|
+
this.countAdapterUpdates = 0;
|
|
1985
|
+
|
|
1986
|
+
for (const adapter of this.adapterUpdatesJsonRaw) {
|
|
1987
|
+
this.listAdapterUpdates.push({
|
|
1988
|
+
Adapter: adapter.Adapter,
|
|
1989
|
+
'Available Version': adapter.newVersion,
|
|
1990
|
+
'Installed Version': adapter.oldVersion,
|
|
1991
|
+
});
|
|
1992
|
+
}
|
|
1993
|
+
this.countAdapterUpdates = this.listAdapterUpdates.length;
|
|
1994
|
+
await this.writeAdapterUpdatesDPs();
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
/**
|
|
1998
|
+
* write datapoints for adapter with updates
|
|
1999
|
+
*/
|
|
2000
|
+
async writeAdapterUpdatesDPs() {
|
|
2001
|
+
// Write Datapoints for counts
|
|
2002
|
+
await this.setStateAsync(`adapterAndInstances.countAdapterUpdates`, { val: this.countAdapterUpdates, ack: true });
|
|
2003
|
+
|
|
2004
|
+
// list deactivated instances
|
|
2005
|
+
if (this.countAdapterUpdates === 0) {
|
|
2006
|
+
this.listAdapterUpdates = [{ Adapter: '--none--', 'Available Version': '', 'Installed Version': '' }];
|
|
2007
|
+
}
|
|
2008
|
+
await this.setStateAsync(`adapterAndInstances.listAdapterUpdates`, { val: JSON.stringify(this.listAdapterUpdates), ack: true });
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
/**
|
|
2012
|
+
* create instanceList
|
|
2013
|
+
*/
|
|
2014
|
+
async createInstanceList() {
|
|
2015
|
+
this.listAllInstances = [];
|
|
2016
|
+
this.listDeactivatedInstances = [];
|
|
2017
|
+
this.listErrorInstanceRaw = [];
|
|
2018
|
+
this.listErrorInstance = [];
|
|
2019
|
+
|
|
2020
|
+
for (const instance of this.listInstanceRaw.values()) {
|
|
2021
|
+
// fill raw list
|
|
2022
|
+
if (instance.isAlive && !instance.isHealthy) {
|
|
2023
|
+
this.listErrorInstanceRaw.push({
|
|
2024
|
+
Adapter: instance.Adapter,
|
|
2025
|
+
Instance: instance.InstanceName,
|
|
2026
|
+
Mode: instance.instanceMode,
|
|
2027
|
+
Status: instance.status,
|
|
2028
|
+
});
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
if (this.blacklistInstancesLists.includes(instance.instanceAlivePath)) continue;
|
|
2032
|
+
this.listAllInstances.push({
|
|
2033
|
+
Adapter: instance.Adapter,
|
|
2034
|
+
Instance: instance.InstanceName,
|
|
2035
|
+
Mode: instance.instanceMode,
|
|
2036
|
+
Schedule: instance.schedule,
|
|
2037
|
+
Version: instance.adapterVersion,
|
|
2038
|
+
Status: instance.status,
|
|
2039
|
+
});
|
|
2040
|
+
if (!instance.isAlive) {
|
|
2041
|
+
this.listDeactivatedInstances.push({
|
|
2042
|
+
Adapter: instance.Adapter,
|
|
2043
|
+
Instance: instance.InstanceName,
|
|
2044
|
+
Status: instance.status,
|
|
2045
|
+
});
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
// fill List for User
|
|
2049
|
+
if (instance.isAlive && !instance.isHealthy) {
|
|
2050
|
+
this.listErrorInstance.push({
|
|
2051
|
+
Adapter: instance.Adapter,
|
|
2052
|
+
Instance: instance.InstanceName,
|
|
2053
|
+
Mode: instance.instanceMode,
|
|
2054
|
+
Status: instance.status,
|
|
2055
|
+
});
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
await this.countInstances();
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
/**
|
|
2062
|
+
* count instanceList
|
|
2063
|
+
*/
|
|
2064
|
+
async countInstances() {
|
|
2065
|
+
this.countAllInstances = 0;
|
|
2066
|
+
this.countDeactivatedInstances = 0;
|
|
2067
|
+
this.countErrorInstance = 0;
|
|
2068
|
+
|
|
2069
|
+
this.countAllInstances = this.listAllInstances.length;
|
|
2070
|
+
this.countDeactivatedInstances = this.listDeactivatedInstances.length;
|
|
2071
|
+
this.countErrorInstance = this.listErrorInstance.length;
|
|
2072
|
+
}
|
|
2073
|
+
|
|
2074
|
+
/**
|
|
2075
|
+
* write datapoints for instances list and counts
|
|
2076
|
+
*/
|
|
2077
|
+
async writeInstanceDPs() {
|
|
2078
|
+
// Write Datapoints for counts
|
|
2079
|
+
await this.setStateAsync(`adapterAndInstances.countAllInstances`, { val: this.countAllInstances, ack: true });
|
|
2080
|
+
await this.setStateAsync(`adapterAndInstances.countDeactivatedInstances`, { val: this.countDeactivatedInstances, ack: true });
|
|
2081
|
+
|
|
2082
|
+
// List all instances
|
|
2083
|
+
await this.setStateAsync(`adapterAndInstances.listAllInstances`, { val: JSON.stringify(this.listAllInstances), ack: true });
|
|
2084
|
+
|
|
2085
|
+
// list deactivated instances
|
|
2086
|
+
if (this.countDeactivatedInstances === 0) {
|
|
2087
|
+
this.listDeactivatedInstances = [{ Instance: '--none--', Version: '', Status: '' }];
|
|
2088
|
+
}
|
|
2089
|
+
await this.setStateAsync(`adapterAndInstances.listDeactivatedInstances`, { val: JSON.stringify(this.listDeactivatedInstances), ack: true });
|
|
2090
|
+
await this.setStateAsync(`adapterAndInstances.countDeactivatedInstances`, { val: this.countDeactivatedInstances, ack: true });
|
|
2091
|
+
|
|
2092
|
+
// list error instances
|
|
2093
|
+
if (this.countErrorInstance === 0) {
|
|
2094
|
+
this.listErrorInstance = [{ Instance: '--none--', Mode: '', Status: '' }];
|
|
2095
|
+
}
|
|
2096
|
+
await this.setStateAsync(`adapterAndInstances.listInstancesError`, { val: JSON.stringify(this.listErrorInstance), ack: true });
|
|
2097
|
+
await this.setStateAsync(`adapterAndInstances.countInstancesError`, { val: this.countErrorInstance, ack: true });
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
/**
|
|
2101
|
+
* create Datapoints for Instances
|
|
2102
|
+
*/
|
|
2103
|
+
async createDPsForInstances() {
|
|
2104
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances`, {
|
|
2105
|
+
type: 'channel',
|
|
2106
|
+
common: {
|
|
2107
|
+
name: {
|
|
2108
|
+
en: 'Adapter and Instances',
|
|
2109
|
+
de: 'Adapter und Instanzen',
|
|
2110
|
+
ru: 'Адаптер и Instances',
|
|
2111
|
+
pt: 'Adaptador e instâncias',
|
|
2112
|
+
nl: 'Adapter en Instance',
|
|
2113
|
+
fr: 'Adaptateur et instances',
|
|
2114
|
+
it: 'Adattatore e istanze',
|
|
2115
|
+
es: 'Adaptador e instalaciones',
|
|
2116
|
+
pl: 'Adapter and Instances',
|
|
2117
|
+
uk: 'Адаптер та інстанції',
|
|
2118
|
+
'zh-cn': '道歉和案',
|
|
2119
|
+
},
|
|
2120
|
+
},
|
|
2121
|
+
native: {},
|
|
2122
|
+
});
|
|
2123
|
+
|
|
2124
|
+
// Instances
|
|
2125
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.listAllInstances`, {
|
|
2126
|
+
type: 'state',
|
|
2127
|
+
common: {
|
|
2128
|
+
name: {
|
|
2129
|
+
en: 'JSON List of all instances',
|
|
2130
|
+
de: 'JSON Liste aller Instanzen',
|
|
2131
|
+
ru: 'ДЖСОН Список всех инстанций',
|
|
2132
|
+
pt: 'J. Lista de todas as instâncias',
|
|
2133
|
+
nl: 'JSON List van alle instanties',
|
|
2134
|
+
fr: 'JSON Liste de tous les cas',
|
|
2135
|
+
it: 'JSON Elenco di tutte le istanze',
|
|
2136
|
+
es: 'JSON Lista de todos los casos',
|
|
2137
|
+
pl: 'JSON Lista wszystkich instancji',
|
|
2138
|
+
uk: 'Сонце Список всіх екземплярів',
|
|
2139
|
+
'zh-cn': '附 件 所有事例一览表',
|
|
2140
|
+
},
|
|
2141
|
+
type: 'array',
|
|
2142
|
+
role: 'json',
|
|
2143
|
+
read: true,
|
|
2144
|
+
write: false,
|
|
2145
|
+
},
|
|
2146
|
+
native: {},
|
|
2147
|
+
});
|
|
2148
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.countAllInstances`, {
|
|
2149
|
+
type: 'state',
|
|
2150
|
+
common: {
|
|
2151
|
+
name: {
|
|
2152
|
+
en: 'Number of all instances',
|
|
2153
|
+
de: 'Anzahl aller Instanzen',
|
|
2154
|
+
ru: 'Количество всех инстанций',
|
|
2155
|
+
pt: 'Número de todas as instâncias',
|
|
2156
|
+
nl: 'Nummer van alle gevallen',
|
|
2157
|
+
fr: 'Nombre de cas',
|
|
2158
|
+
it: 'Numero di tutte le istanze',
|
|
2159
|
+
es: 'Número de casos',
|
|
2160
|
+
pl: 'Liczba wszystkich instancji',
|
|
2161
|
+
uk: 'Кількість всіх екземплярів',
|
|
2162
|
+
'zh-cn': '各类案件数目',
|
|
2163
|
+
},
|
|
2164
|
+
type: 'number',
|
|
2165
|
+
role: 'value',
|
|
2166
|
+
read: true,
|
|
2167
|
+
write: false,
|
|
2168
|
+
},
|
|
2169
|
+
native: {},
|
|
2170
|
+
});
|
|
2171
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.listDeactivatedInstances`, {
|
|
2172
|
+
type: 'state',
|
|
2173
|
+
common: {
|
|
2174
|
+
name: {
|
|
2175
|
+
en: 'JSON List of deactivated instances',
|
|
2176
|
+
de: 'JSON Liste der deaktivierten Instanzen',
|
|
2177
|
+
ru: 'ДЖСОН Список деактивированных инстанций',
|
|
2178
|
+
pt: 'J. Lista de instâncias desativadas',
|
|
2179
|
+
nl: 'JSON List van gedeactiveerde instanties',
|
|
2180
|
+
fr: 'JSON Liste des cas désactivés',
|
|
2181
|
+
it: 'JSON Elenco delle istanze disattivate',
|
|
2182
|
+
es: 'JSON Lista de casos desactivados',
|
|
2183
|
+
pl: 'JSON Lista przypadków deaktywowanych',
|
|
2184
|
+
uk: 'Сонце Перелік деактивованих екземплярів',
|
|
2185
|
+
'zh-cn': '附 件 被动事例清单',
|
|
2186
|
+
},
|
|
2187
|
+
type: 'array',
|
|
2188
|
+
role: 'json',
|
|
2189
|
+
read: true,
|
|
2190
|
+
write: false,
|
|
2191
|
+
},
|
|
2192
|
+
native: {},
|
|
2193
|
+
});
|
|
2194
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.countDeactivatedInstances`, {
|
|
2195
|
+
type: 'state',
|
|
2196
|
+
common: {
|
|
2197
|
+
name: {
|
|
2198
|
+
en: 'Number of deactivated instances',
|
|
2199
|
+
de: 'Anzahl deaktivierter Instanzen',
|
|
2200
|
+
ru: 'Количество деактивированных инстанций',
|
|
2201
|
+
pt: 'Número de instâncias desativadas',
|
|
2202
|
+
nl: 'Nummer van gedeactiveerde instanties',
|
|
2203
|
+
fr: 'Nombre de cas désactivés',
|
|
2204
|
+
it: 'Numero di istanze disattivate',
|
|
2205
|
+
es: 'Número de casos desactivados',
|
|
2206
|
+
pl: 'Liczba deaktywowanych instancji',
|
|
2207
|
+
uk: 'Кількість деактивованих екземплярів',
|
|
2208
|
+
'zh-cn': 'A. 递解事件的数目',
|
|
2209
|
+
},
|
|
2210
|
+
type: 'number',
|
|
2211
|
+
role: 'value',
|
|
2212
|
+
read: true,
|
|
2213
|
+
write: false,
|
|
2214
|
+
},
|
|
2215
|
+
native: {},
|
|
2216
|
+
});
|
|
2217
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.listInstancesError`, {
|
|
2218
|
+
type: 'state',
|
|
2219
|
+
common: {
|
|
2220
|
+
name: {
|
|
2221
|
+
en: 'JSON list of instances with error',
|
|
2222
|
+
de: 'JSON-Liste von Instanzen mit Fehler',
|
|
2223
|
+
ru: 'JSON список инстанций с ошибкой',
|
|
2224
|
+
pt: 'Lista de instâncias JSON com erro',
|
|
2225
|
+
nl: 'JSON lijst met fouten',
|
|
2226
|
+
fr: 'Liste des instances avec erreur',
|
|
2227
|
+
it: 'Elenco JSON delle istanze con errore',
|
|
2228
|
+
es: 'JSON lista de casos con error',
|
|
2229
|
+
pl: 'Lista błędów JSON',
|
|
2230
|
+
uk: 'JSON список екземплярів з помилкою',
|
|
2231
|
+
'zh-cn': '联合工作组办公室错误事件清单',
|
|
2232
|
+
},
|
|
2233
|
+
type: 'array',
|
|
2234
|
+
role: 'json',
|
|
2235
|
+
read: true,
|
|
2236
|
+
write: false,
|
|
2237
|
+
},
|
|
2238
|
+
native: {},
|
|
2239
|
+
});
|
|
2240
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.countInstancesError`, {
|
|
2241
|
+
type: 'state',
|
|
2242
|
+
common: {
|
|
2243
|
+
name: {
|
|
2244
|
+
en: 'Count of instances with error',
|
|
2245
|
+
de: 'Anzahl der Instanzen mit Fehler',
|
|
2246
|
+
ru: 'Количество инстанций с ошибкой',
|
|
2247
|
+
pt: 'Contagem de instâncias com erro',
|
|
2248
|
+
nl: 'Graaf van instoringen met fouten',
|
|
2249
|
+
fr: 'Nombre de cas avec erreur',
|
|
2250
|
+
it: 'Conteggio di istanze con errore',
|
|
2251
|
+
es: 'Cuenta de casos con error',
|
|
2252
|
+
pl: 'Liczba przykładów w przypadku błędów',
|
|
2253
|
+
uk: 'Кількість екземплярів з помилкою',
|
|
2254
|
+
'zh-cn': '发生错误的情况',
|
|
2255
|
+
},
|
|
2256
|
+
type: 'number',
|
|
2257
|
+
role: 'value',
|
|
2258
|
+
read: true,
|
|
2259
|
+
write: false,
|
|
2260
|
+
},
|
|
2261
|
+
native: {},
|
|
2262
|
+
});
|
|
2263
|
+
|
|
2264
|
+
// Adapter
|
|
2265
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.listAdapterUpdates`, {
|
|
2266
|
+
type: 'state',
|
|
2267
|
+
common: {
|
|
2268
|
+
name: {
|
|
2269
|
+
en: 'JSON list of adapters with available updates',
|
|
2270
|
+
de: 'JSON-Liste der Adapter mit verfügbaren Updates',
|
|
2271
|
+
ru: 'JSON список адаптеров с доступными обновлениями',
|
|
2272
|
+
pt: 'Lista de adaptadores JSON com atualizações disponíveis',
|
|
2273
|
+
nl: 'JSON lijst met beschikbare updates',
|
|
2274
|
+
fr: 'Liste JSON des adaptateurs avec mises à jour disponibles',
|
|
2275
|
+
it: 'Elenco di adattatori JSON con aggiornamenti disponibili',
|
|
2276
|
+
es: 'JSON lista de adaptadores con actualizaciones disponibles',
|
|
2277
|
+
pl: 'JSON lista adapterów z dostępnymi aktualizacjami',
|
|
2278
|
+
uk: 'JSON список адаптерів з доступними оновленнями',
|
|
2279
|
+
'zh-cn': '附录A',
|
|
2280
|
+
},
|
|
2281
|
+
type: 'array',
|
|
2282
|
+
role: 'json',
|
|
2283
|
+
read: true,
|
|
2284
|
+
write: false,
|
|
2285
|
+
},
|
|
2286
|
+
native: {},
|
|
2287
|
+
});
|
|
2288
|
+
await this.setObjectNotExistsAsync(`adapterAndInstances.countAdapterUpdates`, {
|
|
2289
|
+
type: 'state',
|
|
2290
|
+
common: {
|
|
2291
|
+
name: {
|
|
2292
|
+
en: 'Number of adapters with available updates',
|
|
2293
|
+
de: 'Anzahl der Adapter mit verfügbaren Updates',
|
|
2294
|
+
ru: 'Количество адаптеров с доступными обновлениями',
|
|
2295
|
+
pt: 'Número de adaptadores com atualizações disponíveis',
|
|
2296
|
+
nl: 'Nummer van adapters met beschikbare updates',
|
|
2297
|
+
fr: "Nombre d'adaptateurs avec mises à jour disponibles",
|
|
2298
|
+
it: 'Numero di adattatori con aggiornamenti disponibili',
|
|
2299
|
+
es: 'Número de adaptadores con actualizaciones disponibles',
|
|
2300
|
+
pl: 'Liczba adapterów z dostępną aktualizacją',
|
|
2301
|
+
uk: 'Кількість адаптерів з доступними оновленнями',
|
|
2302
|
+
'zh-cn': '更新的适应者人数',
|
|
2303
|
+
},
|
|
2304
|
+
type: 'number',
|
|
2305
|
+
role: 'value',
|
|
2306
|
+
read: true,
|
|
2307
|
+
write: false,
|
|
2308
|
+
},
|
|
2309
|
+
native: {},
|
|
2310
|
+
});
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
/**
|
|
2314
|
+
* delete Datapoints for Instances
|
|
2315
|
+
*/
|
|
2316
|
+
async deleteDPsForInstances() {
|
|
2317
|
+
await this.delObjectAsync(`adapterAndInstances`);
|
|
2318
|
+
await this.delObjectAsync(`adapterAndInstances.listAllInstances`);
|
|
2319
|
+
await this.delObjectAsync(`adapterAndInstances.countAllInstances`);
|
|
2320
|
+
await this.delObjectAsync(`adapterAndInstances.listDeactivatedInstances`);
|
|
2321
|
+
await this.delObjectAsync(`adapterAndInstances.countDeactivatedInstances`);
|
|
2322
|
+
await this.delObjectAsync(`adapterAndInstances.listInstancesError`);
|
|
2323
|
+
await this.delObjectAsync(`adapterAndInstances.countInstancesError`);
|
|
2324
|
+
await this.delObjectAsync(`adapterAndInstances.listAdapterUpdates`);
|
|
2325
|
+
await this.delObjectAsync(`adapterAndInstances.countAdapterUpdates`);
|
|
2326
|
+
}
|
|
2327
|
+
|
|
2328
|
+
/*=============================================
|
|
2329
|
+
= functions to send notifications =
|
|
2330
|
+
=============================================*/
|
|
2331
|
+
|
|
2332
|
+
/**
|
|
2333
|
+
* Notification service
|
|
2334
|
+
* @param {string} text - Text which should be send
|
|
2335
|
+
*/
|
|
2336
|
+
async sendNotification(text) {
|
|
2337
|
+
// Pushover
|
|
2338
|
+
try {
|
|
2339
|
+
if (this.config.instancePushover) {
|
|
2340
|
+
//first check if instance is living
|
|
2341
|
+
const pushoverAliveState = await this.getInitValue('system.adapter.' + this.config.instancePushover + '.alive');
|
|
2342
|
+
|
|
2343
|
+
if (!pushoverAliveState) {
|
|
2344
|
+
this.log.warn('Pushover instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
2345
|
+
} else {
|
|
2346
|
+
await this.sendToAsync(this.config.instancePushover, 'send', {
|
|
2347
|
+
message: text,
|
|
2348
|
+
title: this.config.titlePushover,
|
|
2349
|
+
device: this.config.devicePushover,
|
|
2350
|
+
priority: this.config.prioPushover,
|
|
2351
|
+
});
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
} catch (error) {
|
|
2355
|
+
this.errorReporting('[sendNotification Pushover]', error);
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
// Telegram
|
|
2359
|
+
try {
|
|
2360
|
+
if (this.config.instanceTelegram) {
|
|
2361
|
+
//first check if instance is living
|
|
2362
|
+
const telegramAliveState = await this.getInitValue('system.adapter.' + this.config.instanceTelegram + '.alive');
|
|
2363
|
+
|
|
2364
|
+
if (!telegramAliveState) {
|
|
2365
|
+
this.log.warn('Telegram instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
2366
|
+
} else {
|
|
2367
|
+
await this.sendToAsync(this.config.instanceTelegram, 'send', {
|
|
2368
|
+
text: text,
|
|
2369
|
+
user: this.config.deviceTelegram,
|
|
2370
|
+
chatId: this.config.chatIdTelegram,
|
|
2371
|
+
});
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
} catch (error) {
|
|
2375
|
+
this.errorReporting('[sendNotification Telegram]', error);
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
// Whatsapp
|
|
2379
|
+
try {
|
|
2380
|
+
if (this.config.instanceWhatsapp) {
|
|
2381
|
+
//first check if instance is living
|
|
2382
|
+
const whatsappAliveState = await this.getInitValue('system.adapter.' + this.config.instanceWhatsapp + '.alive');
|
|
2383
|
+
|
|
2384
|
+
if (!whatsappAliveState) {
|
|
2385
|
+
this.log.warn('Whatsapp instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
2386
|
+
} else {
|
|
2387
|
+
await this.sendToAsync(this.config.instanceWhatsapp, 'send', {
|
|
2388
|
+
text: text,
|
|
2389
|
+
phone: this.config.phoneWhatsapp,
|
|
2390
|
+
});
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
} catch (error) {
|
|
2394
|
+
this.errorReporting('[sendNotification Whatsapp]', error);
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
// Email
|
|
2398
|
+
try {
|
|
2399
|
+
if (this.config.instanceEmail) {
|
|
2400
|
+
//first check if instance is living
|
|
2401
|
+
const eMailAliveState = await this.getInitValue('system.adapter.' + this.config.instanceEmail + '.alive');
|
|
2402
|
+
|
|
2403
|
+
if (!eMailAliveState) {
|
|
2404
|
+
this.log.warn('eMail instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
2405
|
+
} else {
|
|
2406
|
+
await this.sendToAsync(this.config.instanceEmail, 'send', {
|
|
2407
|
+
sendTo: this.config.sendToEmail,
|
|
2408
|
+
text: text,
|
|
2409
|
+
subject: this.config.subjectEmail,
|
|
2410
|
+
});
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
} catch (error) {
|
|
2414
|
+
this.errorReporting('[sendNotification eMail]', error);
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
// Jarvis Notification
|
|
2418
|
+
try {
|
|
2419
|
+
if (this.config.instanceJarvis) {
|
|
2420
|
+
//first check if instance is living
|
|
2421
|
+
const jarvisAliveState = await this.getInitValue('system.adapter.' + this.config.instanceJarvis + '.alive');
|
|
2422
|
+
|
|
2423
|
+
if (!jarvisAliveState) {
|
|
2424
|
+
this.log.warn('Jarvis instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
2425
|
+
} else {
|
|
2426
|
+
const jsonText = JSON.stringify(text);
|
|
2427
|
+
await this.setForeignStateAsync(
|
|
2428
|
+
`${this.config.instanceJarvis}.addNotification`,
|
|
2429
|
+
'{"title":"' + this.config.titleJarvis + ' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message": ' + jsonText + ',"display": "drawer"}',
|
|
2430
|
+
);
|
|
1687
2431
|
}
|
|
1688
2432
|
}
|
|
1689
2433
|
} catch (error) {
|
|
@@ -1731,376 +2475,379 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1731
2475
|
}
|
|
1732
2476
|
} // <-- End of sendNotification function
|
|
1733
2477
|
|
|
2478
|
+
/*---------- Notifications ----------*/
|
|
1734
2479
|
/**
|
|
1735
|
-
*
|
|
2480
|
+
* Notifications on state changes
|
|
2481
|
+
* @param {string} type
|
|
2482
|
+
* @param {object} id
|
|
1736
2483
|
*/
|
|
1737
|
-
async
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
if (!this.blacklistNotify.includes(id.Path)) {
|
|
1767
|
-
if (!this.config.showAdapterNameinMsg) {
|
|
1768
|
-
deviceList = `${deviceList}\n${id.Device} (${id.Battery})`;
|
|
1769
|
-
} else {
|
|
1770
|
-
// Add adaptername if checkbox is checked true in options by user
|
|
1771
|
-
deviceList = `${deviceList}\n${id.Adapter}: ${id.Device} (${id.Battery})`;
|
|
1772
|
-
}
|
|
2484
|
+
async sendStateNotifications(type, id) {
|
|
2485
|
+
if (isUnloaded) return;
|
|
2486
|
+
let objectData;
|
|
2487
|
+
let list = '';
|
|
2488
|
+
let message = '';
|
|
2489
|
+
const setMessage = async (message) => {
|
|
2490
|
+
this.log.info(`${message}`);
|
|
2491
|
+
await this.setStateAsync('lastNotification', `${message}`, true);
|
|
2492
|
+
await this.sendNotification(`${message}`);
|
|
2493
|
+
return (message = '');
|
|
2494
|
+
};
|
|
2495
|
+
switch (type) {
|
|
2496
|
+
case 'lowBatDevice':
|
|
2497
|
+
objectData = this.listAllDevicesRaw.get(id);
|
|
2498
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2499
|
+
message = `Gerät mit geringer Batterie erkannt: \n${objectData.Device} (${objectData.Battery})`;
|
|
2500
|
+
} else {
|
|
2501
|
+
message = `Gerät mit geringer Batterie erkannt: \n${objectData.Adapter}: ${objectData.Device} (${objectData.Battery})`;
|
|
2502
|
+
}
|
|
2503
|
+
setMessage(message);
|
|
2504
|
+
break;
|
|
2505
|
+
case 'onlineStateDevice':
|
|
2506
|
+
objectData = this.listAllDevicesRaw.get(id);
|
|
2507
|
+
switch (objectData.Status) {
|
|
2508
|
+
case 'Online':
|
|
2509
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2510
|
+
message = `Folgendes Gerät ist wieder erreichbar: \n${objectData.Device} (${objectData.LastContact})`;
|
|
2511
|
+
} else {
|
|
2512
|
+
message = `Folgendes Gerät ist wieder erreichbar: \n${objectData.Adapter}: ${objectData.Device} (${objectData.LastContact})`;
|
|
1773
2513
|
}
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
this.
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
this.errorReporting('[sendBatteryNotifyShedule]', error);
|
|
2514
|
+
break;
|
|
2515
|
+
case 'Offline':
|
|
2516
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2517
|
+
message = `Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n${objectData.Device} (${objectData.LastContact})`;
|
|
2518
|
+
} else {
|
|
2519
|
+
message = `Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n${objectData.Adapter}: ${objectData.Device} (${objectData.LastContact})`;
|
|
2520
|
+
}
|
|
2521
|
+
break;
|
|
1783
2522
|
}
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
let msg = '';
|
|
1799
|
-
let deviceList = '';
|
|
1800
|
-
|
|
1801
|
-
if (!this.config.showAdapterNameinMsg) {
|
|
1802
|
-
deviceList = `${deviceList}\n${deviceName} (${battery})`;
|
|
1803
|
-
} else {
|
|
1804
|
-
deviceList = `${deviceList}\n${adapter}: ${deviceName} (${battery})`;
|
|
1805
|
-
}
|
|
1806
|
-
msg = `Gerät mit geringer Batterie erkannt: \n`;
|
|
2523
|
+
setMessage(message);
|
|
2524
|
+
break;
|
|
2525
|
+
case 'updateDevice':
|
|
2526
|
+
objectData = this.listAllDevicesRaw.get(id);
|
|
2527
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2528
|
+
message = `Neue Geräte Updates vorhanden: \n${objectData.Device}`;
|
|
2529
|
+
} else {
|
|
2530
|
+
message = `Neue Geräte Updates vorhanden: \n${objectData.Adapter}: ${objectData.Device}`;
|
|
2531
|
+
}
|
|
2532
|
+
setMessage(message);
|
|
2533
|
+
break;
|
|
2534
|
+
case 'updateAdapter':
|
|
2535
|
+
objectData = this.listAdapterUpdates;
|
|
2536
|
+
list = '';
|
|
1807
2537
|
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
2538
|
+
for (const id of objectData) {
|
|
2539
|
+
list = `${list}\n${id.Adapter}: v${id['Available Version']}`;
|
|
2540
|
+
}
|
|
2541
|
+
if (list.length === 0) return;
|
|
2542
|
+
message = `Neue Adapter Updates vorhanden: ${list}`;
|
|
2543
|
+
setMessage(message);
|
|
2544
|
+
break;
|
|
2545
|
+
case 'errorInstance':
|
|
2546
|
+
objectData = this.listInstanceRaw.get(id);
|
|
2547
|
+
message = `Instanz Watchdog:\n${objectData.InstanceName}: ${objectData.status}`;
|
|
2548
|
+
setMessage(message);
|
|
2549
|
+
break;
|
|
1813
2550
|
}
|
|
1814
|
-
this.log.debug(`Finished the function: ${this.sendLowBatNoticiation.name}`);
|
|
1815
2551
|
}
|
|
1816
2552
|
|
|
1817
2553
|
/**
|
|
1818
|
-
*
|
|
1819
|
-
* @param {string}
|
|
1820
|
-
* @param {string} adapter
|
|
1821
|
-
* @param {string} status
|
|
1822
|
-
* @param {string} lastContact
|
|
2554
|
+
* Notifications per user defined schedule
|
|
2555
|
+
* @param {string} type
|
|
1823
2556
|
*/
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
}
|
|
1834
|
-
|
|
1835
|
-
}
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
//
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
2557
|
+
sendScheduleNotifications(type) {
|
|
2558
|
+
if (isUnloaded) return;
|
|
2559
|
+
|
|
2560
|
+
let time;
|
|
2561
|
+
let cron;
|
|
2562
|
+
let list = '';
|
|
2563
|
+
let message = '';
|
|
2564
|
+
const checkDays = [];
|
|
2565
|
+
const setMessage = async (message) => {
|
|
2566
|
+
this.log.info(`${message}`);
|
|
2567
|
+
await this.setStateAsync('lastNotification', `${message}`, true);
|
|
2568
|
+
await this.sendNotification(`${message}`);
|
|
2569
|
+
return (message = '');
|
|
2570
|
+
};
|
|
2571
|
+
|
|
2572
|
+
switch (type) {
|
|
2573
|
+
case 'lowBatteryDevices':
|
|
2574
|
+
// push the selected days in list
|
|
2575
|
+
if (this.config.checkMonday) checkDays.push(1);
|
|
2576
|
+
if (this.config.checkTuesday) checkDays.push(2);
|
|
2577
|
+
if (this.config.checkWednesday) checkDays.push(3);
|
|
2578
|
+
if (this.config.checkThursday) checkDays.push(4);
|
|
2579
|
+
if (this.config.checkFriday) checkDays.push(5);
|
|
2580
|
+
if (this.config.checkSaturday) checkDays.push(6);
|
|
2581
|
+
if (this.config.checkSunday) checkDays.push(0);
|
|
2582
|
+
|
|
2583
|
+
time = this.config.checkSendBatteryTime.split(':');
|
|
2584
|
+
|
|
2585
|
+
if (checkDays.length === 0) {
|
|
2586
|
+
this.log.warn(`No days selected for daily low battery devices message. Please check the instance configuration!`);
|
|
2587
|
+
return; // cancel function if no day is selected
|
|
2588
|
+
}
|
|
2589
|
+
this.log.debug(`Number of selected days for daily low battery devices message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
1853
2590
|
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
2591
|
+
cron = '1 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2592
|
+
schedule.scheduleJob(cron, () => {
|
|
2593
|
+
list = '';
|
|
2594
|
+
for (const id of this.batteryLowPoweredRaw) {
|
|
2595
|
+
if (this.blacklistNotify.includes(id.Path)) continue;
|
|
2596
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2597
|
+
list = `${list}\n${id.Device} (${id.Battery})`;
|
|
2598
|
+
} else {
|
|
2599
|
+
// Add adaptername if checkbox is checked true in options by user
|
|
2600
|
+
list = `${list}\n${id.Adapter}: ${id.Device} (${id.Battery})`;
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
if (list.length === 0) return;
|
|
2604
|
+
message = `Tägliche Meldung über Geräte mit niedrigen Batteriezuständen: ${list}`;
|
|
2605
|
+
setMessage(message);
|
|
2606
|
+
});
|
|
2607
|
+
break;
|
|
2608
|
+
case 'offlineDevices':
|
|
2609
|
+
// push the selected days in list
|
|
2610
|
+
if (this.config.checkOfflineMonday) checkDays.push(1);
|
|
2611
|
+
if (this.config.checkOfflineTuesday) checkDays.push(2);
|
|
2612
|
+
if (this.config.checkOfflineWednesday) checkDays.push(3);
|
|
2613
|
+
if (this.config.checkOfflineThursday) checkDays.push(4);
|
|
2614
|
+
if (this.config.checkOfflineFriday) checkDays.push(5);
|
|
2615
|
+
if (this.config.checkOfflineSaturday) checkDays.push(6);
|
|
2616
|
+
if (this.config.checkOfflineSunday) checkDays.push(0);
|
|
2617
|
+
|
|
2618
|
+
time = this.config.checkSendOfflineTime.split(':');
|
|
2619
|
+
|
|
2620
|
+
if (checkDays.length === 0) {
|
|
2621
|
+
this.log.warn(`No days selected for daily offline devices message. Please check the instance configuration!`);
|
|
2622
|
+
return; // cancel function if no day is selected
|
|
2623
|
+
}
|
|
2624
|
+
this.log.debug(`Number of selected days for daily offline devices message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
1878
2625
|
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
try {
|
|
1883
|
-
let deviceList = '';
|
|
2626
|
+
cron = '2 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2627
|
+
schedule.scheduleJob(cron, () => {
|
|
2628
|
+
list = '';
|
|
1884
2629
|
|
|
1885
2630
|
for (const id of this.offlineDevicesRaw) {
|
|
1886
|
-
if (
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
}
|
|
2631
|
+
if (this.blacklistNotify.includes(id.Path)) continue;
|
|
2632
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2633
|
+
list = `${list}\n${id.Device} (${id.LastContact})`;
|
|
2634
|
+
} else {
|
|
2635
|
+
list = `${list}\n${id.Adapter}: ${id.Device} (${id.LastContact})`;
|
|
1892
2636
|
}
|
|
1893
2637
|
}
|
|
1894
2638
|
|
|
1895
|
-
if (
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
2639
|
+
if (list.length === 0) return;
|
|
2640
|
+
message = `Tägliche Meldung über offline Geräte: ${list}`;
|
|
2641
|
+
setMessage(message);
|
|
2642
|
+
});
|
|
2643
|
+
break;
|
|
2644
|
+
case 'updateDevices':
|
|
2645
|
+
// push the selected days in list
|
|
2646
|
+
if (this.config.checkUpgradeMonday) checkDays.push(1);
|
|
2647
|
+
if (this.config.checkUpgradeTuesday) checkDays.push(2);
|
|
2648
|
+
if (this.config.checkUpgradeWednesday) checkDays.push(3);
|
|
2649
|
+
if (this.config.checkUpgradeThursday) checkDays.push(4);
|
|
2650
|
+
if (this.config.checkUpgradeFriday) checkDays.push(5);
|
|
2651
|
+
if (this.config.checkUpgradeSaturday) checkDays.push(6);
|
|
2652
|
+
if (this.config.checkUpgradeSunday) checkDays.push(0);
|
|
2653
|
+
|
|
2654
|
+
time = this.config.checkSendUpgradeTime.split(':');
|
|
2655
|
+
|
|
2656
|
+
if (checkDays.length === 0) {
|
|
2657
|
+
this.log.warn(`No days selected for daily updatable devices message. Please check the instance configuration!`);
|
|
2658
|
+
return; // cancel function if no day is selected
|
|
1903
2659
|
}
|
|
1904
|
-
|
|
1905
|
-
}
|
|
1906
|
-
} //<--End of daily offline notification
|
|
1907
|
-
|
|
1908
|
-
/**
|
|
1909
|
-
* check if device updates are available and send notification
|
|
1910
|
-
* @param {string} deviceName
|
|
1911
|
-
* @param {string} adapter
|
|
1912
|
-
**/
|
|
1913
|
-
async sendDeviceUpdatesNotification(deviceName, adapter) {
|
|
1914
|
-
this.log.debug(`Start the function: ${this.sendDeviceUpdatesNotification.name}`);
|
|
1915
|
-
|
|
1916
|
-
try {
|
|
1917
|
-
let msg = '';
|
|
1918
|
-
let deviceList = '';
|
|
1919
|
-
|
|
1920
|
-
if (!this.config.showAdapterNameinMsg) {
|
|
1921
|
-
deviceList = `${deviceList}\n${deviceName}`;
|
|
1922
|
-
} else {
|
|
1923
|
-
deviceList = `${deviceList}\n${adapter}: ${deviceName}`;
|
|
1924
|
-
}
|
|
1925
|
-
|
|
1926
|
-
msg = `Neue Geräte Updates vorhanden: \n`;
|
|
1927
|
-
|
|
1928
|
-
this.log.info(msg + deviceList);
|
|
1929
|
-
await this.setStateAsync('lastNotification', msg + deviceList, true);
|
|
1930
|
-
await this.sendNotification(msg + deviceList);
|
|
1931
|
-
} catch (error) {
|
|
1932
|
-
this.errorReporting('[sendDeviceUpdatesNotification]', error);
|
|
1933
|
-
}
|
|
1934
|
-
this.log.debug(`Finished the function: ${this.sendDeviceUpdatesNotification.name}`);
|
|
1935
|
-
}
|
|
1936
|
-
|
|
1937
|
-
/**
|
|
1938
|
-
* send shedule message with offline devices
|
|
1939
|
-
*/
|
|
1940
|
-
async sendUpgradeNotificationsShedule() {
|
|
1941
|
-
const time = this.config.checkSendUpgradeTime.split(':');
|
|
1942
|
-
|
|
1943
|
-
const checkDays = []; // list of selected days
|
|
1944
|
-
|
|
1945
|
-
// push the selected days in list
|
|
1946
|
-
if (this.config.checkUpgradeMonday) checkDays.push(1);
|
|
1947
|
-
if (this.config.checkUpgradeTuesday) checkDays.push(2);
|
|
1948
|
-
if (this.config.checkUpgradeWednesday) checkDays.push(3);
|
|
1949
|
-
if (this.config.checkUpgradeThursday) checkDays.push(4);
|
|
1950
|
-
if (this.config.checkUpgradeFriday) checkDays.push(5);
|
|
1951
|
-
if (this.config.checkUpgradeSaturday) checkDays.push(6);
|
|
1952
|
-
if (this.config.checkUpgradeSunday) checkDays.push(0);
|
|
1953
|
-
|
|
1954
|
-
if (checkDays.length >= 1) {
|
|
1955
|
-
// check if an day is selected
|
|
1956
|
-
this.log.debug(`Number of selected days for daily Upgrade message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
1957
|
-
} else {
|
|
1958
|
-
this.log.warn(`No days selected for daily Upgrade message. Please check the instance configuration!`);
|
|
1959
|
-
return; // cancel function if no day is selected
|
|
1960
|
-
}
|
|
2660
|
+
this.log.debug(`Number of selected days for daily updatable devices message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
1961
2661
|
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
try {
|
|
1966
|
-
let deviceList = '';
|
|
2662
|
+
cron = '3 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2663
|
+
schedule.scheduleJob(cron, () => {
|
|
2664
|
+
list = '';
|
|
1967
2665
|
|
|
1968
2666
|
for (const id of this.upgradableDevicesRaw) {
|
|
1969
|
-
if (
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
}
|
|
2667
|
+
if (this.blacklistNotify.includes(id.Path)) continue;
|
|
2668
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2669
|
+
list = `${list}\n${id.Device}`;
|
|
2670
|
+
} else {
|
|
2671
|
+
list = `${list}\n${id.Adapter}: ${id.Device}`;
|
|
1975
2672
|
}
|
|
1976
2673
|
}
|
|
1977
|
-
if (
|
|
1978
|
-
|
|
1979
|
-
|
|
2674
|
+
if (list.length === 0) return;
|
|
2675
|
+
message = `Tägliche Meldung über verfügbare Geräte Updates: ${list}`;
|
|
2676
|
+
setMessage(message);
|
|
2677
|
+
});
|
|
2678
|
+
break;
|
|
2679
|
+
case 'updateAdapter':
|
|
2680
|
+
// push the selected days in list
|
|
2681
|
+
if (this.config.checkAdapterUpdateMonday) checkDays.push(1);
|
|
2682
|
+
if (this.config.checkAdapterUpdateTuesday) checkDays.push(2);
|
|
2683
|
+
if (this.config.checkAdapterUpdateWednesday) checkDays.push(3);
|
|
2684
|
+
if (this.config.checkAdapterUpdateThursday) checkDays.push(4);
|
|
2685
|
+
if (this.config.checkAdapterUpdateFriday) checkDays.push(5);
|
|
2686
|
+
if (this.config.checkAdapterUpdateSaturday) checkDays.push(6);
|
|
2687
|
+
if (this.config.checkAdapterUpdateSunday) checkDays.push(0);
|
|
2688
|
+
|
|
2689
|
+
time = this.config.checkSendAdapterUpdateTime.split(':');
|
|
2690
|
+
|
|
2691
|
+
if (checkDays.length === 0) {
|
|
2692
|
+
this.log.warn(`No days selected for daily adapter update message. Please check the instance configuration!`);
|
|
2693
|
+
return; // cancel function if no day is selected
|
|
2694
|
+
}
|
|
2695
|
+
this.log.debug(`Number of selected days for daily adapter update message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2696
|
+
|
|
2697
|
+
cron = '4 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2698
|
+
schedule.scheduleJob(cron, () => {
|
|
2699
|
+
list = '';
|
|
1980
2700
|
|
|
1981
|
-
|
|
2701
|
+
for (const id of this.listAdapterUpdates) {
|
|
2702
|
+
list = `${list}\n${id.Adapter}: v${id['Available Version']}`;
|
|
1982
2703
|
}
|
|
1983
|
-
|
|
1984
|
-
|
|
2704
|
+
if (list.length === 0) return;
|
|
2705
|
+
message = `Tägliche Meldung über verfügbare Adapter Updates: ${list}`;
|
|
2706
|
+
setMessage(message);
|
|
2707
|
+
});
|
|
2708
|
+
break;
|
|
2709
|
+
case 'errorInstance':
|
|
2710
|
+
// push the selected days in list
|
|
2711
|
+
if (this.config.checkFailedInstancesMonday) checkDays.push(1);
|
|
2712
|
+
if (this.config.checkFailedInstancesTuesday) checkDays.push(2);
|
|
2713
|
+
if (this.config.checkFailedInstancesWednesday) checkDays.push(3);
|
|
2714
|
+
if (this.config.checkFailedInstancesThursday) checkDays.push(4);
|
|
2715
|
+
if (this.config.checkFailedInstancesFriday) checkDays.push(5);
|
|
2716
|
+
if (this.config.checkFailedInstancesSaturday) checkDays.push(6);
|
|
2717
|
+
if (this.config.checkFailedInstancesSunday) checkDays.push(0);
|
|
2718
|
+
|
|
2719
|
+
time = this.config.checkSendInstanceFailedTime.split(':');
|
|
2720
|
+
|
|
2721
|
+
if (checkDays.length === 0) {
|
|
2722
|
+
this.log.warn(`No days selected for daily instance error message. Please check the instance configuration!`);
|
|
2723
|
+
return; // cancel function if no day is selected
|
|
1985
2724
|
}
|
|
1986
|
-
|
|
2725
|
+
this.log.debug(`Number of selected days for daily instance error message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2726
|
+
cron = '5 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2727
|
+
schedule.scheduleJob(cron, () => {
|
|
2728
|
+
list = '';
|
|
2729
|
+
|
|
2730
|
+
for (const id of this.listErrorInstanceRaw) {
|
|
2731
|
+
if (this.blacklistInstancesNotify.includes(id.instanceAlivePath)) continue;
|
|
2732
|
+
list = `${list}\n${id.Instance}: ${id.Status}`;
|
|
2733
|
+
}
|
|
2734
|
+
if (list.length === 0) return;
|
|
2735
|
+
message = `Tägliche Meldung über fehlerhafte Instanzen: ${list}`;
|
|
2736
|
+
setMessage(message);
|
|
2737
|
+
});
|
|
2738
|
+
break;
|
|
1987
2739
|
}
|
|
1988
|
-
}
|
|
2740
|
+
}
|
|
1989
2741
|
|
|
1990
2742
|
/*=============================================
|
|
1991
2743
|
= functions to create html lists =
|
|
1992
2744
|
=============================================*/
|
|
1993
|
-
|
|
1994
2745
|
/**
|
|
2746
|
+
* @param {string} type - type of list
|
|
1995
2747
|
* @param {object} devices - Device
|
|
1996
2748
|
* @param {number} deviceCount - Counted devices
|
|
2749
|
+
* @param {object} isLowBatteryList - list Low Battery Devices
|
|
1997
2750
|
*/
|
|
1998
|
-
async
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
html += `<tr>
|
|
2020
|
-
<td><font>${device.Device}</font></td>
|
|
2021
|
-
<td align=center><font>${device.Adapter}</font></td>
|
|
2022
|
-
<td align=right><font>${device['Signal strength']}</font></td>
|
|
2751
|
+
async createListHTML(type, devices, deviceCount, isLowBatteryList) {
|
|
2752
|
+
let html;
|
|
2753
|
+
switch (type) {
|
|
2754
|
+
case 'linkQualityList':
|
|
2755
|
+
devices = devices.sort((a, b) => {
|
|
2756
|
+
a = a.Device || '';
|
|
2757
|
+
b = b.Device || '';
|
|
2758
|
+
return a.localeCompare(b);
|
|
2759
|
+
});
|
|
2760
|
+
html = `<center>
|
|
2761
|
+
<b>Link Quality Devices:<font> ${deviceCount}</b><small></small></font>
|
|
2762
|
+
<p></p>
|
|
2763
|
+
</center>
|
|
2764
|
+
<table width=100%>
|
|
2765
|
+
<tr>
|
|
2766
|
+
<th align=left>Device</th>
|
|
2767
|
+
<th align=center width=120>Adapter</th>
|
|
2768
|
+
<th align=right>Link Quality</th>
|
|
2769
|
+
</tr>
|
|
2770
|
+
<tr>
|
|
2771
|
+
<td colspan="5"><hr></td>
|
|
2023
2772
|
</tr>`;
|
|
2024
|
-
}
|
|
2025
2773
|
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2774
|
+
for (const device of devices) {
|
|
2775
|
+
html += `<tr>
|
|
2776
|
+
<td><font>${device.Device}</font></td>
|
|
2777
|
+
<td align=center><font>${device.Adapter}</font></td>
|
|
2778
|
+
<td align=right><font>${device['Signal strength']}</font></td>
|
|
2779
|
+
</tr>`;
|
|
2780
|
+
}
|
|
2029
2781
|
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
<td colspan="5"><hr></td>
|
|
2052
|
-
</tr>`;
|
|
2053
|
-
|
|
2054
|
-
for (const device of devices) {
|
|
2055
|
-
html += `<tr>
|
|
2056
|
-
<td><font>${device.Device}</font></td>
|
|
2057
|
-
<td align=center><font>${device.Adapter}</font></td>
|
|
2058
|
-
<td align=center><font color=orange>${device['Last contact']}</font></td>
|
|
2782
|
+
html += '</table>';
|
|
2783
|
+
break;
|
|
2784
|
+
|
|
2785
|
+
case 'offlineList':
|
|
2786
|
+
devices = devices.sort((a, b) => {
|
|
2787
|
+
a = a.Device || '';
|
|
2788
|
+
b = b.Device || '';
|
|
2789
|
+
return a.localeCompare(b);
|
|
2790
|
+
});
|
|
2791
|
+
html = `<center>
|
|
2792
|
+
<b>Offline Devices: <font color=${deviceCount === 0 ? '#3bcf0e' : 'orange'}>${deviceCount}</b><small></small></font>
|
|
2793
|
+
<p></p>
|
|
2794
|
+
</center>
|
|
2795
|
+
<table width=100%>
|
|
2796
|
+
<tr>
|
|
2797
|
+
<th align=left>Device</th>
|
|
2798
|
+
<th align=center width=120>Adapter</th>
|
|
2799
|
+
<th align=center>Letzter Kontakt</th>
|
|
2800
|
+
</tr>
|
|
2801
|
+
<tr>
|
|
2802
|
+
<td colspan="5"><hr></td>
|
|
2059
2803
|
</tr>`;
|
|
2060
|
-
}
|
|
2061
2804
|
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2805
|
+
for (const device of devices) {
|
|
2806
|
+
html += `<tr>
|
|
2807
|
+
<td><font>${device.Device}</font></td>
|
|
2808
|
+
<td align=center><font>${device.Adapter}</font></td>
|
|
2809
|
+
<td align=center><font color=orange>${device['Last contact']}</font></td>
|
|
2810
|
+
</tr>`;
|
|
2811
|
+
}
|
|
2065
2812
|
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
* @param {object} [deviceCount] - Counted devices
|
|
2069
|
-
* @param {object} [isLowBatteryList] - list Low Battery Devices
|
|
2070
|
-
*/
|
|
2071
|
-
async createBatteryListHTML(devices, deviceCount, isLowBatteryList) {
|
|
2072
|
-
devices = devices.sort((a, b) => {
|
|
2073
|
-
a = a.Device || '';
|
|
2074
|
-
b = b.Device || '';
|
|
2075
|
-
return a.localeCompare(b);
|
|
2076
|
-
});
|
|
2077
|
-
let html = `<center>
|
|
2078
|
-
<b>${isLowBatteryList === true ? 'Schwache ' : ''}Batterie Devices: <font color=${isLowBatteryList === true ? (deviceCount > 0 ? 'orange' : '#3bcf0e') : ''}>${deviceCount}</b></font>
|
|
2079
|
-
<p></p>
|
|
2080
|
-
</center>
|
|
2081
|
-
<table width=100%>
|
|
2082
|
-
<tr>
|
|
2083
|
-
<th align=left>Device</th>
|
|
2084
|
-
<th align=center width=120>Adapter</th>
|
|
2085
|
-
<th align=${isLowBatteryList ? 'center' : 'right'}>Batterie</th>
|
|
2086
|
-
</tr>
|
|
2087
|
-
<tr>
|
|
2088
|
-
<td colspan="5"><hr></td>
|
|
2089
|
-
</tr>`;
|
|
2090
|
-
for (const device of devices) {
|
|
2091
|
-
html += `<tr>
|
|
2092
|
-
<td><font>${device.Device}</font></td>
|
|
2093
|
-
<td align=center><font>${device.Adapter}</font></td>`;
|
|
2094
|
-
|
|
2095
|
-
if (isLowBatteryList) {
|
|
2096
|
-
html += `<td align=center><font color=orange>${device.Battery}</font></td>`;
|
|
2097
|
-
} else {
|
|
2098
|
-
html += `<td align=right><font color=#3bcf0e>${device.Battery}</font></td>`;
|
|
2099
|
-
}
|
|
2100
|
-
html += `</tr>`;
|
|
2101
|
-
}
|
|
2813
|
+
html += '</table>';
|
|
2814
|
+
break;
|
|
2102
2815
|
|
|
2103
|
-
|
|
2816
|
+
case 'batteryList':
|
|
2817
|
+
devices = devices.sort((a, b) => {
|
|
2818
|
+
a = a.Device || '';
|
|
2819
|
+
b = b.Device || '';
|
|
2820
|
+
return a.localeCompare(b);
|
|
2821
|
+
});
|
|
2822
|
+
html = `<center>
|
|
2823
|
+
<b>${isLowBatteryList === true ? 'Schwache ' : ''}Batterie Devices: <font color=${isLowBatteryList === true ? (deviceCount > 0 ? 'orange' : '#3bcf0e') : ''}>${deviceCount}</b></font>
|
|
2824
|
+
<p></p>
|
|
2825
|
+
</center>
|
|
2826
|
+
<table width=100%>
|
|
2827
|
+
<tr>
|
|
2828
|
+
<th align=left>Device</th>
|
|
2829
|
+
<th align=center width=120>Adapter</th>
|
|
2830
|
+
<th align=${isLowBatteryList ? 'center' : 'right'}>Batterie</th>
|
|
2831
|
+
</tr>
|
|
2832
|
+
<tr>
|
|
2833
|
+
<td colspan="5"><hr></td>
|
|
2834
|
+
</tr>`;
|
|
2835
|
+
for (const device of devices) {
|
|
2836
|
+
html += `<tr>
|
|
2837
|
+
<td><font>${device.Device}</font></td>
|
|
2838
|
+
<td align=center><font>${device.Adapter}</font></td>`;
|
|
2839
|
+
|
|
2840
|
+
if (isLowBatteryList) {
|
|
2841
|
+
html += `<td align=center><font color=orange>${device.Battery}</font></td>`;
|
|
2842
|
+
} else {
|
|
2843
|
+
html += `<td align=right><font color=#3bcf0e>${device.Battery}</font></td>`;
|
|
2844
|
+
}
|
|
2845
|
+
html += `</tr>`;
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2848
|
+
html += '</table>';
|
|
2849
|
+
break;
|
|
2850
|
+
}
|
|
2104
2851
|
return html;
|
|
2105
2852
|
}
|
|
2106
2853
|
|
|
@@ -2112,7 +2859,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2112
2859
|
* @param {object} adptName - Adaptername of devices
|
|
2113
2860
|
*/
|
|
2114
2861
|
async createDPsForEachAdapter(adptName) {
|
|
2115
|
-
await this.setObjectNotExistsAsync(
|
|
2862
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}`, {
|
|
2116
2863
|
type: 'channel',
|
|
2117
2864
|
common: {
|
|
2118
2865
|
name: adptName,
|
|
@@ -2120,7 +2867,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2120
2867
|
native: {},
|
|
2121
2868
|
});
|
|
2122
2869
|
|
|
2123
|
-
await this.setObjectNotExistsAsync(
|
|
2870
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.offlineCount`, {
|
|
2124
2871
|
type: 'state',
|
|
2125
2872
|
common: {
|
|
2126
2873
|
name: {
|
|
@@ -2143,7 +2890,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2143
2890
|
native: {},
|
|
2144
2891
|
});
|
|
2145
2892
|
|
|
2146
|
-
await this.setObjectNotExistsAsync(
|
|
2893
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.offlineList`, {
|
|
2147
2894
|
type: 'state',
|
|
2148
2895
|
common: {
|
|
2149
2896
|
name: {
|
|
@@ -2166,7 +2913,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2166
2913
|
native: {},
|
|
2167
2914
|
});
|
|
2168
2915
|
|
|
2169
|
-
await this.setObjectNotExistsAsync(
|
|
2916
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.oneDeviceOffline`, {
|
|
2170
2917
|
type: 'state',
|
|
2171
2918
|
common: {
|
|
2172
2919
|
name: {
|
|
@@ -2191,7 +2938,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2191
2938
|
native: {},
|
|
2192
2939
|
});
|
|
2193
2940
|
|
|
2194
|
-
await this.setObjectNotExistsAsync(
|
|
2941
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.listAll`, {
|
|
2195
2942
|
type: 'state',
|
|
2196
2943
|
common: {
|
|
2197
2944
|
name: {
|
|
@@ -2214,7 +2961,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2214
2961
|
native: {},
|
|
2215
2962
|
});
|
|
2216
2963
|
|
|
2217
|
-
await this.setObjectNotExistsAsync(
|
|
2964
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.linkQualityList`, {
|
|
2218
2965
|
type: 'state',
|
|
2219
2966
|
common: {
|
|
2220
2967
|
name: {
|
|
@@ -2237,7 +2984,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2237
2984
|
native: {},
|
|
2238
2985
|
});
|
|
2239
2986
|
|
|
2240
|
-
await this.setObjectNotExistsAsync(
|
|
2987
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.countAll`, {
|
|
2241
2988
|
type: 'state',
|
|
2242
2989
|
common: {
|
|
2243
2990
|
name: {
|
|
@@ -2260,7 +3007,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2260
3007
|
native: {},
|
|
2261
3008
|
});
|
|
2262
3009
|
|
|
2263
|
-
await this.setObjectNotExistsAsync(
|
|
3010
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.batteryList`, {
|
|
2264
3011
|
type: 'state',
|
|
2265
3012
|
common: {
|
|
2266
3013
|
name: {
|
|
@@ -2283,7 +3030,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2283
3030
|
native: {},
|
|
2284
3031
|
});
|
|
2285
3032
|
|
|
2286
|
-
await this.setObjectNotExistsAsync(
|
|
3033
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.lowBatteryList`, {
|
|
2287
3034
|
type: 'state',
|
|
2288
3035
|
common: {
|
|
2289
3036
|
name: {
|
|
@@ -2306,7 +3053,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2306
3053
|
native: {},
|
|
2307
3054
|
});
|
|
2308
3055
|
|
|
2309
|
-
await this.setObjectNotExistsAsync(
|
|
3056
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.lowBatteryCount`, {
|
|
2310
3057
|
type: 'state',
|
|
2311
3058
|
common: {
|
|
2312
3059
|
name: {
|
|
@@ -2329,7 +3076,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2329
3076
|
native: {},
|
|
2330
3077
|
});
|
|
2331
3078
|
|
|
2332
|
-
await this.setObjectNotExistsAsync(
|
|
3079
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.oneDeviceLowBat`, {
|
|
2333
3080
|
type: 'state',
|
|
2334
3081
|
common: {
|
|
2335
3082
|
name: {
|
|
@@ -2354,7 +3101,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2354
3101
|
native: {},
|
|
2355
3102
|
});
|
|
2356
3103
|
|
|
2357
|
-
await this.setObjectNotExistsAsync(
|
|
3104
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.batteryCount`, {
|
|
2358
3105
|
type: 'state',
|
|
2359
3106
|
common: {
|
|
2360
3107
|
name: {
|
|
@@ -2377,7 +3124,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2377
3124
|
native: {},
|
|
2378
3125
|
});
|
|
2379
3126
|
|
|
2380
|
-
await this.setObjectNotExistsAsync(
|
|
3127
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.upgradableCount`, {
|
|
2381
3128
|
type: 'state',
|
|
2382
3129
|
common: {
|
|
2383
3130
|
name: {
|
|
@@ -2401,7 +3148,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2401
3148
|
native: {},
|
|
2402
3149
|
});
|
|
2403
3150
|
|
|
2404
|
-
await this.setObjectNotExistsAsync(
|
|
3151
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.upgradableList`, {
|
|
2405
3152
|
type: 'state',
|
|
2406
3153
|
common: {
|
|
2407
3154
|
name: {
|
|
@@ -2425,7 +3172,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2425
3172
|
native: {},
|
|
2426
3173
|
});
|
|
2427
3174
|
|
|
2428
|
-
await this.setObjectNotExistsAsync(
|
|
3175
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.oneDeviceUpdatable`, {
|
|
2429
3176
|
type: 'state',
|
|
2430
3177
|
common: {
|
|
2431
3178
|
name: {
|
|
@@ -2452,6 +3199,29 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2452
3199
|
}
|
|
2453
3200
|
|
|
2454
3201
|
/**
|
|
3202
|
+
* delete datapoints for each adapter
|
|
3203
|
+
* @param {object} adptName - Adaptername of devices
|
|
3204
|
+
*/
|
|
3205
|
+
async deleteDPsForEachAdapter(adptName) {
|
|
3206
|
+
await this.delObjectAsync(`devices.${adptName}`);
|
|
3207
|
+
await this.delObjectAsync(`devices.${adptName}.offlineCount`);
|
|
3208
|
+
await this.delObjectAsync(`devices.${adptName}.offlineList`);
|
|
3209
|
+
await this.delObjectAsync(`devices.${adptName}.oneDeviceOffline`);
|
|
3210
|
+
await this.delObjectAsync(`devices.${adptName}.listAll`);
|
|
3211
|
+
await this.delObjectAsync(`devices.${adptName}.linkQualityList`);
|
|
3212
|
+
await this.delObjectAsync(`devices.${adptName}.countAll`);
|
|
3213
|
+
await this.delObjectAsync(`devices.${adptName}.batteryList`);
|
|
3214
|
+
await this.delObjectAsync(`devices.${adptName}.lowBatteryList`);
|
|
3215
|
+
await this.delObjectAsync(`devices.${adptName}.lowBatteryCount`);
|
|
3216
|
+
await this.delObjectAsync(`devices.${adptName}.oneDeviceLowBat`);
|
|
3217
|
+
await this.delObjectAsync(`devices.${adptName}.batteryCount`);
|
|
3218
|
+
await this.delObjectAsync(`devices.${adptName}.upgradableCount`);
|
|
3219
|
+
await this.delObjectAsync(`devices.${adptName}.upgradableList`);
|
|
3220
|
+
await this.delObjectAsync(`devices.${adptName}.oneDeviceUpdatable`);
|
|
3221
|
+
}
|
|
3222
|
+
|
|
3223
|
+
/**
|
|
3224
|
+
* create HTML list datapoints
|
|
2455
3225
|
* @param {object} [adptName] - Adaptername of devices
|
|
2456
3226
|
**/
|
|
2457
3227
|
async createHtmlListDatapoints(adptName) {
|
|
@@ -2463,7 +3233,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2463
3233
|
dpSubFolder = '';
|
|
2464
3234
|
}
|
|
2465
3235
|
|
|
2466
|
-
await this.setObjectNotExistsAsync(
|
|
3236
|
+
await this.setObjectNotExistsAsync(`devices.${dpSubFolder}offlineListHTML`, {
|
|
2467
3237
|
type: 'state',
|
|
2468
3238
|
common: {
|
|
2469
3239
|
name: {
|
|
@@ -2486,7 +3256,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2486
3256
|
native: {},
|
|
2487
3257
|
});
|
|
2488
3258
|
|
|
2489
|
-
await this.setObjectNotExistsAsync(
|
|
3259
|
+
await this.setObjectNotExistsAsync(`devices.${dpSubFolder}linkQualityListHTML`, {
|
|
2490
3260
|
type: 'state',
|
|
2491
3261
|
common: {
|
|
2492
3262
|
name: {
|
|
@@ -2509,7 +3279,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2509
3279
|
native: {},
|
|
2510
3280
|
});
|
|
2511
3281
|
|
|
2512
|
-
await this.setObjectNotExistsAsync(
|
|
3282
|
+
await this.setObjectNotExistsAsync(`devices.${dpSubFolder}batteryListHTML`, {
|
|
2513
3283
|
type: 'state',
|
|
2514
3284
|
common: {
|
|
2515
3285
|
name: {
|
|
@@ -2532,7 +3302,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2532
3302
|
native: {},
|
|
2533
3303
|
});
|
|
2534
3304
|
|
|
2535
|
-
await this.setObjectNotExistsAsync(
|
|
3305
|
+
await this.setObjectNotExistsAsync(`devices.${dpSubFolder}lowBatteryListHTML`, {
|
|
2536
3306
|
type: 'state',
|
|
2537
3307
|
common: {
|
|
2538
3308
|
name: {
|
|
@@ -2556,6 +3326,25 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2556
3326
|
});
|
|
2557
3327
|
}
|
|
2558
3328
|
|
|
3329
|
+
/**
|
|
3330
|
+
* delete html datapoints
|
|
3331
|
+
* @param {object} [adptName] - Adaptername of devices
|
|
3332
|
+
**/
|
|
3333
|
+
async deleteHtmlListDatapoints(adptName) {
|
|
3334
|
+
// delete the datapoints in subfolders with the adaptername otherwise delete the dP's in the root folder
|
|
3335
|
+
let dpSubFolder;
|
|
3336
|
+
if (adptName) {
|
|
3337
|
+
dpSubFolder = `${adptName}.`;
|
|
3338
|
+
} else {
|
|
3339
|
+
dpSubFolder = '';
|
|
3340
|
+
}
|
|
3341
|
+
|
|
3342
|
+
await this.delObjectAsync(`devices.${dpSubFolder}offlineListHTML`);
|
|
3343
|
+
await this.delObjectAsync(`devices.${dpSubFolder}linkQualityListHTML`);
|
|
3344
|
+
await this.delObjectAsync(`devices.${dpSubFolder}batteryListHTML`);
|
|
3345
|
+
await this.delObjectAsync(`devices.${dpSubFolder}lowBatteryListHTML`);
|
|
3346
|
+
}
|
|
3347
|
+
|
|
2559
3348
|
/*=============================================
|
|
2560
3349
|
= help functions =
|
|
2561
3350
|
=============================================*/
|
|
@@ -2571,20 +3360,27 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2571
3360
|
/**
|
|
2572
3361
|
* @param {number} dpValue - get Time of this datapoint
|
|
2573
3362
|
*/
|
|
2574
|
-
|
|
3363
|
+
getTimestamp(dpValue) {
|
|
2575
3364
|
const time = new Date();
|
|
2576
3365
|
return (dpValue = Math.round((time.getTime() - dpValue) / 1000 / 60));
|
|
2577
3366
|
}
|
|
2578
3367
|
|
|
2579
3368
|
/**
|
|
2580
3369
|
* @param {string} dp - get Time of this datapoint
|
|
3370
|
+
* @param {number} ms - milliseconds
|
|
2581
3371
|
*/
|
|
2582
|
-
async getTimestampConnectionDP(dp) {
|
|
3372
|
+
async getTimestampConnectionDP(dp, ms) {
|
|
2583
3373
|
const time = new Date();
|
|
2584
3374
|
const dpValue = await this.getForeignStateAsync(dp);
|
|
2585
|
-
if (dpValue
|
|
2586
|
-
|
|
2587
|
-
|
|
3375
|
+
if (dpValue) {
|
|
3376
|
+
if (!dpValue.val) return false;
|
|
3377
|
+
|
|
3378
|
+
const dpLastStateChange = Math.round(time.getTime() - dpValue.lc); // calculate in ms
|
|
3379
|
+
if (dpLastStateChange >= ms) {
|
|
3380
|
+
return true;
|
|
3381
|
+
} else {
|
|
3382
|
+
return false;
|
|
3383
|
+
}
|
|
2588
3384
|
}
|
|
2589
3385
|
}
|
|
2590
3386
|
|
|
@@ -2609,13 +3405,39 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2609
3405
|
/**
|
|
2610
3406
|
* @param {object} data - object
|
|
2611
3407
|
*/
|
|
2612
|
-
|
|
3408
|
+
parseData(data) {
|
|
2613
3409
|
if (!data) return {};
|
|
2614
3410
|
if (typeof data === 'object') return data;
|
|
2615
3411
|
if (typeof data === 'string') return JSON.parse(data);
|
|
2616
3412
|
return {};
|
|
2617
3413
|
}
|
|
2618
3414
|
|
|
3415
|
+
/**
|
|
3416
|
+
* @param {number} time
|
|
3417
|
+
*/
|
|
3418
|
+
wait(time) {
|
|
3419
|
+
return new Promise(function (resolve) {
|
|
3420
|
+
setTimeout(resolve, time);
|
|
3421
|
+
});
|
|
3422
|
+
}
|
|
3423
|
+
|
|
3424
|
+
/**
|
|
3425
|
+
* Get previous run of cron job schedule
|
|
3426
|
+
* Requires cron-parser!
|
|
3427
|
+
* Inspired by https://stackoverflow.com/questions/68134104/
|
|
3428
|
+
* @param {string} lastCronRun
|
|
3429
|
+
*/
|
|
3430
|
+
getPreviousCronRun(lastCronRun) {
|
|
3431
|
+
try {
|
|
3432
|
+
const interval = cronParser.parseExpression(lastCronRun);
|
|
3433
|
+
const previous = interval.prev();
|
|
3434
|
+
return Math.floor(Date.now() - previous.getTime()); // in ms
|
|
3435
|
+
} catch (error) {
|
|
3436
|
+
this.log.warn(error);
|
|
3437
|
+
return;
|
|
3438
|
+
}
|
|
3439
|
+
}
|
|
3440
|
+
|
|
2619
3441
|
/**
|
|
2620
3442
|
* @param {string} codePart - Message Prefix
|
|
2621
3443
|
* @param {object} error - Sentry message
|