iobroker.device-watcher 2.0.0 → 2.0.2
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 +135 -101
- package/admin/i18n/de/translations.json +7 -10
- package/admin/i18n/en/translations.json +3 -2
- package/admin/i18n/es/translations.json +6 -9
- package/admin/i18n/fr/translations.json +6 -9
- package/admin/i18n/it/translations.json +6 -9
- package/admin/i18n/nl/translations.json +6 -9
- package/admin/i18n/pl/translations.json +7 -10
- package/admin/i18n/pt/translations.json +9 -12
- package/admin/i18n/ru/translations.json +6 -9
- package/admin/i18n/uk/translations.json +80 -0
- package/admin/i18n/zh-cn/translations.json +7 -10
- package/admin/jsonConfig.json +1301 -1304
- package/io-package.json +65 -57
- package/lib/arrApart.js +257 -220
- package/main.js +818 -708
- package/package.json +4 -1
package/main.js
CHANGED
|
@@ -16,7 +16,6 @@ const enableSendSentry = true;
|
|
|
16
16
|
let isUnloaded = false;
|
|
17
17
|
|
|
18
18
|
class DeviceWatcher extends utils.Adapter {
|
|
19
|
-
|
|
20
19
|
constructor(options) {
|
|
21
20
|
super({
|
|
22
21
|
...options,
|
|
@@ -30,12 +29,21 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
30
29
|
this.batteryPowered = [];
|
|
31
30
|
this.batteryLowPowered = [];
|
|
32
31
|
this.listAllDevices = [];
|
|
33
|
-
this.listAllDevicesRaw = [];
|
|
34
32
|
this.blacklistLists = [];
|
|
35
33
|
this.blacklistNotify = [];
|
|
36
34
|
this.arrDev = [];
|
|
37
35
|
this.adapterSelected = [];
|
|
38
36
|
|
|
37
|
+
// raw arrays
|
|
38
|
+
this.listAllDevicesRaw = [];
|
|
39
|
+
this.batteryLowPoweredRaw = [];
|
|
40
|
+
this.offlineDevicesRaw = [];
|
|
41
|
+
|
|
42
|
+
// raw counts
|
|
43
|
+
this.offlineDevicesCountRaw = 0;
|
|
44
|
+
this.offlineDevicesCountRawOld = 0;
|
|
45
|
+
this.lowBatteryPoweredCountRaw = 0;
|
|
46
|
+
|
|
39
47
|
// counts
|
|
40
48
|
this.offlineDevicesCount = 0;
|
|
41
49
|
this.deviceCounter = 0;
|
|
@@ -51,9 +59,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
51
59
|
// this.on('objectChange', this.onObjectChange.bind(this));
|
|
52
60
|
this.on('message', this.onMessage.bind(this));
|
|
53
61
|
this.on('unload', this.onUnload.bind(this));
|
|
54
|
-
|
|
55
62
|
}
|
|
56
63
|
|
|
64
|
+
/**
|
|
65
|
+
* onReady
|
|
66
|
+
*/
|
|
57
67
|
async onReady() {
|
|
58
68
|
this.log.debug(`Adapter ${adapterName} was started`);
|
|
59
69
|
|
|
@@ -71,7 +81,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
71
81
|
fritzdect: this.config.fritzdectDevices,
|
|
72
82
|
ham: this.config.hamDevices,
|
|
73
83
|
harmony: this.config.harmonyDevices,
|
|
74
|
-
hmiP
|
|
84
|
+
hmiP: this.config.hmiPDevices,
|
|
75
85
|
hmrpc: this.config.hmrpcDevices,
|
|
76
86
|
hs100: this.config.hs100Devices,
|
|
77
87
|
hue: this.config.hueDevices,
|
|
@@ -111,7 +121,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
111
121
|
fritzdect: this.config.fritzdectMaxMinutes,
|
|
112
122
|
ham: this.config.hamMaxMinutes,
|
|
113
123
|
harmony: this.config.harmonyMaxMinutes,
|
|
114
|
-
hmiP
|
|
124
|
+
hmiP: this.config.hmiPMaxMinutes,
|
|
115
125
|
hmrpc: this.config.hmrpcMaxMinutes,
|
|
116
126
|
hs100: this.config.hs100MaxMinutes,
|
|
117
127
|
hue: this.config.hueMaxMinutes,
|
|
@@ -158,7 +168,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
158
168
|
// show list in debug log
|
|
159
169
|
this.log.debug(JSON.stringify(this.arrDev));
|
|
160
170
|
|
|
161
|
-
this.log.info(`Number of selected adapters: ${this.adapterSelected.length}. Loading data from: ${
|
|
171
|
+
this.log.info(`Number of selected adapters: ${this.adapterSelected.length}. Loading data from: ${this.adapterSelected.join(', ')} ...`);
|
|
162
172
|
} else {
|
|
163
173
|
this.log.warn(`No adapter selected. Please check the instance configuration!`);
|
|
164
174
|
return; // cancel run if no adapter is selected
|
|
@@ -175,8 +185,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
175
185
|
try {
|
|
176
186
|
for (const [id] of Object.entries(arrApart)) {
|
|
177
187
|
if (!isUnloaded) {
|
|
178
|
-
if (
|
|
179
|
-
|
|
188
|
+
if (this.supAdapter !== undefined && this.supAdapter[id]) {
|
|
180
189
|
if (this.config.createOwnFolder) {
|
|
181
190
|
await this.createDPsForEachAdapter(id);
|
|
182
191
|
if (this.config.createHtmlList) await this.createHtmlListDatapoints(id);
|
|
@@ -202,7 +211,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
202
211
|
|
|
203
212
|
// send overview of offline devices
|
|
204
213
|
if (this.config.checkSendOfflineMsgDaily) await this.sendOfflineNotificationsShedule();
|
|
205
|
-
|
|
206
214
|
} catch (error) {
|
|
207
215
|
this.errorReporting('[onReady]', error);
|
|
208
216
|
this.terminate ? this.terminate(15) : process.exit(15);
|
|
@@ -210,10 +218,10 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
210
218
|
} // <-- onReady end
|
|
211
219
|
|
|
212
220
|
/**
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
221
|
+
* Is called if a subscribed state changes
|
|
222
|
+
* @param {string} id
|
|
223
|
+
* @param {ioBroker.State | null | undefined} state
|
|
224
|
+
*/
|
|
217
225
|
onStateChange(id, state) {
|
|
218
226
|
if (state) {
|
|
219
227
|
// The state was changed
|
|
@@ -225,8 +233,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
225
233
|
}
|
|
226
234
|
|
|
227
235
|
/**
|
|
228
|
-
|
|
229
|
-
|
|
236
|
+
* @param {ioBroker.Message} obj
|
|
237
|
+
*/
|
|
230
238
|
onMessage(obj) {
|
|
231
239
|
const devices = [];
|
|
232
240
|
let myCount = 0;
|
|
@@ -234,28 +242,33 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
234
242
|
|
|
235
243
|
switch (obj.command) {
|
|
236
244
|
case 'devicesList':
|
|
237
|
-
if(obj.message){
|
|
238
|
-
try{
|
|
245
|
+
if (obj.message) {
|
|
246
|
+
try {
|
|
239
247
|
result = this.listAllDevicesRaw;
|
|
240
|
-
for(const element in result){
|
|
248
|
+
for (const element in result) {
|
|
241
249
|
const label = 'Device: ' + result[element].Device + ' - Adapter: ' + result[element].Adapter;
|
|
242
|
-
const myValueObject = {
|
|
243
|
-
|
|
244
|
-
|
|
250
|
+
const myValueObject = {
|
|
251
|
+
deviceName: result[element].Device,
|
|
252
|
+
adapter: result[element].Adapter,
|
|
253
|
+
path: result[element].Path,
|
|
254
|
+
};
|
|
255
|
+
devices[myCount] = { label: label, value: JSON.stringify(myValueObject) };
|
|
256
|
+
myCount++;
|
|
245
257
|
}
|
|
246
258
|
this.sendTo(obj.from, obj.command, devices, obj.callback);
|
|
247
|
-
}
|
|
248
|
-
catch(error){
|
|
259
|
+
} catch (error) {
|
|
249
260
|
this.sendTo(obj.from, obj.command, obj.callback);
|
|
250
261
|
}
|
|
251
|
-
}
|
|
252
|
-
else{
|
|
262
|
+
} else {
|
|
253
263
|
this.sendTo(obj.from, obj.command, obj.callback);
|
|
254
264
|
}
|
|
255
265
|
break;
|
|
256
266
|
}
|
|
257
267
|
}
|
|
258
268
|
|
|
269
|
+
/**
|
|
270
|
+
* refresh data with interval
|
|
271
|
+
*/
|
|
259
272
|
async refreshData() {
|
|
260
273
|
const nextTimeout = this.config.updateinterval * 1000;
|
|
261
274
|
|
|
@@ -276,9 +289,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
276
289
|
} else {
|
|
277
290
|
return; // cancel run if unloaded was called.
|
|
278
291
|
}
|
|
279
|
-
|
|
280
292
|
} // <-- refreshData end
|
|
281
293
|
|
|
294
|
+
/**
|
|
295
|
+
* main function
|
|
296
|
+
*/
|
|
282
297
|
async main() {
|
|
283
298
|
this.log.debug(`Function started: ${this.main.name}`);
|
|
284
299
|
|
|
@@ -286,7 +301,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
286
301
|
try {
|
|
287
302
|
for (const [id] of Object.entries(arrApart)) {
|
|
288
303
|
if (!isUnloaded) {
|
|
289
|
-
if (
|
|
304
|
+
if (this.supAdapter !== undefined && this.supAdapter[id]) {
|
|
290
305
|
if (this.config.createOwnFolder) {
|
|
291
306
|
await this.createDataForEachAdapter(id);
|
|
292
307
|
this.log.debug(`Created and filled data for ${await this.capitalize(id)}`);
|
|
@@ -312,13 +327,12 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
312
327
|
this.log.debug(`Function finished: ${this.main.name}`);
|
|
313
328
|
} //<--End of main function
|
|
314
329
|
|
|
315
|
-
|
|
316
330
|
/**
|
|
317
|
-
* @param {string}
|
|
331
|
+
* @param {string} id - id which should be capitalize
|
|
318
332
|
*/
|
|
319
|
-
|
|
333
|
+
capitalize(id) {
|
|
320
334
|
//make the first letter uppercase
|
|
321
|
-
return
|
|
335
|
+
return id && id[0].toUpperCase() + id.slice(1);
|
|
322
336
|
}
|
|
323
337
|
|
|
324
338
|
/**
|
|
@@ -326,7 +340,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
326
340
|
*/
|
|
327
341
|
async getTimestamp(dpValue) {
|
|
328
342
|
const time = new Date();
|
|
329
|
-
return dpValue = Math.round((time.getTime() - dpValue) / 1000 / 60);
|
|
343
|
+
return (dpValue = Math.round((time.getTime() - dpValue) / 1000 / 60));
|
|
330
344
|
}
|
|
331
345
|
|
|
332
346
|
/**
|
|
@@ -347,6 +361,19 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
347
361
|
if (stateVal) return stateVal.val;
|
|
348
362
|
}
|
|
349
363
|
|
|
364
|
+
/**
|
|
365
|
+
* @param {object} data - object
|
|
366
|
+
*/
|
|
367
|
+
async parseData(data) {
|
|
368
|
+
if (!data) return {};
|
|
369
|
+
if (typeof data === 'object') return data;
|
|
370
|
+
if (typeof data === 'string') return JSON.parse(data);
|
|
371
|
+
return {};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* create blacklist
|
|
376
|
+
*/
|
|
350
377
|
async createBlacklist() {
|
|
351
378
|
this.log.debug(`Function started: ${this.createBlacklist.name}`);
|
|
352
379
|
|
|
@@ -354,14 +381,18 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
354
381
|
const myBlacklist = this.config.tableBlacklist;
|
|
355
382
|
|
|
356
383
|
for (const i in myBlacklist) {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
384
|
+
try {
|
|
385
|
+
const blacklistParse = await this.parseData(myBlacklist[i].devices);
|
|
386
|
+
// push devices in list to ignor device in lists
|
|
387
|
+
if (myBlacklist[i].checkIgnorLists) {
|
|
388
|
+
this.blacklistLists.push(blacklistParse.path);
|
|
389
|
+
}
|
|
390
|
+
// push devices in list to ignor device in notifications
|
|
391
|
+
if (myBlacklist[i].checkIgnorNotify) {
|
|
392
|
+
this.blacklistNotify.push(blacklistParse.path);
|
|
393
|
+
}
|
|
394
|
+
} catch (error) {
|
|
395
|
+
this.errorReporting('[createBlacklist]', error);
|
|
365
396
|
}
|
|
366
397
|
}
|
|
367
398
|
|
|
@@ -379,71 +410,87 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
379
410
|
* @param {object} i - each Device
|
|
380
411
|
*/
|
|
381
412
|
async getDeviceName(id, i) {
|
|
382
|
-
const currDeviceString = id.slice(0,
|
|
383
|
-
const shortCurrDeviceString = currDeviceString.slice(0,
|
|
384
|
-
const shortshortCurrDeviceString = shortCurrDeviceString.slice(0,
|
|
385
|
-
|
|
386
|
-
// Get device name
|
|
387
|
-
const deviceObject = await this.getForeignObjectAsync(currDeviceString);
|
|
388
|
-
const shortDeviceObject = await this.getForeignObjectAsync(shortCurrDeviceString);
|
|
389
|
-
const shortshortDeviceObject = await this.getForeignObjectAsync(shortshortCurrDeviceString);
|
|
390
|
-
let deviceName;
|
|
391
|
-
|
|
392
|
-
// Get ID with currDeviceString from datapoint
|
|
393
|
-
switch (this.arrDev[i].adapter) {
|
|
394
|
-
// Get ID for Switchbot and ESPHome Devices
|
|
395
|
-
case 'switchbotBle':
|
|
396
|
-
case 'esphome':
|
|
397
|
-
deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
|
|
398
|
-
break;
|
|
413
|
+
const currDeviceString = id.slice(0, id.lastIndexOf('.') + 1 - 1);
|
|
414
|
+
const shortCurrDeviceString = currDeviceString.slice(0, currDeviceString.lastIndexOf('.') + 1 - 1);
|
|
415
|
+
const shortshortCurrDeviceString = shortCurrDeviceString.slice(0, shortCurrDeviceString.lastIndexOf('.') + 1 - 1);
|
|
399
416
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
case 'tado':
|
|
425
|
-
deviceName = currDeviceString.slice(currDeviceString.lastIndexOf('.') + 1);
|
|
426
|
-
break;
|
|
427
|
-
|
|
428
|
-
//Get ID of foldername
|
|
429
|
-
case 'yeelight-2':
|
|
430
|
-
deviceName = shortCurrDeviceString.slice(shortCurrDeviceString.lastIndexOf('.') + 1);
|
|
431
|
-
break;
|
|
417
|
+
try {
|
|
418
|
+
// Get device name
|
|
419
|
+
const deviceObject = await this.getForeignObjectAsync(currDeviceString);
|
|
420
|
+
const shortDeviceObject = await this.getForeignObjectAsync(shortCurrDeviceString);
|
|
421
|
+
const shortshortDeviceObject = await this.getForeignObjectAsync(shortshortCurrDeviceString);
|
|
422
|
+
let deviceName;
|
|
423
|
+
|
|
424
|
+
// Get ID with currDeviceString from datapoint
|
|
425
|
+
switch (this.arrDev[i].adapterID) {
|
|
426
|
+
// Get ID for Switchbot and ESPHome Devices
|
|
427
|
+
case 'switchbotBle':
|
|
428
|
+
case 'esphome':
|
|
429
|
+
deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
|
|
430
|
+
break;
|
|
431
|
+
|
|
432
|
+
// Get ID with short currDeviceString from objectjson
|
|
433
|
+
case 'hueExt':
|
|
434
|
+
case 'hmrpc':
|
|
435
|
+
case 'nukiExt':
|
|
436
|
+
case 'wled':
|
|
437
|
+
if (shortDeviceObject && typeof shortDeviceObject === 'object') {
|
|
438
|
+
deviceName = shortDeviceObject.common.name;
|
|
439
|
+
}
|
|
440
|
+
break;
|
|
432
441
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
442
|
+
// Get ID with short short currDeviceString from objectjson (HMiP Devices)
|
|
443
|
+
case 'hmiP':
|
|
444
|
+
if (shortshortDeviceObject && typeof shortshortDeviceObject === 'object') {
|
|
445
|
+
deviceName = shortshortDeviceObject.common.name;
|
|
446
|
+
}
|
|
447
|
+
break;
|
|
448
|
+
|
|
449
|
+
// Get ID with short currDeviceString from datapoint
|
|
450
|
+
case 'mihomeVacuum':
|
|
451
|
+
case 'roomba':
|
|
452
|
+
deviceName = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].id);
|
|
453
|
+
break;
|
|
454
|
+
|
|
455
|
+
//Get ID of foldername
|
|
456
|
+
case 'tado':
|
|
457
|
+
deviceName = currDeviceString.slice(currDeviceString.lastIndexOf('.') + 1);
|
|
458
|
+
break;
|
|
459
|
+
|
|
460
|
+
//Get ID of foldername
|
|
461
|
+
case 'yeelight':
|
|
462
|
+
deviceName = shortCurrDeviceString.slice(shortCurrDeviceString.lastIndexOf('.') + 1);
|
|
463
|
+
break;
|
|
464
|
+
|
|
465
|
+
// Get ID with main selektor from objectjson
|
|
466
|
+
default:
|
|
467
|
+
if (deviceObject && typeof deviceObject === 'object') {
|
|
441
468
|
deviceName = deviceObject.common.name;
|
|
442
469
|
}
|
|
443
|
-
|
|
444
|
-
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
return deviceName;
|
|
473
|
+
} catch (error) {
|
|
474
|
+
this.errorReporting('[getDeviceName]', error);
|
|
445
475
|
}
|
|
446
|
-
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* get Last Contact
|
|
480
|
+
* @param {object} selector - Selector
|
|
481
|
+
*/
|
|
482
|
+
async getLastContact(selector) {
|
|
483
|
+
const lastContact = await this.getTimestamp(selector);
|
|
484
|
+
let lastContactString;
|
|
485
|
+
|
|
486
|
+
lastContactString = this.formatDate(new Date(selector), 'hh:mm') + ' Uhr';
|
|
487
|
+
if (Math.round(lastContact) > 100) {
|
|
488
|
+
lastContactString = Math.round(lastContact / 60) + ' Stunden';
|
|
489
|
+
}
|
|
490
|
+
if (Math.round(lastContact / 60) > 48) {
|
|
491
|
+
lastContactString = Math.round(lastContact / 60 / 24) + ' Tagen';
|
|
492
|
+
}
|
|
493
|
+
return lastContactString;
|
|
447
494
|
}
|
|
448
495
|
|
|
449
496
|
/**
|
|
@@ -455,59 +502,73 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
455
502
|
this.batteryLowPowered = [];
|
|
456
503
|
this.listAllDevices = [];
|
|
457
504
|
this.offlineDevices = [];
|
|
505
|
+
this.batteryLowPoweredRaw = [];
|
|
506
|
+
this.offlineDevicesRaw = [];
|
|
458
507
|
|
|
459
508
|
for (const device of this.listAllDevicesRaw) {
|
|
509
|
+
/*---------- fill raw lists ----------*/
|
|
510
|
+
// low bat list
|
|
511
|
+
if (device['LowBat'] && device['Status'] !== 'Offline') {
|
|
512
|
+
this.batteryLowPoweredRaw.push({
|
|
513
|
+
Path: device['Path'],
|
|
514
|
+
Device: device['Device'],
|
|
515
|
+
Adapter: device['Adapter'],
|
|
516
|
+
Battery: device['Battery'],
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
// offline raw list
|
|
520
|
+
if (device['Status'] === 'Offline') {
|
|
521
|
+
this.offlineDevicesRaw.push({
|
|
522
|
+
Path: device['Path'],
|
|
523
|
+
Device: device['Device'],
|
|
524
|
+
Adapter: device['Adapter'],
|
|
525
|
+
'Last contact': device['Last contact'],
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/*---------- fill user lists ----------*/
|
|
460
530
|
if (!this.blacklistLists.includes(device['Path'])) {
|
|
461
|
-
this.listAllDevices.push(
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
}
|
|
470
|
-
);
|
|
531
|
+
this.listAllDevices.push({
|
|
532
|
+
Device: device['Device'],
|
|
533
|
+
Adapter: device['Adapter'],
|
|
534
|
+
Battery: device['Battery'],
|
|
535
|
+
'Signal strength': device['Signal strength'],
|
|
536
|
+
'Last contact': device['Last contact'],
|
|
537
|
+
Status: device['Status'],
|
|
538
|
+
});
|
|
471
539
|
// LinkQuality lists
|
|
472
540
|
if (device['Signal strength'] != ' - ') {
|
|
473
|
-
this.linkQualityDevices.push(
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
}
|
|
479
|
-
);
|
|
541
|
+
this.linkQualityDevices.push({
|
|
542
|
+
Device: device['Device'],
|
|
543
|
+
Adapter: device['Adapter'],
|
|
544
|
+
'Signal strength': device['Signal strength'],
|
|
545
|
+
});
|
|
480
546
|
}
|
|
481
547
|
// Battery lists
|
|
482
|
-
if (device['
|
|
483
|
-
this.batteryPowered.push(
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
);
|
|
548
|
+
if (device['isBatteryDevice']) {
|
|
549
|
+
this.batteryPowered.push({
|
|
550
|
+
Device: device['Device'],
|
|
551
|
+
Adapter: device['Adapter'],
|
|
552
|
+
Battery: device['Battery'],
|
|
553
|
+
Status: device['Status'],
|
|
554
|
+
});
|
|
490
555
|
}
|
|
491
556
|
// Low Bat lists
|
|
492
|
-
if (device['LowBat']) {
|
|
493
|
-
this.batteryLowPowered.push(
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
}
|
|
499
|
-
);
|
|
557
|
+
if (device['LowBat'] && device['Status'] !== 'Offline') {
|
|
558
|
+
this.batteryLowPowered.push({
|
|
559
|
+
Device: device['Device'],
|
|
560
|
+
Adapter: device['Adapter'],
|
|
561
|
+
Battery: device['Battery'],
|
|
562
|
+
});
|
|
500
563
|
}
|
|
501
564
|
|
|
502
565
|
// Offline List
|
|
503
566
|
if (device['Status'] === 'Offline') {
|
|
504
|
-
this.offlineDevices.push(
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
}
|
|
510
|
-
);
|
|
567
|
+
this.offlineDevices.push({
|
|
568
|
+
Device: device['Device'],
|
|
569
|
+
Adapter: device['Adapter'],
|
|
570
|
+
'Last contact': device['Last contact'],
|
|
571
|
+
});
|
|
511
572
|
}
|
|
512
573
|
}
|
|
513
574
|
}
|
|
@@ -531,6 +592,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
531
592
|
|
|
532
593
|
// Count how many devices are exists
|
|
533
594
|
this.deviceCounter = this.listAllDevices.length;
|
|
595
|
+
|
|
596
|
+
// raws
|
|
597
|
+
|
|
598
|
+
// Count how many devcies are offline
|
|
599
|
+
this.offlineDevicesCountRaw = this.offlineDevicesRaw.length;
|
|
534
600
|
}
|
|
535
601
|
|
|
536
602
|
/**
|
|
@@ -538,39 +604,34 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
538
604
|
*/
|
|
539
605
|
async createData(i) {
|
|
540
606
|
const devices = await this.getForeignStatesAsync(this.arrDev[i].Selektor);
|
|
541
|
-
const
|
|
607
|
+
const adapterID = this.arrDev[i].adapterID;
|
|
542
608
|
|
|
543
|
-
/*---------- Start of
|
|
609
|
+
/*---------- Start of loop ----------*/
|
|
544
610
|
for (const [id] of Object.entries(devices)) {
|
|
545
611
|
if (!isUnloaded) {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
612
|
+
/*=============================================
|
|
613
|
+
= Get device name =
|
|
614
|
+
=============================================*/
|
|
549
615
|
const deviceName = await this.getDeviceName(id, i);
|
|
550
616
|
|
|
551
|
-
|
|
552
|
-
|
|
617
|
+
/*=============================================
|
|
618
|
+
= Get adapter name =
|
|
619
|
+
=============================================*/
|
|
620
|
+
const adapter = this.arrDev[i].adapter;
|
|
553
621
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
const
|
|
622
|
+
/*=============================================
|
|
623
|
+
= Get path to datapoints =
|
|
624
|
+
=============================================*/
|
|
625
|
+
const currDeviceString = id.slice(0, id.lastIndexOf('.') + 1 - 1);
|
|
626
|
+
const shortCurrDeviceString = currDeviceString.slice(0, currDeviceString.lastIndexOf('.') + 1 - 1);
|
|
558
627
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
/*for (const [value] of Object.entries(this.devices)) {
|
|
563
|
-
this.log.warn(`${value}`);
|
|
564
|
-
this.subscribeForeignStatesAsync(value);
|
|
565
|
-
}*/
|
|
566
|
-
//this.subscribeForeignStatesAsync(currDeviceString + this.arrDev[i].reach);
|
|
567
|
-
// <--- END TEST
|
|
568
|
-
|
|
569
|
-
// Get link quality
|
|
628
|
+
/*=============================================
|
|
629
|
+
= Get signal strength =
|
|
630
|
+
=============================================*/
|
|
570
631
|
let deviceQualityState;
|
|
571
632
|
let linkQuality;
|
|
572
633
|
|
|
573
|
-
switch (
|
|
634
|
+
switch (adapterID) {
|
|
574
635
|
case 'mihomeVacuum':
|
|
575
636
|
deviceQualityState = await this.getForeignStateAsync(shortCurrDeviceString + this.arrDev[i].rssiState);
|
|
576
637
|
break;
|
|
@@ -593,7 +654,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
593
654
|
if (this.config.trueState) {
|
|
594
655
|
linkQuality = deviceQualityState.val;
|
|
595
656
|
} else {
|
|
596
|
-
switch (
|
|
657
|
+
switch (adapterID) {
|
|
597
658
|
case 'roomba':
|
|
598
659
|
case 'sonoff':
|
|
599
660
|
linkQuality = deviceQualityState.val + '%'; // If quality state is already an percent value
|
|
@@ -609,8 +670,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
609
670
|
} else if (deviceQualityState.val < 0) {
|
|
610
671
|
linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
|
|
611
672
|
// If Quality State is an value between 0-255 (zigbee) calculate in percent:
|
|
612
|
-
} else if (
|
|
613
|
-
linkQuality = parseFloat((100 / 255 * deviceQualityState.val).toFixed(0)) + '%';
|
|
673
|
+
} else if (deviceQualityState.val >= 0) {
|
|
674
|
+
linkQuality = parseFloat(((100 / 255) * deviceQualityState.val).toFixed(0)) + '%';
|
|
614
675
|
}
|
|
615
676
|
break;
|
|
616
677
|
}
|
|
@@ -618,12 +679,12 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
618
679
|
break;
|
|
619
680
|
|
|
620
681
|
case 'string':
|
|
621
|
-
switch (
|
|
682
|
+
switch (adapterID) {
|
|
622
683
|
case 'netatmo':
|
|
623
684
|
// for Netatmo devices
|
|
624
685
|
linkQuality = deviceQualityState.val;
|
|
625
686
|
break;
|
|
626
|
-
case '
|
|
687
|
+
case 'nukiExt':
|
|
627
688
|
linkQuality = ' - ';
|
|
628
689
|
break;
|
|
629
690
|
}
|
|
@@ -633,207 +694,37 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
633
694
|
linkQuality = ' - ';
|
|
634
695
|
}
|
|
635
696
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
let lastDeviceUnreachStateChange;
|
|
640
|
-
|
|
641
|
-
const deviceMainSelector = await this.getForeignStateAsync(id);
|
|
642
|
-
const deviceStateSelector = await this.getForeignStateAsync(shortCurrDeviceString + this.arrDev[i].stateValue); // for hmrpc devices
|
|
643
|
-
const rssiPeerSelector = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rssiPeerState);
|
|
644
|
-
|
|
645
|
-
if (deviceMainSelector) {
|
|
646
|
-
try {
|
|
647
|
-
const lastContact = await this.getTimestamp(deviceMainSelector.ts);
|
|
648
|
-
const lastStateChange = await this.getTimestamp(deviceMainSelector.lc);
|
|
649
|
-
const deviceUnreachState = await this.getInitValue(currDeviceString + this.arrDev[i].reach);
|
|
650
|
-
const deviceUnreachSelector = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].reach);
|
|
651
|
-
if (deviceUnreachSelector) {lastDeviceUnreachStateChange = await this.getTimestamp(deviceUnreachSelector.lc);}
|
|
652
|
-
const shortDeviceUnreachState = await this.getForeignStateAsync(shortCurrDeviceString + this.arrDev[i].reach);
|
|
653
|
-
|
|
654
|
-
const getLastContact = async () => {
|
|
655
|
-
lastContactString = this.formatDate(new Date((deviceMainSelector.ts)), 'hh:mm') + ' Uhr';
|
|
656
|
-
if (Math.round(lastContact) > 100) {
|
|
657
|
-
lastContactString = Math.round(lastContact / 60) + ' Stunden';
|
|
658
|
-
}
|
|
659
|
-
if (Math.round(lastContact / 60) > 48) {
|
|
660
|
-
lastContactString = Math.round(lastContact / 60 / 24) + ' Tagen';
|
|
661
|
-
}
|
|
662
|
-
return lastContactString;
|
|
663
|
-
};
|
|
664
|
-
|
|
665
|
-
const getLastStateChange = async () => {
|
|
666
|
-
lastContactString = this.formatDate(new Date((deviceMainSelector.lc)), 'hh:mm') + ' Uhr';
|
|
667
|
-
if (Math.round(lastStateChange) > 100) {
|
|
668
|
-
lastContactString = Math.round(lastStateChange / 60) + ' Stunden';
|
|
669
|
-
}
|
|
670
|
-
if (Math.round(lastStateChange / 60) > 48) {
|
|
671
|
-
lastContactString = Math.round(lastStateChange / 60 / 24) + ' Tagen';
|
|
672
|
-
}
|
|
673
|
-
return lastContactString;
|
|
674
|
-
};
|
|
675
|
-
|
|
676
|
-
// If there is no contact since user sets minutes add device in offline list
|
|
677
|
-
// calculate to days after 48 hours
|
|
678
|
-
switch (this.arrDev[i].reach) {
|
|
679
|
-
case 'none':
|
|
680
|
-
await getLastContact();
|
|
681
|
-
break;
|
|
682
|
-
|
|
683
|
-
default:
|
|
684
|
-
//State changed
|
|
685
|
-
if (this.arrDev[i].adapter === 'hmrpc') {
|
|
686
|
-
if (linkQuality != ' - ') {
|
|
687
|
-
if (deviceUnreachState) {
|
|
688
|
-
await getLastStateChange();
|
|
689
|
-
} else {
|
|
690
|
-
await getLastContact();
|
|
691
|
-
}
|
|
692
|
-
} else {
|
|
693
|
-
if (deviceStateSelector) { // because old hm devices don't send rssi states
|
|
694
|
-
const lastContactOfState = await this.getTimestamp(deviceStateSelector.ts);
|
|
695
|
-
const getLastContactOfState = async () => {
|
|
696
|
-
lastContactString = this.formatDate(new Date((deviceStateSelector.ts)), 'hh:mm') + ' Uhr';
|
|
697
|
-
if (Math.round(lastContactOfState) > 100) {
|
|
698
|
-
lastContactString = Math.round(lastContactOfState / 60) + ' Stunden';
|
|
699
|
-
}
|
|
700
|
-
if (Math.round(lastContactOfState / 60) > 48) {
|
|
701
|
-
lastContactString = Math.round(lastContactOfState / 60 / 24) + ' Tagen';
|
|
702
|
-
}
|
|
703
|
-
return lastContactString;
|
|
704
|
-
};
|
|
705
|
-
await getLastContactOfState();
|
|
706
|
-
} else if (rssiPeerSelector) { // because old hm sensors don't send rssi/state values
|
|
707
|
-
const lastContactOfState = await this.getTimestamp(rssiPeerSelector.ts);
|
|
708
|
-
const getLastContactOfState = async () => {
|
|
709
|
-
lastContactString = this.formatDate(new Date((rssiPeerSelector.ts)), 'hh:mm') + ' Uhr';
|
|
710
|
-
if (Math.round(lastContactOfState) > 100) {
|
|
711
|
-
lastContactString = Math.round(lastContactOfState / 60) + ' Stunden';
|
|
712
|
-
}
|
|
713
|
-
if (Math.round(lastContactOfState / 60) > 48) {
|
|
714
|
-
lastContactString = Math.round(lastContactOfState / 60 / 24) + ' Tagen';
|
|
715
|
-
}
|
|
716
|
-
return lastContactString;
|
|
717
|
-
};
|
|
718
|
-
await getLastContactOfState();
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
} else {
|
|
723
|
-
if (!deviceUnreachState) {
|
|
724
|
-
await getLastStateChange();
|
|
725
|
-
} else {
|
|
726
|
-
await getLastContact();
|
|
727
|
-
}
|
|
728
|
-
break;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
const adapterID = this.arrDev[i].adapter;
|
|
733
|
-
|
|
734
|
-
switch (adapterID) {
|
|
735
|
-
case 'hmrpc':
|
|
736
|
-
case 'hmiP':
|
|
737
|
-
case 'maxcube':
|
|
738
|
-
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
739
|
-
if (deviceUnreachState) {
|
|
740
|
-
deviceState = 'Offline'; //set online state to offline
|
|
741
|
-
}
|
|
742
|
-
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
743
|
-
deviceState = 'Offline'; //set online state to offline
|
|
744
|
-
}
|
|
745
|
-
break;
|
|
746
|
-
case 'ping':
|
|
747
|
-
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
748
|
-
if (!deviceUnreachState) {
|
|
749
|
-
deviceState = 'Offline'; //set online state to offline
|
|
750
|
-
}
|
|
751
|
-
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID]) && (!deviceUnreachState)) {
|
|
752
|
-
deviceState = 'Offline'; //set online state to offline
|
|
753
|
-
}
|
|
754
|
-
break;
|
|
755
|
-
case 'unifi':
|
|
756
|
-
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
757
|
-
if (deviceUnreachState === 0) {
|
|
758
|
-
deviceState = 'Offline'; //set online state to offline
|
|
759
|
-
}
|
|
760
|
-
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
761
|
-
deviceState = 'Offline'; //set online state to offline
|
|
762
|
-
|
|
763
|
-
}
|
|
764
|
-
break;
|
|
765
|
-
case 'shelly':
|
|
766
|
-
case 'sonoff':
|
|
767
|
-
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
768
|
-
if (!deviceUnreachState) {
|
|
769
|
-
deviceState = 'Offline'; //set online state to offline
|
|
770
|
-
}
|
|
771
|
-
} else if ((!deviceUnreachState) && (typeof lastDeviceUnreachStateChange !== 'undefined') && (this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
772
|
-
deviceState = 'Offline'; //set online state to offline
|
|
773
|
-
}
|
|
774
|
-
break;
|
|
775
|
-
case 'mihomeVacuum':
|
|
776
|
-
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
777
|
-
if (!shortDeviceUnreachState) {
|
|
778
|
-
deviceState = 'Offline'; //set online state to offline
|
|
779
|
-
}
|
|
780
|
-
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
781
|
-
deviceState = 'Offline'; //set online state to offline
|
|
782
|
-
}
|
|
783
|
-
break;
|
|
784
|
-
case 'miHome':
|
|
785
|
-
if (this.arrDev[i].battery === 'none') {
|
|
786
|
-
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
787
|
-
if (!deviceUnreachState) {
|
|
788
|
-
deviceState = 'Offline'; //set online state to offline
|
|
789
|
-
}
|
|
790
|
-
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
791
|
-
deviceState = 'Offline'; //set online state to offline
|
|
792
|
-
}
|
|
793
|
-
} else {
|
|
794
|
-
if (this.config.mihomeMaxMinutes === -1) {
|
|
795
|
-
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
796
|
-
deviceState = 'Offline'; //set online state to offline
|
|
797
|
-
}
|
|
798
|
-
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
799
|
-
deviceState = 'Offline'; //set online state to offline
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
break;
|
|
803
|
-
default:
|
|
804
|
-
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
805
|
-
if (!deviceUnreachState) {
|
|
806
|
-
deviceState = 'Offline'; //set online state to offline
|
|
807
|
-
}
|
|
808
|
-
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
809
|
-
deviceState = 'Offline'; //set online state to offline
|
|
810
|
-
}
|
|
811
|
-
break;
|
|
812
|
-
}
|
|
813
|
-
} catch (error) {
|
|
814
|
-
this.errorReporting('[getLastContact]', error);
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
// Get battery states
|
|
697
|
+
/*=============================================
|
|
698
|
+
= Get battery data =
|
|
699
|
+
=============================================*/
|
|
819
700
|
let batteryHealth;
|
|
820
701
|
let lowBatIndicator;
|
|
702
|
+
let isBatteryDevice;
|
|
703
|
+
|
|
704
|
+
// Get battery states
|
|
705
|
+
const deviceBatteryState = await this.getInitValue(currDeviceString + this.arrDev[i].battery);
|
|
706
|
+
const shortDeviceBatteryState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery);
|
|
707
|
+
const shortDeviceBatteryState2 = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery2);
|
|
708
|
+
|
|
709
|
+
// Get low bat states
|
|
821
710
|
let deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat);
|
|
822
711
|
if (deviceLowBatState === undefined) {
|
|
823
712
|
deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat2);
|
|
824
713
|
}
|
|
825
714
|
|
|
826
|
-
if (
|
|
715
|
+
if (!deviceBatteryState && !shortDeviceBatteryState && !shortDeviceBatteryState2) {
|
|
827
716
|
if (deviceLowBatState !== undefined) {
|
|
828
717
|
switch (this.arrDev[i].isLowBat || this.arrDev[i].isLowBat2) {
|
|
829
718
|
case 'none':
|
|
830
719
|
batteryHealth = ' - ';
|
|
831
720
|
break;
|
|
832
721
|
default:
|
|
833
|
-
if (
|
|
722
|
+
if (deviceLowBatState === false || deviceLowBatState === 'NORMAL' || deviceLowBatState === 1) {
|
|
834
723
|
batteryHealth = 'ok';
|
|
724
|
+
isBatteryDevice = true;
|
|
835
725
|
} else {
|
|
836
726
|
batteryHealth = 'low';
|
|
727
|
+
isBatteryDevice = true;
|
|
837
728
|
}
|
|
838
729
|
break;
|
|
839
730
|
}
|
|
@@ -841,90 +732,267 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
841
732
|
batteryHealth = ' - ';
|
|
842
733
|
}
|
|
843
734
|
} else {
|
|
844
|
-
switch (
|
|
735
|
+
switch (adapterID) {
|
|
845
736
|
case 'hmrpc':
|
|
846
737
|
if (deviceBatteryState === 0) {
|
|
847
738
|
batteryHealth = ' - ';
|
|
848
739
|
} else {
|
|
849
740
|
batteryHealth = deviceBatteryState + 'V';
|
|
741
|
+
isBatteryDevice = true;
|
|
850
742
|
}
|
|
851
743
|
break;
|
|
852
744
|
|
|
853
|
-
case '
|
|
745
|
+
case 'hueExt':
|
|
854
746
|
if (shortDeviceBatteryState) {
|
|
855
747
|
batteryHealth = shortDeviceBatteryState + '%';
|
|
748
|
+
isBatteryDevice = true;
|
|
856
749
|
}
|
|
857
750
|
break;
|
|
858
751
|
case 'mihomeVacuum':
|
|
859
752
|
if (shortDeviceBatteryState) {
|
|
860
753
|
batteryHealth = shortDeviceBatteryState + '%';
|
|
754
|
+
isBatteryDevice = true;
|
|
861
755
|
} else if (shortDeviceBatteryState2) {
|
|
862
756
|
batteryHealth = shortDeviceBatteryState2 + '%';
|
|
757
|
+
isBatteryDevice = true;
|
|
863
758
|
}
|
|
864
759
|
break;
|
|
865
760
|
default:
|
|
866
|
-
batteryHealth =
|
|
761
|
+
batteryHealth = deviceBatteryState + '%';
|
|
762
|
+
isBatteryDevice = true;
|
|
867
763
|
}
|
|
868
764
|
}
|
|
869
765
|
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
766
|
+
/*=============================================
|
|
767
|
+
= Set Lowbat indicator =
|
|
768
|
+
=============================================*/
|
|
769
|
+
switch (typeof deviceLowBatState) {
|
|
770
|
+
case 'number':
|
|
771
|
+
if (deviceLowBatState === 0) {
|
|
874
772
|
lowBatIndicator = true;
|
|
875
773
|
}
|
|
876
774
|
break;
|
|
877
|
-
|
|
878
|
-
|
|
775
|
+
|
|
776
|
+
case 'string':
|
|
777
|
+
if (deviceLowBatState !== 'NORMAL') {
|
|
778
|
+
// Tado devices
|
|
879
779
|
lowBatIndicator = true;
|
|
880
780
|
}
|
|
881
781
|
break;
|
|
882
782
|
|
|
883
|
-
|
|
884
|
-
if (
|
|
783
|
+
case 'boolean':
|
|
784
|
+
if (deviceLowBatState) {
|
|
885
785
|
lowBatIndicator = true;
|
|
886
|
-
}
|
|
786
|
+
}
|
|
787
|
+
break;
|
|
788
|
+
|
|
789
|
+
default: // if the battery state is under the set limit
|
|
790
|
+
if (deviceBatteryState && deviceBatteryState < this.config.minWarnBatterie) {
|
|
887
791
|
lowBatIndicator = true;
|
|
888
792
|
}
|
|
793
|
+
break;
|
|
889
794
|
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
795
|
+
|
|
796
|
+
/*=============================================
|
|
797
|
+
= Get last contact of device =
|
|
798
|
+
=============================================*/
|
|
799
|
+
let lastContactString;
|
|
800
|
+
let deviceState = 'Online';
|
|
801
|
+
|
|
802
|
+
const deviceMainSelector = await this.getForeignStateAsync(id);
|
|
803
|
+
const deviceUnreachSelector = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].reach);
|
|
804
|
+
const deviceStateSelector = await this.getForeignStateAsync(shortCurrDeviceString + this.arrDev[i].stateValue); // for hmrpc devices
|
|
805
|
+
const rssiPeerSelector = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rssiPeerState);
|
|
806
|
+
|
|
807
|
+
if (deviceMainSelector) {
|
|
808
|
+
try {
|
|
809
|
+
const lastContact = await this.getTimestamp(deviceMainSelector.ts);
|
|
810
|
+
const deviceUnreachState = await this.getInitValue(currDeviceString + this.arrDev[i].reach);
|
|
811
|
+
const lastDeviceUnreachStateChange = deviceUnreachSelector != undefined ? await this.getTimestamp(deviceUnreachSelector.lc) : await this.getTimestamp(deviceMainSelector.ts);
|
|
812
|
+
const shortDeviceUnreachState = await this.getForeignStateAsync(shortCurrDeviceString + this.arrDev[i].reach);
|
|
813
|
+
|
|
814
|
+
// If there is no contact since user sets minutes add device in offline list
|
|
815
|
+
// calculate to days after 48 hours
|
|
816
|
+
switch (this.arrDev[i].reach) {
|
|
817
|
+
case 'none':
|
|
818
|
+
lastContactString = await this.getLastContact(deviceMainSelector.ts);
|
|
819
|
+
break;
|
|
820
|
+
|
|
821
|
+
default:
|
|
822
|
+
//State changed
|
|
823
|
+
if (adapterID === 'hmrpc') {
|
|
824
|
+
if (linkQuality !== ' - ') {
|
|
825
|
+
if (deviceUnreachState) {
|
|
826
|
+
lastContactString = await this.getLastContact(deviceMainSelector.lc);
|
|
827
|
+
} else {
|
|
828
|
+
lastContactString = await this.getLastContact(deviceMainSelector.ts);
|
|
829
|
+
}
|
|
830
|
+
} else {
|
|
831
|
+
if (deviceStateSelector) {
|
|
832
|
+
// because old hm devices don't send rssi states
|
|
833
|
+
lastContactString = await this.getLastContact(deviceStateSelector.ts);
|
|
834
|
+
} else if (rssiPeerSelector) {
|
|
835
|
+
// because old hm sensors don't send rssi/state values
|
|
836
|
+
lastContactString = await this.getLastContact(rssiPeerSelector.ts);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
} else {
|
|
840
|
+
if (!deviceUnreachState) {
|
|
841
|
+
lastContactString = await this.getLastContact(deviceMainSelector.lc);
|
|
842
|
+
} else {
|
|
843
|
+
lastContactString = await this.getLastContact(deviceMainSelector.ts);
|
|
844
|
+
}
|
|
845
|
+
break;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/*=============================================
|
|
850
|
+
= Set Online Status =
|
|
851
|
+
=============================================*/
|
|
852
|
+
if (this.maxMinutes !== undefined) {
|
|
853
|
+
switch (adapterID) {
|
|
854
|
+
case 'hmrpc':
|
|
855
|
+
case 'hmiP':
|
|
856
|
+
case 'maxcube':
|
|
857
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
858
|
+
if (deviceUnreachState) {
|
|
859
|
+
deviceState = 'Offline'; //set online state to offline
|
|
860
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
861
|
+
}
|
|
862
|
+
} else if (lastDeviceUnreachStateChange > this.maxMinutes[adapterID] && deviceUnreachState) {
|
|
863
|
+
deviceState = 'Offline'; //set online state to offline
|
|
864
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
865
|
+
}
|
|
866
|
+
break;
|
|
867
|
+
case 'ping':
|
|
868
|
+
case 'deconz':
|
|
869
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
870
|
+
if (!deviceUnreachState) {
|
|
871
|
+
deviceState = 'Offline'; //set online state to offline
|
|
872
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
873
|
+
}
|
|
874
|
+
} else if (lastDeviceUnreachStateChange > this.maxMinutes[adapterID] && !deviceUnreachState) {
|
|
875
|
+
deviceState = 'Offline'; //set online state to offline
|
|
876
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
877
|
+
}
|
|
878
|
+
break;
|
|
879
|
+
case 'unifi':
|
|
880
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
881
|
+
if (deviceUnreachState === 0) {
|
|
882
|
+
deviceState = 'Offline'; //set online state to offline
|
|
883
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
884
|
+
}
|
|
885
|
+
} else if (this.maxMinutes !== undefined && lastContact > this.maxMinutes[adapterID]) {
|
|
886
|
+
deviceState = 'Offline'; //set online state to offline
|
|
887
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
888
|
+
}
|
|
889
|
+
break;
|
|
890
|
+
case 'shelly':
|
|
891
|
+
case 'sonoff':
|
|
892
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
893
|
+
if (!deviceUnreachState) {
|
|
894
|
+
deviceState = 'Offline'; //set online state to offline
|
|
895
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
896
|
+
}
|
|
897
|
+
} else if (!deviceUnreachState && lastDeviceUnreachStateChange > this.maxMinutes[adapterID]) {
|
|
898
|
+
deviceState = 'Offline'; //set online state to offline
|
|
899
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
900
|
+
}
|
|
901
|
+
break;
|
|
902
|
+
case 'mihomeVacuum':
|
|
903
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
904
|
+
if (!shortDeviceUnreachState) {
|
|
905
|
+
deviceState = 'Offline'; //set online state to offline
|
|
906
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
907
|
+
}
|
|
908
|
+
} else if (lastContact > this.maxMinutes[adapterID]) {
|
|
909
|
+
deviceState = 'Offline'; //set online state to offline
|
|
910
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
911
|
+
}
|
|
912
|
+
break;
|
|
913
|
+
case 'mihome':
|
|
914
|
+
if (this.arrDev[i].battery === 'none') {
|
|
915
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
916
|
+
if (!deviceUnreachState) {
|
|
917
|
+
deviceState = 'Offline'; //set online state to offline
|
|
918
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
919
|
+
}
|
|
920
|
+
} else if (lastContact > this.maxMinutes[adapterID]) {
|
|
921
|
+
deviceState = 'Offline'; //set online state to offline
|
|
922
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
923
|
+
}
|
|
924
|
+
} else {
|
|
925
|
+
if (this.config.mihomeMaxMinutes <= 0) {
|
|
926
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
927
|
+
deviceState = 'Offline'; //set online state to offline
|
|
928
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
929
|
+
}
|
|
930
|
+
} else if (lastContact > this.maxMinutes[adapterID]) {
|
|
931
|
+
deviceState = 'Offline'; //set online state to offline
|
|
932
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
break;
|
|
936
|
+
default:
|
|
937
|
+
if (this.maxMinutes[adapterID] <= 0) {
|
|
938
|
+
if (!deviceUnreachState) {
|
|
939
|
+
deviceState = 'Offline'; //set online state to offline
|
|
940
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
941
|
+
}
|
|
942
|
+
} else if (lastContact > this.maxMinutes[adapterID]) {
|
|
943
|
+
deviceState = 'Offline'; //set online state to offline
|
|
944
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
945
|
+
}
|
|
946
|
+
break;
|
|
902
947
|
}
|
|
903
|
-
|
|
948
|
+
}
|
|
949
|
+
} catch (error) {
|
|
950
|
+
this.errorReporting('[getLastContact]', error);
|
|
904
951
|
}
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
/*=============================================
|
|
955
|
+
= Fill Raw Lists =
|
|
956
|
+
=============================================*/
|
|
957
|
+
|
|
958
|
+
/* Add only devices with battery in the rawlist */
|
|
959
|
+
if (this.listOnlyBattery) {
|
|
960
|
+
if (isBatteryDevice) {
|
|
961
|
+
this.listAllDevicesRaw.push({
|
|
962
|
+
Path: id,
|
|
963
|
+
Device: deviceName,
|
|
964
|
+
Adapter: adapter,
|
|
965
|
+
isBatteryDevice: isBatteryDevice,
|
|
966
|
+
Battery: batteryHealth,
|
|
967
|
+
LowBat: lowBatIndicator,
|
|
913
968
|
'Signal strength': linkQuality,
|
|
914
969
|
'Last contact': lastContactString,
|
|
915
|
-
|
|
916
|
-
}
|
|
917
|
-
|
|
970
|
+
Status: deviceState,
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
} else {
|
|
974
|
+
/* Add all devices */
|
|
975
|
+
this.listAllDevicesRaw.push({
|
|
976
|
+
Path: id,
|
|
977
|
+
Device: deviceName,
|
|
978
|
+
Adapter: adapter,
|
|
979
|
+
isBatteryDevice: isBatteryDevice,
|
|
980
|
+
Battery: batteryHealth,
|
|
981
|
+
LowBat: lowBatIndicator,
|
|
982
|
+
'Signal strength': linkQuality,
|
|
983
|
+
'Last contact': lastContactString,
|
|
984
|
+
Status: deviceState,
|
|
985
|
+
});
|
|
918
986
|
}
|
|
919
987
|
} else {
|
|
920
|
-
|
|
988
|
+
/* cancel run if unloaded was called. */
|
|
989
|
+
return;
|
|
921
990
|
}
|
|
922
991
|
} // <-- end of loop
|
|
923
992
|
await this.createLists();
|
|
924
993
|
await this.countDevices();
|
|
925
994
|
} // <-- end of createData
|
|
926
995
|
|
|
927
|
-
|
|
928
996
|
/**
|
|
929
997
|
* @param {string} adptName - Adapter name
|
|
930
998
|
*/
|
|
@@ -932,16 +1000,17 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
932
1000
|
// create Data for each Adapter in own lists
|
|
933
1001
|
this.log.debug(`Function started: ${this.createDataForEachAdapter.name}`);
|
|
934
1002
|
|
|
1003
|
+
await this.resetVars(); // reset the arrays and counts
|
|
1004
|
+
|
|
935
1005
|
try {
|
|
936
1006
|
for (let i = 0; i < this.arrDev.length; i++) {
|
|
937
|
-
|
|
938
|
-
|
|
1007
|
+
if (this.arrDev[i].adapterID.includes(adptName)) {
|
|
1008
|
+
// list device only if selected adapter matched with device
|
|
939
1009
|
await this.createData(i);
|
|
940
1010
|
}
|
|
941
1011
|
}
|
|
942
|
-
await this.writeDatapoints(adptName); // fill the datapoints
|
|
943
|
-
await this.resetVars(); // reset the arrays and counts
|
|
944
1012
|
|
|
1013
|
+
await this.writeDatapoints(adptName); // fill the datapoints
|
|
945
1014
|
} catch (error) {
|
|
946
1015
|
this.errorReporting('[createDataForEachAdapter]', error);
|
|
947
1016
|
}
|
|
@@ -949,8 +1018,10 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
949
1018
|
this.log.debug(`Function finished: ${this.createDataForEachAdapter.name}`);
|
|
950
1019
|
} // <-- end of createDataForEachAdapter
|
|
951
1020
|
|
|
1021
|
+
/**
|
|
1022
|
+
* create Data of all selected adapter in one list
|
|
1023
|
+
*/
|
|
952
1024
|
async createDataOfAllAdapter() {
|
|
953
|
-
// create Data of all selected adapter in one list
|
|
954
1025
|
this.log.debug(`Function started: ${this.createDataOfAllAdapter.name}`);
|
|
955
1026
|
|
|
956
1027
|
try {
|
|
@@ -968,7 +1039,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
968
1039
|
if (this.config.checkSendOfflineMsg) await this.sendOfflineNotifications();
|
|
969
1040
|
|
|
970
1041
|
await this.writeDatapoints(); // fill the datapoints
|
|
971
|
-
|
|
972
1042
|
} catch (error) {
|
|
973
1043
|
this.errorReporting('[createDataOfAllAdapter]', error);
|
|
974
1044
|
}
|
|
@@ -976,13 +1046,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
976
1046
|
this.log.debug(`Function finished: ${this.createDataOfAllAdapter.name}`);
|
|
977
1047
|
} // <-- end of createDataOfAllAdapter
|
|
978
1048
|
|
|
979
|
-
|
|
980
1049
|
/**
|
|
981
1050
|
* Notification service
|
|
982
1051
|
* @param {string} text - Text which should be send
|
|
983
1052
|
*/
|
|
984
1053
|
async sendNotification(text) {
|
|
985
|
-
|
|
986
1054
|
// Pushover
|
|
987
1055
|
try {
|
|
988
1056
|
if (this.config.instancePushover) {
|
|
@@ -996,7 +1064,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
996
1064
|
message: text,
|
|
997
1065
|
title: this.config.titlePushover,
|
|
998
1066
|
device: this.config.devicePushover,
|
|
999
|
-
priority: this.config.prioPushover
|
|
1067
|
+
priority: this.config.prioPushover,
|
|
1000
1068
|
});
|
|
1001
1069
|
}
|
|
1002
1070
|
}
|
|
@@ -1016,7 +1084,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1016
1084
|
await this.sendToAsync(this.config.instanceTelegram, 'send', {
|
|
1017
1085
|
text: text,
|
|
1018
1086
|
user: this.config.deviceTelegram,
|
|
1019
|
-
chatId: this.config.chatIdTelegram
|
|
1087
|
+
chatId: this.config.chatIdTelegram,
|
|
1020
1088
|
});
|
|
1021
1089
|
}
|
|
1022
1090
|
}
|
|
@@ -1035,7 +1103,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1035
1103
|
} else {
|
|
1036
1104
|
await this.sendToAsync(this.config.instanceWhatsapp, 'send', {
|
|
1037
1105
|
text: text,
|
|
1038
|
-
phone: this.config.phoneWhatsapp
|
|
1106
|
+
phone: this.config.phoneWhatsapp,
|
|
1039
1107
|
});
|
|
1040
1108
|
}
|
|
1041
1109
|
}
|
|
@@ -1055,7 +1123,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1055
1123
|
await this.sendToAsync(this.config.instanceEmail, 'send', {
|
|
1056
1124
|
sendTo: this.config.sendToEmail,
|
|
1057
1125
|
text: text,
|
|
1058
|
-
subject: this.config.subjectEmail
|
|
1126
|
+
subject: this.config.subjectEmail,
|
|
1059
1127
|
});
|
|
1060
1128
|
}
|
|
1061
1129
|
}
|
|
@@ -1073,7 +1141,10 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1073
1141
|
this.log.warn('Jarvis instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1074
1142
|
} else {
|
|
1075
1143
|
const jsonText = JSON.stringify(text);
|
|
1076
|
-
await this.setForeignStateAsync(
|
|
1144
|
+
await this.setForeignStateAsync(
|
|
1145
|
+
`${this.config.instanceJarvis}.addNotification`,
|
|
1146
|
+
'{"title":"' + this.config.titleJarvis + ' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message": ' + jsonText + ',"display": "drawer"}',
|
|
1147
|
+
);
|
|
1077
1148
|
}
|
|
1078
1149
|
}
|
|
1079
1150
|
} catch (error) {
|
|
@@ -1090,7 +1161,10 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1090
1161
|
this.log.warn('Lovelace instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1091
1162
|
} else {
|
|
1092
1163
|
const jsonText = JSON.stringify(text);
|
|
1093
|
-
await this.setForeignStateAsync(
|
|
1164
|
+
await this.setForeignStateAsync(
|
|
1165
|
+
`${this.config.instanceLovelace}.notifications.add`,
|
|
1166
|
+
'{"message":' + jsonText + ', "title":"' + this.config.titleLovelace + ' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')"}',
|
|
1167
|
+
);
|
|
1094
1168
|
}
|
|
1095
1169
|
}
|
|
1096
1170
|
} catch (error) {
|
|
@@ -1098,10 +1172,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1098
1172
|
}
|
|
1099
1173
|
} // <-- End of sendNotification function
|
|
1100
1174
|
|
|
1175
|
+
/**
|
|
1176
|
+
* send shedule message for low battery devices
|
|
1177
|
+
*/
|
|
1101
1178
|
async sendBatteryNotifyShedule() {
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
const time = (this.config.checkSendBatteryTime).split(':');
|
|
1179
|
+
const time = this.config.checkSendBatteryTime.split(':');
|
|
1105
1180
|
|
|
1106
1181
|
const checkDays = []; // list of selected days
|
|
1107
1182
|
|
|
@@ -1114,8 +1189,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1114
1189
|
if (this.config.checkSaturday) checkDays.push(6);
|
|
1115
1190
|
if (this.config.checkSunday) checkDays.push(0);
|
|
1116
1191
|
|
|
1117
|
-
if (checkDays.length >= 1) {
|
|
1118
|
-
|
|
1192
|
+
if (checkDays.length >= 1) {
|
|
1193
|
+
// check if an day is selected
|
|
1194
|
+
this.log.debug(`Number of selected days for daily battery message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
1119
1195
|
} else {
|
|
1120
1196
|
this.log.warn(`No days selected for daily battery message. Please check the instance configuration!`);
|
|
1121
1197
|
return; // cancel function if no day is selected
|
|
@@ -1127,20 +1203,18 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1127
1203
|
try {
|
|
1128
1204
|
let deviceList = '';
|
|
1129
1205
|
|
|
1130
|
-
for (const id of this.
|
|
1131
|
-
if (!this.blacklistNotify.includes(id['
|
|
1206
|
+
for (const id of this.batteryLowPoweredRaw) {
|
|
1207
|
+
if (!this.blacklistNotify.includes(id['Path'])) {
|
|
1132
1208
|
deviceList = `${deviceList}\n${id['Device']} (${id['Battery']})`;
|
|
1133
1209
|
}
|
|
1134
1210
|
}
|
|
1135
1211
|
|
|
1136
|
-
if (
|
|
1212
|
+
if (this.lowBatteryPoweredCountRaw > 0 && deviceList.length > 0) {
|
|
1137
1213
|
this.log.info(`Niedrige Batteriezustände: ${deviceList}`);
|
|
1138
1214
|
this.setStateAsync('lastNotification', `Niedrige Batteriezustände: ${deviceList}`, true);
|
|
1139
1215
|
|
|
1140
1216
|
this.sendNotification(`Niedriege Batteriezustände: ${deviceList}`);
|
|
1141
|
-
|
|
1142
1217
|
}
|
|
1143
|
-
|
|
1144
1218
|
} catch (error) {
|
|
1145
1219
|
this.errorReporting('[sendBatteryNotifyShedule]', error);
|
|
1146
1220
|
}
|
|
@@ -1148,48 +1222,48 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1148
1222
|
}
|
|
1149
1223
|
} //<--End of battery notification
|
|
1150
1224
|
|
|
1225
|
+
/**
|
|
1226
|
+
* send message if an device is offline
|
|
1227
|
+
*/
|
|
1151
1228
|
async sendOfflineNotifications() {
|
|
1152
|
-
// send message if an device is offline
|
|
1153
|
-
|
|
1154
1229
|
this.log.debug(`Start the function: ${this.sendOfflineNotifications.name}`);
|
|
1155
1230
|
|
|
1156
1231
|
try {
|
|
1157
1232
|
let msg = '';
|
|
1158
1233
|
let deviceList = '';
|
|
1159
|
-
const offlineDevicesCountOld = await this.getOwnInitValue('offlineCount');
|
|
1160
1234
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
if (!this.blacklistNotify.includes(id['Device'])) {
|
|
1165
|
-
deviceList = `${deviceList}\n${id['Device']} (${id['Last contact']})`;
|
|
1166
|
-
}
|
|
1235
|
+
for (const id of this.offlineDevicesRaw) {
|
|
1236
|
+
if (!this.blacklistNotify.includes(id['Path'])) {
|
|
1237
|
+
deviceList = `${deviceList}\n${id['Device']} (${id['Last contact']})`;
|
|
1167
1238
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
await this.setStateAsync('lastNotification', msg + deviceList, true);
|
|
1179
|
-
await this.sendNotification(msg + deviceList);
|
|
1239
|
+
}
|
|
1240
|
+
if (deviceList.length !== this.offlineDevicesCountRawOld) {
|
|
1241
|
+
if (deviceList.length == 0) {
|
|
1242
|
+
msg = 'Alle Geräte sind Online.';
|
|
1243
|
+
} else if (deviceList.length == 1) {
|
|
1244
|
+
// make singular if it is only one device
|
|
1245
|
+
msg = 'Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n';
|
|
1246
|
+
} else if (deviceList.length >= 2) {
|
|
1247
|
+
//make plural if it is more than one device
|
|
1248
|
+
msg = `Folgende Geräte sind seit einiger Zeit nicht erreichbar: \n`;
|
|
1180
1249
|
}
|
|
1181
1250
|
|
|
1251
|
+
this.log.info(msg + deviceList);
|
|
1252
|
+
this.offlineDevicesCountRawOld = deviceList.length;
|
|
1253
|
+
await this.setStateAsync('lastNotification', msg + deviceList, true);
|
|
1254
|
+
await this.sendNotification(msg + deviceList);
|
|
1182
1255
|
}
|
|
1183
1256
|
} catch (error) {
|
|
1184
1257
|
this.errorReporting('[sendOfflineMessage]', error);
|
|
1185
1258
|
}
|
|
1186
1259
|
this.log.debug(`Finished the function: ${this.sendOfflineNotifications.name}`);
|
|
1187
|
-
}//<--End of offline notification
|
|
1260
|
+
} //<--End of offline notification
|
|
1188
1261
|
|
|
1262
|
+
/**
|
|
1263
|
+
* send shedule message with offline devices
|
|
1264
|
+
*/
|
|
1189
1265
|
async sendOfflineNotificationsShedule() {
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
const time = (this.config.checkSendOfflineTime).split(':');
|
|
1266
|
+
const time = this.config.checkSendOfflineTime.split(':');
|
|
1193
1267
|
|
|
1194
1268
|
const checkDays = []; // list of selected days
|
|
1195
1269
|
|
|
@@ -1202,8 +1276,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1202
1276
|
if (this.config.checkOfflineSaturday) checkDays.push(6);
|
|
1203
1277
|
if (this.config.checkOfflineSunday) checkDays.push(0);
|
|
1204
1278
|
|
|
1205
|
-
if (checkDays.length >= 1) {
|
|
1206
|
-
|
|
1279
|
+
if (checkDays.length >= 1) {
|
|
1280
|
+
// check if an day is selected
|
|
1281
|
+
this.log.debug(`Number of selected days for daily offline message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
1207
1282
|
} else {
|
|
1208
1283
|
this.log.warn(`No days selected for daily offline message. Please check the instance configuration!`);
|
|
1209
1284
|
return; // cancel function if no day is selected
|
|
@@ -1215,8 +1290,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1215
1290
|
try {
|
|
1216
1291
|
let deviceList = '';
|
|
1217
1292
|
|
|
1218
|
-
for (const id of this.
|
|
1219
|
-
if (!this.blacklistNotify.includes(id['
|
|
1293
|
+
for (const id of this.offlineDevicesRaw) {
|
|
1294
|
+
if (!this.blacklistNotify.includes(id['Path'])) {
|
|
1220
1295
|
deviceList = `${deviceList}\n${id['Device']} (${id['Last contact']})`;
|
|
1221
1296
|
}
|
|
1222
1297
|
}
|
|
@@ -1227,14 +1302,16 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1227
1302
|
|
|
1228
1303
|
this.sendNotification(`Geräte Offline: ${deviceList}`);
|
|
1229
1304
|
}
|
|
1230
|
-
|
|
1231
1305
|
} catch (error) {
|
|
1232
1306
|
this.errorReporting('[sendOfflineNotificationsShedule]', error);
|
|
1233
1307
|
}
|
|
1234
1308
|
});
|
|
1235
1309
|
}
|
|
1236
|
-
}//<--End of daily offline notification
|
|
1310
|
+
} //<--End of daily offline notification
|
|
1237
1311
|
|
|
1312
|
+
/**
|
|
1313
|
+
* reset arrays and counts
|
|
1314
|
+
*/
|
|
1238
1315
|
async resetVars() {
|
|
1239
1316
|
//Reset all arrays and counts
|
|
1240
1317
|
this.log.debug(`Function started: ${this.resetVars.name}`);
|
|
@@ -1246,6 +1323,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1246
1323
|
this.batteryLowPowered = [];
|
|
1247
1324
|
this.listAllDevices = [];
|
|
1248
1325
|
this.listAllDevicesRaw = [];
|
|
1326
|
+
|
|
1327
|
+
// raws
|
|
1328
|
+
this.batteryLowPoweredRaw = [];
|
|
1329
|
+
this.offlineDevicesRaw = [];
|
|
1330
|
+
this.lowBatteryPoweredCountRaw = 0;
|
|
1331
|
+
this.offlineDevicesCountRaw = 0;
|
|
1332
|
+
|
|
1249
1333
|
// counts
|
|
1250
1334
|
this.offlineDevicesCount = 0;
|
|
1251
1335
|
this.deviceCounter = 0;
|
|
@@ -1256,7 +1340,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1256
1340
|
this.log.debug(`Function finished: ${this.resetVars.name}`);
|
|
1257
1341
|
} // <-- end of resetVars
|
|
1258
1342
|
|
|
1259
|
-
|
|
1260
1343
|
/**
|
|
1261
1344
|
* @param {string} [adptName] - Adaptername
|
|
1262
1345
|
*/
|
|
@@ -1266,7 +1349,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1266
1349
|
this.log.debug(`Start the function: ${this.writeDatapoints.name}`);
|
|
1267
1350
|
|
|
1268
1351
|
try {
|
|
1269
|
-
|
|
1270
1352
|
let dpSubFolder;
|
|
1271
1353
|
//write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
|
|
1272
1354
|
if (adptName) {
|
|
@@ -1282,62 +1364,91 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1282
1364
|
|
|
1283
1365
|
if (this.deviceCounter == 0) {
|
|
1284
1366
|
// if no device is count, write the JSON List with default value
|
|
1285
|
-
this.listAllDevices = [{
|
|
1367
|
+
this.listAllDevices = [{ Device: '--none--', Adapter: '', Battery: '', 'Last contact': '', 'Signal strength': '' }];
|
|
1286
1368
|
}
|
|
1287
1369
|
await this.setStateAsync(`${dpSubFolder}listAll`, { val: JSON.stringify(this.listAllDevices), ack: true });
|
|
1288
1370
|
|
|
1289
1371
|
if (this.linkQualityCount == 0) {
|
|
1290
1372
|
// if no device is count, write the JSON List with default value
|
|
1291
|
-
this.linkQualityDevices = [{
|
|
1373
|
+
this.linkQualityDevices = [{ Device: '--none--', Adapter: '', 'Signal strength': '' }];
|
|
1292
1374
|
}
|
|
1293
1375
|
//write JSON list
|
|
1294
|
-
await this.setStateAsync(`${dpSubFolder}linkQualityList`, {
|
|
1376
|
+
await this.setStateAsync(`${dpSubFolder}linkQualityList`, {
|
|
1377
|
+
val: JSON.stringify(this.linkQualityDevices),
|
|
1378
|
+
ack: true,
|
|
1379
|
+
});
|
|
1295
1380
|
//write HTML list
|
|
1296
|
-
if (this.config.createHtmlList)
|
|
1381
|
+
if (this.config.createHtmlList)
|
|
1382
|
+
await this.setStateAsync(`${dpSubFolder}linkQualityListHTML`, {
|
|
1383
|
+
val: await this.creatLinkQualityListHTML(this.linkQualityDevices, this.linkQualityCount),
|
|
1384
|
+
ack: true,
|
|
1385
|
+
});
|
|
1297
1386
|
|
|
1298
1387
|
if (this.offlineDevicesCount == 0) {
|
|
1299
1388
|
// if no device is count, write the JSON List with default value
|
|
1300
|
-
this.offlineDevices = [{
|
|
1389
|
+
this.offlineDevices = [{ Device: '--none--', Adapter: '', 'Last contact': '' }];
|
|
1301
1390
|
}
|
|
1302
1391
|
//write JSON list
|
|
1303
|
-
await this.setStateAsync(`${dpSubFolder}offlineList`, {
|
|
1392
|
+
await this.setStateAsync(`${dpSubFolder}offlineList`, {
|
|
1393
|
+
val: JSON.stringify(this.offlineDevices),
|
|
1394
|
+
ack: true,
|
|
1395
|
+
});
|
|
1304
1396
|
//write HTML list
|
|
1305
|
-
if (this.config.createHtmlList)
|
|
1397
|
+
if (this.config.createHtmlList)
|
|
1398
|
+
await this.setStateAsync(`${dpSubFolder}offlineListHTML`, {
|
|
1399
|
+
val: await this.createOfflineListHTML(this.offlineDevices, this.offlineDevicesCount),
|
|
1400
|
+
ack: true,
|
|
1401
|
+
});
|
|
1306
1402
|
|
|
1307
1403
|
if (this.batteryPoweredCount == 0) {
|
|
1308
1404
|
// if no device is count, write the JSON List with default value
|
|
1309
|
-
this.batteryPowered = [{
|
|
1405
|
+
this.batteryPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
|
|
1310
1406
|
}
|
|
1311
1407
|
//write JSON list
|
|
1312
|
-
await this.setStateAsync(`${dpSubFolder}batteryList`, {
|
|
1408
|
+
await this.setStateAsync(`${dpSubFolder}batteryList`, {
|
|
1409
|
+
val: JSON.stringify(this.batteryPowered),
|
|
1410
|
+
ack: true,
|
|
1411
|
+
});
|
|
1313
1412
|
//write HTML list
|
|
1314
|
-
if (this.config.createHtmlList)
|
|
1413
|
+
if (this.config.createHtmlList)
|
|
1414
|
+
await this.setStateAsync(`${dpSubFolder}batteryListHTML`, {
|
|
1415
|
+
val: await this.createBatteryListHTML(this.batteryPowered, this.batteryPoweredCount, false),
|
|
1416
|
+
ack: true,
|
|
1417
|
+
});
|
|
1315
1418
|
|
|
1316
1419
|
if (this.lowBatteryPoweredCount == 0) {
|
|
1317
1420
|
// if no device is count, write the JSON List with default value
|
|
1318
|
-
this.batteryLowPowered = [{
|
|
1421
|
+
this.batteryLowPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
|
|
1319
1422
|
}
|
|
1320
1423
|
//write JSON list
|
|
1321
|
-
await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {
|
|
1424
|
+
await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {
|
|
1425
|
+
val: JSON.stringify(this.batteryLowPowered),
|
|
1426
|
+
ack: true,
|
|
1427
|
+
});
|
|
1322
1428
|
//write HTML list
|
|
1323
|
-
if (this.config.createHtmlList)
|
|
1429
|
+
if (this.config.createHtmlList)
|
|
1430
|
+
await this.setStateAsync(`${dpSubFolder}lowBatteryListHTML`, {
|
|
1431
|
+
val: await this.createBatteryListHTML(this.batteryLowPowered, this.lowBatteryPoweredCount, true),
|
|
1432
|
+
ack: true,
|
|
1433
|
+
});
|
|
1324
1434
|
|
|
1325
1435
|
// create timestamp of last run
|
|
1326
1436
|
const lastCheck = this.formatDate(new Date(), 'DD.MM.YYYY') + ' - ' + this.formatDate(new Date(), 'hh:mm:ss');
|
|
1327
1437
|
await this.setStateAsync('lastCheck', lastCheck, true);
|
|
1328
|
-
}
|
|
1329
|
-
catch (error) {
|
|
1438
|
+
} catch (error) {
|
|
1330
1439
|
this.errorReporting('[writeDatapoints]', error);
|
|
1331
1440
|
}
|
|
1332
1441
|
this.log.debug(`Function finished: ${this.writeDatapoints.name}`);
|
|
1333
|
-
}//<--End of writing Datapoints
|
|
1442
|
+
} //<--End of writing Datapoints
|
|
1334
1443
|
|
|
1335
1444
|
/**
|
|
1336
1445
|
* @param {object} devices - Device
|
|
1337
1446
|
* @param {number} deviceCount - Counted devices
|
|
1338
1447
|
*/
|
|
1339
1448
|
async creatLinkQualityListHTML(devices, deviceCount) {
|
|
1340
|
-
devices = devices.sort((a, b) => {
|
|
1449
|
+
devices = devices.sort((a, b) => {
|
|
1450
|
+
return a.Device.localeCompare(b.Device);
|
|
1451
|
+
});
|
|
1341
1452
|
let html = `<center>
|
|
1342
1453
|
<b>Link Quality Devices:<font> ${deviceCount}</b><small></small></font>
|
|
1343
1454
|
<p></p>
|
|
@@ -1369,7 +1480,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1369
1480
|
* @param {number} deviceCount - Counted devices
|
|
1370
1481
|
*/
|
|
1371
1482
|
async createOfflineListHTML(devices, deviceCount) {
|
|
1372
|
-
devices = devices.sort((a, b) => {
|
|
1483
|
+
devices = devices.sort((a, b) => {
|
|
1484
|
+
return a.Device.localeCompare(b.Device);
|
|
1485
|
+
});
|
|
1373
1486
|
let html = `<center>
|
|
1374
1487
|
<b>Offline Devices: <font color=${deviceCount == 0 ? '#3bcf0e' : 'orange'}>${deviceCount}</b><small></small></font>
|
|
1375
1488
|
<p></p>
|
|
@@ -1402,7 +1515,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1402
1515
|
* @param {object} [isLowBatteryList] - list Low Battery Devices
|
|
1403
1516
|
*/
|
|
1404
1517
|
async createBatteryListHTML(devices, deviceCount, isLowBatteryList) {
|
|
1405
|
-
devices = devices.sort((a, b) => {
|
|
1518
|
+
devices = devices.sort((a, b) => {
|
|
1519
|
+
return a.Device.localeCompare(b.Device);
|
|
1520
|
+
});
|
|
1406
1521
|
let html = `<center>
|
|
1407
1522
|
<b>${isLowBatteryList == true ? 'Schwache ' : ''}Batterie Devices: <font color=${isLowBatteryList == true ? (deviceCount > 0 ? 'orange' : '#3bcf0e') : ''}>${deviceCount}</b></font>
|
|
1408
1523
|
<p></p>
|
|
@@ -1416,7 +1531,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1416
1531
|
<tr>
|
|
1417
1532
|
<td colspan="5"><hr></td>
|
|
1418
1533
|
</tr>`;
|
|
1419
|
-
|
|
1420
1534
|
for (const device of devices) {
|
|
1421
1535
|
html += `<tr>
|
|
1422
1536
|
<td><font>${device.Device}</font></td>
|
|
@@ -1427,7 +1541,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1427
1541
|
} else {
|
|
1428
1542
|
html += `<td align=right><font color=#3bcf0e>${device.Battery}</font></td>`;
|
|
1429
1543
|
}
|
|
1430
|
-
|
|
1431
1544
|
html += `</tr>`;
|
|
1432
1545
|
}
|
|
1433
1546
|
|
|
@@ -1440,7 +1553,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1440
1553
|
* @param {object} adptName - Adaptername of devices
|
|
1441
1554
|
*/
|
|
1442
1555
|
async createDPsForEachAdapter(adptName) {
|
|
1443
|
-
|
|
1444
1556
|
await this.setObjectNotExistsAsync(`${adptName}`, {
|
|
1445
1557
|
type: 'channel',
|
|
1446
1558
|
common: {
|
|
@@ -1450,210 +1562,210 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1450
1562
|
});
|
|
1451
1563
|
|
|
1452
1564
|
await this.setObjectNotExistsAsync(`${adptName}.offlineCount`, {
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
'zh-cn': '线内装置数量'
|
|
1565
|
+
type: 'state',
|
|
1566
|
+
common: {
|
|
1567
|
+
name: {
|
|
1568
|
+
en: 'Number of devices offline',
|
|
1569
|
+
de: 'Anzahl der Geräte offline',
|
|
1570
|
+
ru: 'Количество устройств offline',
|
|
1571
|
+
pt: 'Número de dispositivos offline',
|
|
1572
|
+
nl: 'Nummer van apparatuur offline',
|
|
1573
|
+
fr: 'Nombre de dispositifs hors ligne',
|
|
1574
|
+
it: 'Numero di dispositivi offline',
|
|
1575
|
+
es: 'Número de dispositivos sin conexión',
|
|
1576
|
+
pl: 'Ilość urządzeń offline',
|
|
1577
|
+
'zh-cn': '线内装置数量',
|
|
1466
1578
|
},
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1579
|
+
type: 'number',
|
|
1580
|
+
role: 'value',
|
|
1581
|
+
read: true,
|
|
1582
|
+
write: false,
|
|
1471
1583
|
},
|
|
1472
|
-
|
|
1584
|
+
native: {},
|
|
1473
1585
|
});
|
|
1474
1586
|
|
|
1475
1587
|
await this.setObjectNotExistsAsync(`${adptName}.offlineList`, {
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
'zh-cn': '线装置清单'
|
|
1588
|
+
type: 'state',
|
|
1589
|
+
common: {
|
|
1590
|
+
name: {
|
|
1591
|
+
en: 'List of offline devices',
|
|
1592
|
+
de: 'Liste der Offline-Geräte',
|
|
1593
|
+
ru: 'Список оффлайн устройств',
|
|
1594
|
+
pt: 'Lista de dispositivos off-line',
|
|
1595
|
+
nl: 'List van offline apparatuur',
|
|
1596
|
+
fr: 'Liste des dispositifs hors ligne',
|
|
1597
|
+
it: 'Elenco dei dispositivi offline',
|
|
1598
|
+
es: 'Lista de dispositivos sin conexión',
|
|
1599
|
+
pl: 'Lista urządzeń offline',
|
|
1600
|
+
'zh-cn': '线装置清单',
|
|
1489
1601
|
},
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1602
|
+
type: 'array',
|
|
1603
|
+
role: 'json',
|
|
1604
|
+
read: true,
|
|
1605
|
+
write: false,
|
|
1494
1606
|
},
|
|
1495
|
-
|
|
1607
|
+
native: {},
|
|
1496
1608
|
});
|
|
1497
1609
|
|
|
1498
1610
|
await this.setObjectNotExistsAsync(`${adptName}.listAll`, {
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
'zh-cn': '所有装置清单'
|
|
1611
|
+
type: 'state',
|
|
1612
|
+
common: {
|
|
1613
|
+
name: {
|
|
1614
|
+
en: 'List of all devices',
|
|
1615
|
+
de: 'Liste aller Geräte',
|
|
1616
|
+
ru: 'Список всех устройств',
|
|
1617
|
+
pt: 'Lista de todos os dispositivos',
|
|
1618
|
+
nl: 'List van alle apparaten',
|
|
1619
|
+
fr: 'Liste de tous les dispositifs',
|
|
1620
|
+
it: 'Elenco di tutti i dispositivi',
|
|
1621
|
+
es: 'Lista de todos los dispositivos',
|
|
1622
|
+
pl: 'Lista wszystkich urządzeń',
|
|
1623
|
+
'zh-cn': '所有装置清单',
|
|
1512
1624
|
},
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1625
|
+
type: 'array',
|
|
1626
|
+
role: 'json',
|
|
1627
|
+
read: true,
|
|
1628
|
+
write: false,
|
|
1517
1629
|
},
|
|
1518
|
-
|
|
1630
|
+
native: {},
|
|
1519
1631
|
});
|
|
1520
1632
|
|
|
1521
1633
|
await this.setObjectNotExistsAsync(`${adptName}.linkQualityList`, {
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
'zh-cn': '具有信号实力的装置清单'
|
|
1634
|
+
type: 'state',
|
|
1635
|
+
common: {
|
|
1636
|
+
name: {
|
|
1637
|
+
en: 'List of devices with signal strength',
|
|
1638
|
+
de: 'Liste der Geräte mit Signalstärke',
|
|
1639
|
+
ru: 'Список устройств с силой сигнала',
|
|
1640
|
+
pt: 'Lista de dispositivos com força de sinal',
|
|
1641
|
+
nl: 'List van apparaten met signaalkracht',
|
|
1642
|
+
fr: 'Liste des dispositifs avec force de signal',
|
|
1643
|
+
it: 'Elenco dei dispositivi con forza del segnale',
|
|
1644
|
+
es: 'Lista de dispositivos con fuerza de señal',
|
|
1645
|
+
pl: 'Lista urządzeń z siłą sygnałową',
|
|
1646
|
+
'zh-cn': '具有信号实力的装置清单',
|
|
1535
1647
|
},
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1648
|
+
type: 'array',
|
|
1649
|
+
role: 'json',
|
|
1650
|
+
read: true,
|
|
1651
|
+
write: false,
|
|
1540
1652
|
},
|
|
1541
|
-
|
|
1653
|
+
native: {},
|
|
1542
1654
|
});
|
|
1543
1655
|
|
|
1544
1656
|
await this.setObjectNotExistsAsync(`${adptName}.countAll`, {
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
'zh-cn': '所有装置的数目'
|
|
1657
|
+
type: 'state',
|
|
1658
|
+
common: {
|
|
1659
|
+
name: {
|
|
1660
|
+
en: 'Number of all devices',
|
|
1661
|
+
de: 'Anzahl aller Geräte',
|
|
1662
|
+
ru: 'Количество всех устройств',
|
|
1663
|
+
pt: 'Número de todos os dispositivos',
|
|
1664
|
+
nl: 'Nummer van alle apparaten',
|
|
1665
|
+
fr: 'Nombre de tous les appareils',
|
|
1666
|
+
it: 'Numero di tutti i dispositivi',
|
|
1667
|
+
es: 'Número de todos los dispositivos',
|
|
1668
|
+
pl: 'Ilość wszystkich urządzeń',
|
|
1669
|
+
'zh-cn': '所有装置的数目',
|
|
1558
1670
|
},
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1671
|
+
type: 'number',
|
|
1672
|
+
role: 'value',
|
|
1673
|
+
read: true,
|
|
1674
|
+
write: false,
|
|
1563
1675
|
},
|
|
1564
|
-
|
|
1676
|
+
native: {},
|
|
1565
1677
|
});
|
|
1566
1678
|
|
|
1567
1679
|
await this.setObjectNotExistsAsync(`${adptName}.batteryList`, {
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
'zh-cn': '电池国装置清单'
|
|
1680
|
+
type: 'state',
|
|
1681
|
+
common: {
|
|
1682
|
+
name: {
|
|
1683
|
+
en: 'List of devices with battery state',
|
|
1684
|
+
de: 'Liste der Geräte mit Batteriezustand',
|
|
1685
|
+
ru: 'Список устройств с состоянием батареи',
|
|
1686
|
+
pt: 'Lista de dispositivos com estado da bateria',
|
|
1687
|
+
nl: 'List van apparaten met batterij staat',
|
|
1688
|
+
fr: 'Liste des appareils avec état de batterie',
|
|
1689
|
+
it: 'Elenco dei dispositivi con stato della batteria',
|
|
1690
|
+
es: 'Lista de dispositivos con estado de batería',
|
|
1691
|
+
pl: 'Lista urządzeń z baterią stanową',
|
|
1692
|
+
'zh-cn': '电池国装置清单',
|
|
1581
1693
|
},
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1694
|
+
type: 'array',
|
|
1695
|
+
role: 'json',
|
|
1696
|
+
read: true,
|
|
1697
|
+
write: false,
|
|
1586
1698
|
},
|
|
1587
|
-
|
|
1699
|
+
native: {},
|
|
1588
1700
|
});
|
|
1589
1701
|
|
|
1590
1702
|
await this.setObjectNotExistsAsync(`${adptName}.lowBatteryList`, {
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
'zh-cn': '低电池国家装置清单'
|
|
1703
|
+
type: 'state',
|
|
1704
|
+
common: {
|
|
1705
|
+
name: {
|
|
1706
|
+
en: 'List of devices with low battery state',
|
|
1707
|
+
de: 'Liste der Geräte mit niedrigem Batteriezustand',
|
|
1708
|
+
ru: 'Список устройств с низким состоянием батареи',
|
|
1709
|
+
pt: 'Lista de dispositivos com baixo estado da bateria',
|
|
1710
|
+
nl: 'List van apparaten met lage batterij staat',
|
|
1711
|
+
fr: 'Liste des appareils à faible état de batterie',
|
|
1712
|
+
it: 'Elenco di dispositivi con stato di batteria basso',
|
|
1713
|
+
es: 'Lista de dispositivos con estado de batería bajo',
|
|
1714
|
+
pl: 'Lista urządzeń o niskim stanie baterii',
|
|
1715
|
+
'zh-cn': '低电池国家装置清单',
|
|
1604
1716
|
},
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1717
|
+
type: 'array',
|
|
1718
|
+
role: 'json',
|
|
1719
|
+
read: true,
|
|
1720
|
+
write: false,
|
|
1609
1721
|
},
|
|
1610
|
-
|
|
1722
|
+
native: {},
|
|
1611
1723
|
});
|
|
1612
1724
|
|
|
1613
1725
|
await this.setObjectNotExistsAsync(`${adptName}.lowBatteryCount`, {
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
'zh-cn': '低电池的装置数量'
|
|
1726
|
+
type: 'state',
|
|
1727
|
+
common: {
|
|
1728
|
+
name: {
|
|
1729
|
+
en: 'Number of devices with low battery',
|
|
1730
|
+
de: 'Anzahl der Geräte mit niedriger Batterie',
|
|
1731
|
+
ru: 'Количество устройств c низкой батареей',
|
|
1732
|
+
pt: 'Número de dispositivos com bateria baixa',
|
|
1733
|
+
nl: 'Nummer van apparaten met lage batterij',
|
|
1734
|
+
fr: 'Nombre de dispositifs avec batterie basse',
|
|
1735
|
+
it: 'Numero di dispositivi con batteria bassa',
|
|
1736
|
+
es: 'Número de dispositivos con batería baja',
|
|
1737
|
+
pl: 'Liczba urządzeń z niską baterią',
|
|
1738
|
+
'zh-cn': '低电池的装置数量',
|
|
1627
1739
|
},
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1740
|
+
type: 'number',
|
|
1741
|
+
role: 'value',
|
|
1742
|
+
read: true,
|
|
1743
|
+
write: false,
|
|
1632
1744
|
},
|
|
1633
|
-
|
|
1745
|
+
native: {},
|
|
1634
1746
|
});
|
|
1635
1747
|
|
|
1636
1748
|
await this.setObjectNotExistsAsync(`${adptName}.batteryCount`, {
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
'zh-cn': '电池的装置数量'
|
|
1749
|
+
type: 'state',
|
|
1750
|
+
common: {
|
|
1751
|
+
name: {
|
|
1752
|
+
en: 'Number of devices with battery',
|
|
1753
|
+
de: 'Anzahl der Geräte mit Batterie',
|
|
1754
|
+
ru: 'Количество устройств c батареей',
|
|
1755
|
+
pt: 'Número de dispositivos com bateria',
|
|
1756
|
+
nl: 'Nummer van apparaten met batterij',
|
|
1757
|
+
fr: 'Nombre de dispositifs avec batterie',
|
|
1758
|
+
it: 'Numero di dispositivi con batteria',
|
|
1759
|
+
es: 'Número de dispositivos con batería',
|
|
1760
|
+
pl: 'Liczba urządzeń z baterią',
|
|
1761
|
+
'zh-cn': '电池的装置数量',
|
|
1650
1762
|
},
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1763
|
+
type: 'number',
|
|
1764
|
+
role: 'value',
|
|
1765
|
+
read: true,
|
|
1766
|
+
write: false,
|
|
1655
1767
|
},
|
|
1656
|
-
|
|
1768
|
+
native: {},
|
|
1657
1769
|
});
|
|
1658
1770
|
}
|
|
1659
1771
|
|
|
@@ -1661,7 +1773,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1661
1773
|
* @param {object} [adptName] - Adaptername of devices
|
|
1662
1774
|
**/
|
|
1663
1775
|
async createHtmlListDatapoints(adptName) {
|
|
1664
|
-
|
|
1665
1776
|
let dpSubFolder;
|
|
1666
1777
|
//write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
|
|
1667
1778
|
if (adptName) {
|
|
@@ -1671,95 +1782,95 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1671
1782
|
}
|
|
1672
1783
|
|
|
1673
1784
|
await this.setObjectNotExistsAsync(`${dpSubFolder}offlineListHTML`, {
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
'zh-cn': 'HTML 线装置清单'
|
|
1785
|
+
type: 'state',
|
|
1786
|
+
common: {
|
|
1787
|
+
name: {
|
|
1788
|
+
en: 'HTML List of offline devices',
|
|
1789
|
+
de: 'HTML Liste der Offline-Geräte',
|
|
1790
|
+
ru: 'HTML Список оффлайн устройств',
|
|
1791
|
+
pt: 'HTML Lista de dispositivos off-line',
|
|
1792
|
+
nl: 'HTML List van offline apparatuur',
|
|
1793
|
+
fr: 'HTML Liste des dispositifs hors ligne',
|
|
1794
|
+
it: 'HTML Elenco dei dispositivi offline',
|
|
1795
|
+
es: 'HTML Lista de dispositivos sin conexión',
|
|
1796
|
+
pl: 'HTML Lista urządzeń offline',
|
|
1797
|
+
'zh-cn': 'HTML 线装置清单',
|
|
1687
1798
|
},
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1799
|
+
type: 'string',
|
|
1800
|
+
role: 'html',
|
|
1801
|
+
read: true,
|
|
1802
|
+
write: false,
|
|
1692
1803
|
},
|
|
1693
|
-
|
|
1804
|
+
native: {},
|
|
1694
1805
|
});
|
|
1695
1806
|
|
|
1696
1807
|
await this.setObjectNotExistsAsync(`${dpSubFolder}linkQualityListHTML`, {
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
'zh-cn': 'HTML 具有信号实力的装置清单'
|
|
1808
|
+
type: 'state',
|
|
1809
|
+
common: {
|
|
1810
|
+
name: {
|
|
1811
|
+
en: 'HTML List of devices with signal strength',
|
|
1812
|
+
de: 'HTML Liste der Geräte mit Signalstärke',
|
|
1813
|
+
ru: 'HTML Список устройств с силой сигнала',
|
|
1814
|
+
pt: 'HTML Lista de dispositivos com força de sinal',
|
|
1815
|
+
nl: 'HTML List van apparaten met signaalkracht',
|
|
1816
|
+
fr: 'HTML Liste des dispositifs avec force de signal',
|
|
1817
|
+
it: 'HTML Elenco dei dispositivi con forza del segnale',
|
|
1818
|
+
es: 'HTML Lista de dispositivos con fuerza de señal',
|
|
1819
|
+
pl: 'HTML Lista urządzeń z siłą sygnałową',
|
|
1820
|
+
'zh-cn': 'HTML 具有信号实力的装置清单',
|
|
1710
1821
|
},
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1822
|
+
type: 'string',
|
|
1823
|
+
role: 'value',
|
|
1824
|
+
read: true,
|
|
1825
|
+
write: false,
|
|
1715
1826
|
},
|
|
1716
|
-
|
|
1827
|
+
native: {},
|
|
1717
1828
|
});
|
|
1718
1829
|
|
|
1719
1830
|
await this.setObjectNotExistsAsync(`${dpSubFolder}batteryListHTML`, {
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
'zh-cn': 'HTML 电池国装置清单'
|
|
1831
|
+
type: 'state',
|
|
1832
|
+
common: {
|
|
1833
|
+
name: {
|
|
1834
|
+
en: 'HTML List of devices with battery state',
|
|
1835
|
+
de: 'HTML Liste der Geräte mit Batteriezustand',
|
|
1836
|
+
ru: 'HTML Список устройств с состоянием батареи',
|
|
1837
|
+
pt: 'HTML Lista de dispositivos com estado da bateria',
|
|
1838
|
+
nl: 'HTML List van apparaten met batterij staat',
|
|
1839
|
+
fr: 'HTML Liste des appareils avec état de batterie',
|
|
1840
|
+
it: 'HTML Elenco dei dispositivi con stato della batteria',
|
|
1841
|
+
es: 'HTML Lista de dispositivos con estado de batería',
|
|
1842
|
+
pl: 'HTML Lista urządzeń z baterią stanową',
|
|
1843
|
+
'zh-cn': 'HTML 电池国装置清单',
|
|
1733
1844
|
},
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1845
|
+
type: 'string',
|
|
1846
|
+
role: 'html',
|
|
1847
|
+
read: true,
|
|
1848
|
+
write: false,
|
|
1738
1849
|
},
|
|
1739
|
-
|
|
1850
|
+
native: {},
|
|
1740
1851
|
});
|
|
1741
1852
|
|
|
1742
1853
|
await this.setObjectNotExistsAsync(`${dpSubFolder}lowBatteryListHTML`, {
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
'zh-cn': 'HTML 低电池国家装置清单'
|
|
1854
|
+
type: 'state',
|
|
1855
|
+
common: {
|
|
1856
|
+
name: {
|
|
1857
|
+
en: 'HTML List of devices with low battery state',
|
|
1858
|
+
de: 'HTML Liste der Geräte mit niedrigem Batteriezustand',
|
|
1859
|
+
ru: 'HTML Список устройств с низким состоянием батареи',
|
|
1860
|
+
pt: 'HTML Lista de dispositivos com baixo estado da bateria',
|
|
1861
|
+
nl: 'HTML List van apparaten met lage batterij staat',
|
|
1862
|
+
fr: 'HTML Liste des appareils à faible état de batterie',
|
|
1863
|
+
it: 'HTML Elenco di dispositivi con stato di batteria basso',
|
|
1864
|
+
es: 'HTML Lista de dispositivos con estado de batería bajo',
|
|
1865
|
+
pl: 'HTML Lista urządzeń o niskim stanie baterii',
|
|
1866
|
+
'zh-cn': 'HTML 低电池国家装置清单',
|
|
1756
1867
|
},
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1868
|
+
type: 'string',
|
|
1869
|
+
role: 'html',
|
|
1870
|
+
read: true,
|
|
1871
|
+
write: false,
|
|
1761
1872
|
},
|
|
1762
|
-
|
|
1873
|
+
native: {},
|
|
1763
1874
|
});
|
|
1764
1875
|
}
|
|
1765
1876
|
|
|
@@ -1782,10 +1893,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1782
1893
|
}
|
|
1783
1894
|
} // <-- end of errorReporting
|
|
1784
1895
|
|
|
1785
|
-
|
|
1786
1896
|
/**
|
|
1787
|
-
|
|
1788
|
-
|
|
1897
|
+
* @param {() => void} callback
|
|
1898
|
+
*/
|
|
1789
1899
|
onUnload(callback) {
|
|
1790
1900
|
try {
|
|
1791
1901
|
if (this.refreshDataTimeout) {
|