iobroker.device-watcher 1.0.0 → 1.1.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 +32 -3
- package/admin/i18n/de/translations.json +6 -1
- package/admin/i18n/en/translations.json +5 -1
- package/admin/i18n/es/translations.json +6 -1
- package/admin/i18n/fr/translations.json +6 -1
- package/admin/i18n/it/translations.json +6 -1
- package/admin/i18n/nl/translations.json +6 -1
- package/admin/i18n/pl/translations.json +6 -1
- package/admin/i18n/pt/translations.json +6 -1
- package/admin/i18n/ru/translations.json +6 -1
- package/admin/i18n/zh-cn/translations.json +6 -1
- package/admin/jsonConfig.json +339 -20
- package/io-package.json +519 -626
- package/main.js +1405 -1010
- package/package.json +11 -7
package/main.js
CHANGED
|
@@ -6,10 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
const utils = require('@iobroker/adapter-core');
|
|
8
8
|
const adapterName = require('./package.json').name.split('.').pop();
|
|
9
|
+
const schedule = require('node-schedule');
|
|
9
10
|
|
|
10
11
|
// Sentry error reporting, disable when testing code!
|
|
11
12
|
const enableSendSentry = true;
|
|
12
13
|
|
|
14
|
+
let isUnloaded = false;
|
|
15
|
+
|
|
13
16
|
class DeviceWatcher extends utils.Adapter {
|
|
14
17
|
|
|
15
18
|
constructor(options) {
|
|
@@ -41,6 +44,19 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
41
44
|
// Interval timer
|
|
42
45
|
this.refreshDataTimeout = null;
|
|
43
46
|
|
|
47
|
+
this.devices = new Map();
|
|
48
|
+
|
|
49
|
+
// Information for dev: add ' 0_userdata.0. ' to selector for testing with own datapoints.
|
|
50
|
+
/*
|
|
51
|
+
This is the main template:
|
|
52
|
+
'Selektor': '',
|
|
53
|
+
'adapter': '',
|
|
54
|
+
'battery': 'none',
|
|
55
|
+
'reach': 'none',
|
|
56
|
+
'isLowBat': 'none',
|
|
57
|
+
'id': 'none''
|
|
58
|
+
*/
|
|
59
|
+
|
|
44
60
|
// arrays of supported adapters
|
|
45
61
|
this.arrApart = {
|
|
46
62
|
alexa2: {
|
|
@@ -93,6 +109,22 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
93
109
|
'reach': '.hubConnected',
|
|
94
110
|
'isLowBat': 'none'
|
|
95
111
|
},
|
|
112
|
+
ham: {
|
|
113
|
+
'Selektor': 'ham.*.Battery-Level',
|
|
114
|
+
'adapter': 'ham',
|
|
115
|
+
'battery': '.Battery-Level',
|
|
116
|
+
'reach': 'none',
|
|
117
|
+
'isLowBat': 'none',
|
|
118
|
+
'id': '.Name'
|
|
119
|
+
},
|
|
120
|
+
hmiP: {
|
|
121
|
+
'Selektor': 'hmip.*.rssiDeviceValue',
|
|
122
|
+
'adapter': 'hmiP',
|
|
123
|
+
'rssiState': '.rssiDeviceValue',
|
|
124
|
+
'battery': 'none',
|
|
125
|
+
'reach': '.unreach',
|
|
126
|
+
'isLowBat': '.lowBat',
|
|
127
|
+
},
|
|
96
128
|
homematic: {
|
|
97
129
|
'Selektor': 'hm-rpc.*.UNREACH',
|
|
98
130
|
'adapter': 'homematic',
|
|
@@ -100,7 +132,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
100
132
|
'battery': '.OPERATING_VOLTAGE',
|
|
101
133
|
'reach': '.UNREACH',
|
|
102
134
|
'isLowBat': '.LOW_BAT',
|
|
103
|
-
'isLowBat2': '.LOWBAT'
|
|
135
|
+
'isLowBat2': '.LOWBAT',
|
|
136
|
+
'stateValue': '.1.STATE'
|
|
104
137
|
},
|
|
105
138
|
hue: {
|
|
106
139
|
'Selektor': 'hue.*.reachable',
|
|
@@ -123,6 +156,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
123
156
|
'reach': 'none',
|
|
124
157
|
'isLowBat': '.lowBatt'
|
|
125
158
|
},
|
|
159
|
+
meross: {
|
|
160
|
+
'Selektor': 'meross.*.online',
|
|
161
|
+
'adapter': 'meross',
|
|
162
|
+
'battery': '.battery',
|
|
163
|
+
'reach': '.online',
|
|
164
|
+
'isLowBat': 'none'
|
|
165
|
+
},
|
|
126
166
|
mihome: {
|
|
127
167
|
'Selektor': 'mihome.*.percent',
|
|
128
168
|
'adapter': 'miHome',
|
|
@@ -147,6 +187,15 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
147
187
|
'isLowBat': 'none',
|
|
148
188
|
'id': '.deviceInfo.model'
|
|
149
189
|
},
|
|
190
|
+
netatmo: {
|
|
191
|
+
'Selektor': 'netatmo.*.LastUpdate',
|
|
192
|
+
'adapter': 'netatmo',
|
|
193
|
+
'rssiState': '.WifiStatus',
|
|
194
|
+
'rfState': '.RfStatus',
|
|
195
|
+
'battery': '.BatteryStatus',
|
|
196
|
+
'reach': 'none',
|
|
197
|
+
'isLowBat': 'none'
|
|
198
|
+
},
|
|
150
199
|
nukiExt: {
|
|
151
200
|
'Selektor': 'nuki-extended.*.lastDataUpdate',
|
|
152
201
|
'adapter': 'nuki-extended',
|
|
@@ -155,6 +204,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
155
204
|
'reach': 'none',
|
|
156
205
|
'isLowBat': '.batteryCritical'
|
|
157
206
|
},
|
|
207
|
+
nut: {
|
|
208
|
+
'Selektor': 'nut.*.charge',
|
|
209
|
+
'adapter': 'nut',
|
|
210
|
+
'battery': '.charge',
|
|
211
|
+
'reach': 'none',
|
|
212
|
+
'isLowBat': 'none'
|
|
213
|
+
},
|
|
158
214
|
ping: {
|
|
159
215
|
'Selektor': 'ping.*.alive',
|
|
160
216
|
'adapter': 'ping',
|
|
@@ -162,15 +218,24 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
162
218
|
'reach': '.alive',
|
|
163
219
|
'isLowBat': 'none'
|
|
164
220
|
},
|
|
221
|
+
roomba: {
|
|
222
|
+
'Selektor': 'roomba.*.signal',
|
|
223
|
+
'adapter': 'roomba',
|
|
224
|
+
'battery': '.battery',
|
|
225
|
+
'reach': '._connected',
|
|
226
|
+
'isLowBat': 'none',
|
|
227
|
+
'id': '.device.name'
|
|
228
|
+
},
|
|
165
229
|
shelly: {
|
|
166
|
-
'Selektor': 'shelly.*.
|
|
230
|
+
'Selektor': 'shelly.*.uptime',
|
|
167
231
|
'adapter': 'shelly',
|
|
232
|
+
'rssiState': '.rssi',
|
|
168
233
|
'battery': '.sensor.battery',
|
|
169
234
|
'reach': '.online',
|
|
170
235
|
'isLowBat': 'none'
|
|
171
236
|
},
|
|
172
237
|
sonoff: {
|
|
173
|
-
'Selektor': 'sonoff.*.
|
|
238
|
+
'Selektor': 'sonoff.*.alive',
|
|
174
239
|
'adapter': 'sonoff',
|
|
175
240
|
'rssiState': '.Wifi_Signal',
|
|
176
241
|
'battery': '.battery',
|
|
@@ -192,6 +257,48 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
192
257
|
'isLowBat': 'none',
|
|
193
258
|
'id': '.id'
|
|
194
259
|
},
|
|
260
|
+
tado: {
|
|
261
|
+
'Selektor': 'tado.*.batteryState',
|
|
262
|
+
'adapter': 'tado',
|
|
263
|
+
'rssiState': 'none',
|
|
264
|
+
'battery': 'none',
|
|
265
|
+
'reach': '.connectionState.value',
|
|
266
|
+
'isLowBat': '.batteryState',
|
|
267
|
+
'id': 'none'
|
|
268
|
+
},
|
|
269
|
+
tradfri: {
|
|
270
|
+
'Selektor': 'tradfri.*.lastSeen',
|
|
271
|
+
'adapter': 'tradfri',
|
|
272
|
+
'rssiState': 'none',
|
|
273
|
+
'battery': '.batteryPercentage',
|
|
274
|
+
'reach': '.alive',
|
|
275
|
+
'isLowBat': 'none',
|
|
276
|
+
'id': 'none'
|
|
277
|
+
},
|
|
278
|
+
unifi: {
|
|
279
|
+
'Selektor': 'unifi.*.state',
|
|
280
|
+
'adapter': 'unifi',
|
|
281
|
+
'battery': 'none',
|
|
282
|
+
'reach': '.state',
|
|
283
|
+
'isLowBat': 'none',
|
|
284
|
+
'id': 'none'
|
|
285
|
+
},
|
|
286
|
+
wled: {
|
|
287
|
+
'Selektor': 'wled.*._online',
|
|
288
|
+
'adapter': 'wled',
|
|
289
|
+
'rssiState': '.wifi.rssi',
|
|
290
|
+
'battery': 'none',
|
|
291
|
+
'reach': '._online',
|
|
292
|
+
'isLowBat': 'none',
|
|
293
|
+
'id': 'none'
|
|
294
|
+
},
|
|
295
|
+
yeelight: {
|
|
296
|
+
'Selektor': 'yeelight-2.*.connect',
|
|
297
|
+
'adapter': 'yeelight-2',
|
|
298
|
+
'battery': 'none',
|
|
299
|
+
'reach': '.connect',
|
|
300
|
+
'isLowBat': 'none'
|
|
301
|
+
},
|
|
195
302
|
zigbee: {
|
|
196
303
|
'Selektor': 'zigbee.*.link_quality',
|
|
197
304
|
'adapter': 'zigbee',
|
|
@@ -199,21 +306,19 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
199
306
|
'reach': '.available',
|
|
200
307
|
'isLowBat': '.battery_low'
|
|
201
308
|
},
|
|
309
|
+
zigbee2mqtt: {
|
|
310
|
+
'Selektor': 'zigbee2mqtt.*.link_quality',
|
|
311
|
+
'adapter': 'zigbee2MQTT',
|
|
312
|
+
'battery': '.battery',
|
|
313
|
+
'reach': '.available',
|
|
314
|
+
'isLowBat': '.battery_low'
|
|
315
|
+
},
|
|
202
316
|
zwave: {
|
|
203
317
|
'Selektor': 'zwave2.*.ready',
|
|
204
318
|
'adapter': 'zwave',
|
|
205
319
|
'battery': '.Battery.level',
|
|
206
320
|
'reach': '.ready',
|
|
207
321
|
'isLowBat': '.Battery.isLow'
|
|
208
|
-
},
|
|
209
|
-
test: { // Only for Dev
|
|
210
|
-
'Selektor': '0_userdata.*.UNREACH',
|
|
211
|
-
'adapter': 'homematic',
|
|
212
|
-
'rssiState': '.RSSI_DEVICE',
|
|
213
|
-
'battery': '.OPERATING_VOLTAGE',
|
|
214
|
-
'reach': '.UNREACH',
|
|
215
|
-
'isLowBat': '.LOW_BAT',
|
|
216
|
-
'isLowBat2': '.LOWBAT'
|
|
217
322
|
}
|
|
218
323
|
};
|
|
219
324
|
|
|
@@ -228,6 +333,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
228
333
|
async onReady() {
|
|
229
334
|
this.log.debug(`Adapter ${adapterName} was started`);
|
|
230
335
|
|
|
336
|
+
isUnloaded = false;
|
|
337
|
+
|
|
231
338
|
try {
|
|
232
339
|
this.supAdapter = {
|
|
233
340
|
alexa2: this.config.alexa2Devices,
|
|
@@ -236,29 +343,44 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
236
343
|
enocean: this.config.enoceanDevices,
|
|
237
344
|
esphome: this.config.esphomeDevices,
|
|
238
345
|
fritzdect: this.config.fritzdectDevices,
|
|
346
|
+
ham: this.config.hamDevices,
|
|
239
347
|
harmony: this.config.harmonyDevices,
|
|
348
|
+
hmiP : this.config.hmiPDevices,
|
|
240
349
|
homematic: this.config.homematicDevices,
|
|
241
350
|
hue: this.config.hueDevices,
|
|
242
351
|
hueExt: this.config.hueExtDevices,
|
|
243
352
|
jeelink: this.config.jeelinkDevices,
|
|
353
|
+
meross: this.config.merossDevices,
|
|
244
354
|
mihome: this.config.mihomeDevices,
|
|
245
355
|
mihomeGW: this.config.mihomeDevices,
|
|
246
356
|
mihomeVacuum: this.config.mihomeVacuumDevices,
|
|
357
|
+
netatmo: this.config.netatmoDevices,
|
|
247
358
|
nukiExt: this.config.nukiExtDevices,
|
|
359
|
+
nut: this.config.nutDevices,
|
|
248
360
|
ping: this.config.pingDevices,
|
|
361
|
+
roomba: this.config.roombaDevices,
|
|
249
362
|
shelly: this.config.shellyDevices,
|
|
250
363
|
sonoff: this.config.sonoffDevices,
|
|
251
364
|
sonos: this.config.sonosDevices,
|
|
252
365
|
switchbotBle: this.config.switchbotBleDevices,
|
|
366
|
+
tado: this.config.tadoDevices,
|
|
367
|
+
tradfri: this.config.tradfriDevices,
|
|
368
|
+
unifi: this.config.unifiDevices,
|
|
369
|
+
wled: this.config.wledDevices,
|
|
370
|
+
yeelight: this.config.yeelightDevices,
|
|
253
371
|
zigbee: this.config.zigbeeDevices,
|
|
372
|
+
zigbee2mqtt: this.config.zigbee2mqttDevices,
|
|
254
373
|
zwave: this.config.zwaveDevices,
|
|
255
|
-
test: false // Only for Dev
|
|
256
374
|
};
|
|
257
375
|
|
|
258
376
|
for (const [id] of Object.entries(this.arrApart)) {
|
|
259
|
-
if (
|
|
260
|
-
|
|
261
|
-
|
|
377
|
+
if (!isUnloaded) {
|
|
378
|
+
if (this.supAdapter[id]) {
|
|
379
|
+
this.arrDev.push(this.arrApart[id]);
|
|
380
|
+
this.adapterSelected.push(await this.capitalize(id));
|
|
381
|
+
}
|
|
382
|
+
} else {
|
|
383
|
+
return; // cancel run if unloaded was called.
|
|
262
384
|
}
|
|
263
385
|
}
|
|
264
386
|
|
|
@@ -280,17 +402,51 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
280
402
|
this.errorReporting('[onReady - create blacklist]', error);
|
|
281
403
|
}
|
|
282
404
|
|
|
283
|
-
//
|
|
284
|
-
|
|
405
|
+
//create and fill datapoints for each adapter if selected
|
|
406
|
+
try {
|
|
407
|
+
for (const [id] of Object.entries(this.arrApart)) {
|
|
408
|
+
if (!isUnloaded) {
|
|
409
|
+
if ((this.supAdapter !== undefined) && (this.supAdapter[id])) {
|
|
410
|
+
|
|
411
|
+
if (this.config.createOwnFolder) {
|
|
412
|
+
await this.createDPsForEachAdapter(id);
|
|
413
|
+
if (this.config.createHtmlList) await this.createHtmlListDatapoints(id);
|
|
414
|
+
this.log.debug(`Created datapoints for ${await this.capitalize(id)}`);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
} else {
|
|
418
|
+
return; // cancel run if unloaded was called.
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
} catch (error) {
|
|
422
|
+
this.errorReporting('[onReady - create and fill datapoints for each adapter]', error);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// create HTML list
|
|
426
|
+
if (this.config.createHtmlList) await this.createHtmlListDatapoints();
|
|
285
427
|
|
|
286
428
|
// update data in interval
|
|
287
429
|
await this.refreshData();
|
|
288
430
|
|
|
431
|
+
// send overview for low battery devices
|
|
432
|
+
if (this.config.checkSendBatteryMsg) await this.sendBatteryNotifyShedule();
|
|
433
|
+
|
|
434
|
+
// send overview of offline devices
|
|
435
|
+
if (this.config.checkSendOfflineMsgDaily) await this.sendOfflineNotificationsShedule();
|
|
436
|
+
|
|
289
437
|
} catch (error) {
|
|
290
438
|
this.errorReporting('[onReady]', error);
|
|
291
439
|
this.terminate ? this.terminate(15) : process.exit(15);
|
|
292
440
|
}
|
|
293
|
-
|
|
441
|
+
|
|
442
|
+
/*
|
|
443
|
+
this.devices.forEach((value, key) => {
|
|
444
|
+
this.log.warn(`${key}: ${value}`);
|
|
445
|
+
this.subscribeStates(value);
|
|
446
|
+
this.onStateChange(key, value);
|
|
447
|
+
});
|
|
448
|
+
*/
|
|
449
|
+
} // <-- onReady end
|
|
294
450
|
|
|
295
451
|
/**
|
|
296
452
|
* Is called if a subscribed state changes
|
|
@@ -300,11 +456,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
300
456
|
async onStateChange(id, state) {
|
|
301
457
|
if (state) {
|
|
302
458
|
// The state was changed
|
|
303
|
-
this.log.
|
|
304
|
-
await this.main();
|
|
459
|
+
this.log.warn(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
|
|
460
|
+
// await this.main();
|
|
305
461
|
} else {
|
|
306
462
|
// The state was deleted
|
|
307
|
-
this.log.
|
|
463
|
+
this.log.warn(`state ${id} deleted`);
|
|
308
464
|
}
|
|
309
465
|
}
|
|
310
466
|
|
|
@@ -319,40 +475,46 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
319
475
|
this.clearTimeout(this.refreshDataTimeout);
|
|
320
476
|
}
|
|
321
477
|
|
|
322
|
-
|
|
323
|
-
this.
|
|
478
|
+
if (!isUnloaded) {
|
|
479
|
+
this.refreshDataTimeout = this.setTimeout(() => {
|
|
480
|
+
this.log.debug('Updating Data');
|
|
324
481
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
482
|
+
this.refreshDataTimeout = null;
|
|
483
|
+
this.refreshData();
|
|
484
|
+
}, nextTimeout);
|
|
485
|
+
} else {
|
|
486
|
+
return; // cancel run if unloaded was called.
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
} // <-- refreshData end
|
|
329
490
|
|
|
330
491
|
async main() {
|
|
331
492
|
this.log.debug(`Function started: ${this.main.name}`);
|
|
332
493
|
|
|
333
494
|
try {
|
|
334
495
|
|
|
335
|
-
//
|
|
496
|
+
// fill datapoints for each adapter if selected
|
|
336
497
|
try {
|
|
337
498
|
for (const [id] of Object.entries(this.arrApart)) {
|
|
338
|
-
if (
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
await this.createDataForEachAdapter(id);
|
|
345
|
-
this.log.debug(`Created and filled data for each adapter`);
|
|
499
|
+
if (!isUnloaded) {
|
|
500
|
+
if ((this.supAdapter !== undefined) && (this.supAdapter[id])) {
|
|
501
|
+
if (this.config.createOwnFolder) {
|
|
502
|
+
await this.createDataForEachAdapter(id);
|
|
503
|
+
this.log.debug(`Created and filled data for each adapter`);
|
|
504
|
+
}
|
|
346
505
|
}
|
|
506
|
+
} else {
|
|
507
|
+
this.log.warn('broke up');
|
|
508
|
+
return; // cancel run if unloaded was called.
|
|
347
509
|
}
|
|
348
510
|
}
|
|
511
|
+
|
|
349
512
|
} catch (error) {
|
|
350
513
|
this.errorReporting('[main - create and fill datapoints for each adapter]', error);
|
|
351
514
|
}
|
|
352
515
|
|
|
353
|
-
//
|
|
516
|
+
// fill counts and lists of all selected adapter
|
|
354
517
|
try {
|
|
355
|
-
if (this.config.createHtmlList) await this.createHtmlListDatapoints();
|
|
356
518
|
await this.createDataOfAllAdapter();
|
|
357
519
|
this.log.debug(`Created and filled data for all adapters`);
|
|
358
520
|
} catch (error) {
|
|
@@ -393,428 +555,182 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
393
555
|
if (stateVal) return stateVal.val;
|
|
394
556
|
}
|
|
395
557
|
|
|
396
|
-
|
|
558
|
+
async createBlacklist() {
|
|
559
|
+
this.log.debug(`Function started: ${this.createBlacklist.name}`);
|
|
560
|
+
|
|
561
|
+
const myBlacklist = this.config.tableBlacklist;
|
|
562
|
+
|
|
563
|
+
for (const i in myBlacklist) {
|
|
564
|
+
if (!isUnloaded) {
|
|
565
|
+
this.blacklistArr.push(myBlacklist[i].device);
|
|
566
|
+
} else {
|
|
567
|
+
return; // cancel run if unloaded was called.
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
this.log.info(`Found items on the blacklist: ${this.blacklistArr}`);
|
|
571
|
+
this.log.debug(`Function finished: ${this.createBlacklist.name}`);
|
|
572
|
+
}
|
|
573
|
+
|
|
397
574
|
/**
|
|
398
|
-
* @param {object}
|
|
575
|
+
* @param {object} i - Device Object
|
|
399
576
|
**/
|
|
400
|
-
async
|
|
577
|
+
async createData(i) {
|
|
578
|
+
const devices = await this.getForeignStatesAsync(this.arrDev[i].Selektor);
|
|
579
|
+
const deviceAdapterName = await this.capitalize(this.arrDev[i].adapter);
|
|
401
580
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
},
|
|
407
|
-
native: {},
|
|
408
|
-
});
|
|
581
|
+
/*---------- Start of second main loop ----------*/
|
|
582
|
+
for (const [id] of Object.entries(devices)) {
|
|
583
|
+
if (!isUnloaded) {
|
|
584
|
+
if (!this.blacklistArr.includes(id)) {
|
|
409
585
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
'name': {
|
|
414
|
-
'en': 'Number of devices offline',
|
|
415
|
-
'de': 'Anzahl der Geräte offline',
|
|
416
|
-
'ru': 'Количество устройств offline',
|
|
417
|
-
'pt': 'Número de dispositivos offline',
|
|
418
|
-
'nl': 'Nummer van apparatuur offline',
|
|
419
|
-
'fr': 'Nombre de dispositifs hors ligne',
|
|
420
|
-
'it': 'Numero di dispositivi offline',
|
|
421
|
-
'es': 'Número de dispositivos sin conexión',
|
|
422
|
-
'pl': 'Ilość urządzeń offline',
|
|
423
|
-
'zh-cn': '线内装置数量'
|
|
424
|
-
},
|
|
425
|
-
'type': 'number',
|
|
426
|
-
'role': 'value',
|
|
427
|
-
'read': true,
|
|
428
|
-
'write': false,
|
|
429
|
-
},
|
|
430
|
-
'native': {}
|
|
431
|
-
});
|
|
586
|
+
const currDeviceString = id.slice(0, (id.lastIndexOf('.') + 1) - 1);
|
|
587
|
+
const shortCurrDeviceString = currDeviceString.slice(0, (currDeviceString.lastIndexOf('.') + 1) - 1);
|
|
588
|
+
const shortshortCurrDeviceString = shortCurrDeviceString.slice(0, (shortCurrDeviceString.lastIndexOf('.') + 1) - 1);
|
|
432
589
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
'de': 'Liste der Offline-Geräte',
|
|
439
|
-
'ru': 'Список оффлайн устройств',
|
|
440
|
-
'pt': 'Lista de dispositivos off-line',
|
|
441
|
-
'nl': 'List van offline apparatuur',
|
|
442
|
-
'fr': 'Liste des dispositifs hors ligne',
|
|
443
|
-
'it': 'Elenco dei dispositivi offline',
|
|
444
|
-
'es': 'Lista de dispositivos sin conexión',
|
|
445
|
-
'pl': 'Lista urządzeń offline',
|
|
446
|
-
'zh-cn': '线装置清单'
|
|
447
|
-
},
|
|
448
|
-
'type': 'array',
|
|
449
|
-
'role': 'json',
|
|
450
|
-
'read': true,
|
|
451
|
-
'write': false,
|
|
452
|
-
},
|
|
453
|
-
'native': {}
|
|
454
|
-
});
|
|
590
|
+
// Get device name
|
|
591
|
+
const deviceObject = await this.getForeignObjectAsync(currDeviceString);
|
|
592
|
+
const shortDeviceObject = await this.getForeignObjectAsync(shortCurrDeviceString);
|
|
593
|
+
const shortshortDeviceObject = await this.getForeignObjectAsync(shortshortCurrDeviceString);
|
|
594
|
+
let deviceName;
|
|
455
595
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
'ru': 'Список всех устройств',
|
|
463
|
-
'pt': 'Lista de todos os dispositivos',
|
|
464
|
-
'nl': 'List van alle apparaten',
|
|
465
|
-
'fr': 'Liste de tous les dispositifs',
|
|
466
|
-
'it': 'Elenco di tutti i dispositivi',
|
|
467
|
-
'es': 'Lista de todos los dispositivos',
|
|
468
|
-
'pl': 'Lista wszystkich urządzeń',
|
|
469
|
-
'zh-cn': '所有装置清单'
|
|
470
|
-
},
|
|
471
|
-
'type': 'array',
|
|
472
|
-
'role': 'json',
|
|
473
|
-
'read': true,
|
|
474
|
-
'write': false,
|
|
475
|
-
},
|
|
476
|
-
'native': {}
|
|
477
|
-
});
|
|
596
|
+
// Get ID with currDeviceString from datapoint
|
|
597
|
+
switch (this.arrDev[i].adapter) {
|
|
598
|
+
case 'switchbotBle': // Get ID for Switchbot and ESPHome Devices
|
|
599
|
+
case 'esphome':
|
|
600
|
+
deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
|
|
601
|
+
break;
|
|
478
602
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
'fr': 'Liste des dispositifs avec force de signal',
|
|
489
|
-
'it': 'Elenco dei dispositivi con forza del segnale',
|
|
490
|
-
'es': 'Lista de dispositivos con fuerza de señal',
|
|
491
|
-
'pl': 'Lista urządzeń z siłą sygnałową',
|
|
492
|
-
'zh-cn': '具有信号实力的装置清单'
|
|
493
|
-
},
|
|
494
|
-
'type': 'array',
|
|
495
|
-
'role': 'json',
|
|
496
|
-
'read': true,
|
|
497
|
-
'write': false,
|
|
498
|
-
},
|
|
499
|
-
'native': {}
|
|
500
|
-
});
|
|
603
|
+
// Get ID with short currDeviceString from objectjson
|
|
604
|
+
case 'hue-extended':
|
|
605
|
+
case 'homematic':
|
|
606
|
+
case 'nuki-extended':
|
|
607
|
+
case 'wled':
|
|
608
|
+
if (shortDeviceObject && typeof shortDeviceObject === 'object') {
|
|
609
|
+
deviceName = shortDeviceObject.common.name;
|
|
610
|
+
}
|
|
611
|
+
break;
|
|
501
612
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
'ru': 'Количество всех устройств',
|
|
509
|
-
'pt': 'Número de todos os dispositivos',
|
|
510
|
-
'nl': 'Nummer van alle apparaten',
|
|
511
|
-
'fr': 'Nombre de tous les appareils',
|
|
512
|
-
'it': 'Numero di tutti i dispositivi',
|
|
513
|
-
'es': 'Número de todos los dispositivos',
|
|
514
|
-
'pl': 'Ilość wszystkich urządzeń',
|
|
515
|
-
'zh-cn': '所有装置的数目'
|
|
516
|
-
},
|
|
517
|
-
'type': 'number',
|
|
518
|
-
'role': 'value',
|
|
519
|
-
'read': true,
|
|
520
|
-
'write': false,
|
|
521
|
-
},
|
|
522
|
-
'native': {}
|
|
523
|
-
});
|
|
613
|
+
// Get ID with short short currDeviceString vom objectjson
|
|
614
|
+
case 'hmiP':
|
|
615
|
+
if (shortshortDeviceObject && typeof shortshortDeviceObject === 'object') {
|
|
616
|
+
deviceName = shortshortDeviceObject.common.name;
|
|
617
|
+
}
|
|
618
|
+
break;
|
|
524
619
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
'de': 'Liste der Geräte mit Batteriezustand',
|
|
531
|
-
'ru': 'Список устройств с состоянием батареи',
|
|
532
|
-
'pt': 'Lista de dispositivos com estado da bateria',
|
|
533
|
-
'nl': 'List van apparaten met batterij staat',
|
|
534
|
-
'fr': 'Liste des appareils avec état de batterie',
|
|
535
|
-
'it': 'Elenco dei dispositivi con stato della batteria',
|
|
536
|
-
'es': 'Lista de dispositivos con estado de batería',
|
|
537
|
-
'pl': 'Lista urządzeń z baterią stanową',
|
|
538
|
-
'zh-cn': '电池国装置清单'
|
|
539
|
-
},
|
|
540
|
-
'type': 'array',
|
|
541
|
-
'role': 'json',
|
|
542
|
-
'read': true,
|
|
543
|
-
'write': false,
|
|
544
|
-
},
|
|
545
|
-
'native': {}
|
|
546
|
-
});
|
|
620
|
+
// Get ID with short currDeviceString from datapoint
|
|
621
|
+
case 'mihomeVacuum':
|
|
622
|
+
case 'roomba':
|
|
623
|
+
deviceName = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].id);
|
|
624
|
+
break;
|
|
547
625
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
'en': 'List of devices with low battery state',
|
|
553
|
-
'de': 'Liste der Geräte mit niedrigem Batteriezustand',
|
|
554
|
-
'ru': 'Список устройств с низким состоянием батареи',
|
|
555
|
-
'pt': 'Lista de dispositivos com baixo estado da bateria',
|
|
556
|
-
'nl': 'List van apparaten met lage batterij staat',
|
|
557
|
-
'fr': 'Liste des appareils à faible état de batterie',
|
|
558
|
-
'it': 'Elenco di dispositivi con stato di batteria basso',
|
|
559
|
-
'es': 'Lista de dispositivos con estado de batería bajo',
|
|
560
|
-
'pl': 'Lista urządzeń o niskim stanie baterii',
|
|
561
|
-
'zh-cn': '低电池国家装置清单'
|
|
562
|
-
},
|
|
563
|
-
'type': 'array',
|
|
564
|
-
'role': 'json',
|
|
565
|
-
'read': true,
|
|
566
|
-
'write': false,
|
|
567
|
-
},
|
|
568
|
-
'native': {}
|
|
569
|
-
});
|
|
570
|
-
|
|
571
|
-
await this.setObjectNotExistsAsync(`${adptName}.lowBatteryCount`, {
|
|
572
|
-
'type': 'state',
|
|
573
|
-
'common': {
|
|
574
|
-
'name': {
|
|
575
|
-
'en': 'Number of devices with low battery',
|
|
576
|
-
'de': 'Anzahl der Geräte mit niedriger Batterie',
|
|
577
|
-
'ru': 'Количество устройств c низкой батареей',
|
|
578
|
-
'pt': 'Número de dispositivos com bateria baixa',
|
|
579
|
-
'nl': 'Nummer van apparaten met lage batterij',
|
|
580
|
-
'fr': 'Nombre de dispositifs avec batterie basse',
|
|
581
|
-
'it': 'Numero di dispositivi con batteria bassa',
|
|
582
|
-
'es': 'Número de dispositivos con batería baja',
|
|
583
|
-
'pl': 'Liczba urządzeń z niską baterią',
|
|
584
|
-
'zh-cn': '低电池的装置数量'
|
|
585
|
-
},
|
|
586
|
-
'type': 'number',
|
|
587
|
-
'role': 'value',
|
|
588
|
-
'read': true,
|
|
589
|
-
'write': false,
|
|
590
|
-
},
|
|
591
|
-
'native': {}
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
await this.setObjectNotExistsAsync(`${adptName}.batteryCount`, {
|
|
595
|
-
'type': 'state',
|
|
596
|
-
'common': {
|
|
597
|
-
'name': {
|
|
598
|
-
'en': 'Number of devices with battery',
|
|
599
|
-
'de': 'Anzahl der Geräte mit Batterie',
|
|
600
|
-
'ru': 'Количество устройств c батареей',
|
|
601
|
-
'pt': 'Número de dispositivos com bateria',
|
|
602
|
-
'nl': 'Nummer van apparaten met batterij',
|
|
603
|
-
'fr': 'Nombre de dispositifs avec batterie',
|
|
604
|
-
'it': 'Numero di dispositivi con batteria',
|
|
605
|
-
'es': 'Número de dispositivos con batería',
|
|
606
|
-
'pl': 'Liczba urządzeń z baterią',
|
|
607
|
-
'zh-cn': '电池的装置数量'
|
|
608
|
-
},
|
|
609
|
-
'type': 'number',
|
|
610
|
-
'role': 'value',
|
|
611
|
-
'read': true,
|
|
612
|
-
'write': false,
|
|
613
|
-
},
|
|
614
|
-
'native': {}
|
|
615
|
-
});
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
/**
|
|
619
|
-
* @param {object} [adptName] - Adaptername of devices
|
|
620
|
-
**/
|
|
621
|
-
async createHtmlListDatapoints(adptName) {
|
|
622
|
-
|
|
623
|
-
let dpSubFolder;
|
|
624
|
-
//write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
|
|
625
|
-
if (adptName) {
|
|
626
|
-
dpSubFolder = `${adptName}.`;
|
|
627
|
-
} else {
|
|
628
|
-
dpSubFolder = '';
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
await this.setObjectNotExistsAsync(`${dpSubFolder}offlineListHTML`, {
|
|
632
|
-
'type': 'state',
|
|
633
|
-
'common': {
|
|
634
|
-
'name': {
|
|
635
|
-
'en': 'HTML List of offline devices',
|
|
636
|
-
'de': 'HTML Liste der Offline-Geräte',
|
|
637
|
-
'ru': 'HTML Список оффлайн устройств',
|
|
638
|
-
'pt': 'HTML Lista de dispositivos off-line',
|
|
639
|
-
'nl': 'HTML List van offline apparatuur',
|
|
640
|
-
'fr': 'HTML Liste des dispositifs hors ligne',
|
|
641
|
-
'it': 'HTML Elenco dei dispositivi offline',
|
|
642
|
-
'es': 'HTML Lista de dispositivos sin conexión',
|
|
643
|
-
'pl': 'HTML Lista urządzeń offline',
|
|
644
|
-
'zh-cn': 'HTML 线装置清单'
|
|
645
|
-
},
|
|
646
|
-
'type': 'string',
|
|
647
|
-
'role': 'html',
|
|
648
|
-
'read': true,
|
|
649
|
-
'write': false,
|
|
650
|
-
},
|
|
651
|
-
'native': {}
|
|
652
|
-
});
|
|
653
|
-
|
|
654
|
-
await this.setObjectNotExistsAsync(`${dpSubFolder}linkQualityListHTML`, {
|
|
655
|
-
'type': 'state',
|
|
656
|
-
'common': {
|
|
657
|
-
'name': {
|
|
658
|
-
'en': 'HTML List of devices with signal strength',
|
|
659
|
-
'de': 'HTML Liste der Geräte mit Signalstärke',
|
|
660
|
-
'ru': 'HTML Список устройств с силой сигнала',
|
|
661
|
-
'pt': 'HTML Lista de dispositivos com força de sinal',
|
|
662
|
-
'nl': 'HTML List van apparaten met signaalkracht',
|
|
663
|
-
'fr': 'HTML Liste des dispositifs avec force de signal',
|
|
664
|
-
'it': 'HTML Elenco dei dispositivi con forza del segnale',
|
|
665
|
-
'es': 'HTML Lista de dispositivos con fuerza de señal',
|
|
666
|
-
'pl': 'HTML Lista urządzeń z siłą sygnałową',
|
|
667
|
-
'zh-cn': 'HTML 具有信号实力的装置清单'
|
|
668
|
-
},
|
|
669
|
-
'type': 'string',
|
|
670
|
-
'role': 'value',
|
|
671
|
-
'read': true,
|
|
672
|
-
'write': false,
|
|
673
|
-
},
|
|
674
|
-
'native': {}
|
|
675
|
-
});
|
|
676
|
-
|
|
677
|
-
await this.setObjectNotExistsAsync(`${dpSubFolder}batteryListHTML`, {
|
|
678
|
-
'type': 'state',
|
|
679
|
-
'common': {
|
|
680
|
-
'name': {
|
|
681
|
-
'en': 'HTML List of devices with battery state',
|
|
682
|
-
'de': 'HTML Liste der Geräte mit Batteriezustand',
|
|
683
|
-
'ru': 'HTML Список устройств с состоянием батареи',
|
|
684
|
-
'pt': 'HTML Lista de dispositivos com estado da bateria',
|
|
685
|
-
'nl': 'HTML List van apparaten met batterij staat',
|
|
686
|
-
'fr': 'HTML Liste des appareils avec état de batterie',
|
|
687
|
-
'it': 'HTML Elenco dei dispositivi con stato della batteria',
|
|
688
|
-
'es': 'HTML Lista de dispositivos con estado de batería',
|
|
689
|
-
'pl': 'HTML Lista urządzeń z baterią stanową',
|
|
690
|
-
'zh-cn': 'HTML 电池国装置清单'
|
|
691
|
-
},
|
|
692
|
-
'type': 'string',
|
|
693
|
-
'role': 'html',
|
|
694
|
-
'read': true,
|
|
695
|
-
'write': false,
|
|
696
|
-
},
|
|
697
|
-
'native': {}
|
|
698
|
-
});
|
|
626
|
+
//Get ID of foldername
|
|
627
|
+
case 'tado':
|
|
628
|
+
deviceName = currDeviceString.slice(currDeviceString.lastIndexOf('.') + 1);
|
|
629
|
+
break;
|
|
699
630
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
'en': 'HTML List of devices with low battery state',
|
|
705
|
-
'de': 'HTML Liste der Geräte mit niedrigem Batteriezustand',
|
|
706
|
-
'ru': 'HTML Список устройств с низким состоянием батареи',
|
|
707
|
-
'pt': 'HTML Lista de dispositivos com baixo estado da bateria',
|
|
708
|
-
'nl': 'HTML List van apparaten met lage batterij staat',
|
|
709
|
-
'fr': 'HTML Liste des appareils à faible état de batterie',
|
|
710
|
-
'it': 'HTML Elenco di dispositivi con stato di batteria basso',
|
|
711
|
-
'es': 'HTML Lista de dispositivos con estado de batería bajo',
|
|
712
|
-
'pl': 'HTML Lista urządzeń o niskim stanie baterii',
|
|
713
|
-
'zh-cn': 'HTML 低电池国家装置清单'
|
|
714
|
-
},
|
|
715
|
-
'type': 'string',
|
|
716
|
-
'role': 'html',
|
|
717
|
-
'read': true,
|
|
718
|
-
'write': false,
|
|
719
|
-
},
|
|
720
|
-
'native': {}
|
|
721
|
-
});
|
|
722
|
-
}
|
|
631
|
+
//Get ID of foldername
|
|
632
|
+
case 'yeelight-2':
|
|
633
|
+
deviceName = shortCurrDeviceString.slice(shortCurrDeviceString.lastIndexOf('.') + 1);
|
|
634
|
+
break;
|
|
723
635
|
|
|
724
|
-
|
|
725
|
-
|
|
636
|
+
// Get ID with main selektor from objectjson
|
|
637
|
+
default:
|
|
638
|
+
if (deviceObject && typeof deviceObject === 'object') {
|
|
639
|
+
deviceName = deviceObject.common.name;
|
|
640
|
+
}
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
726
643
|
|
|
727
|
-
|
|
644
|
+
const deviceMainSelector = await this.getForeignStateAsync(id);
|
|
645
|
+
const deviceStateSelector = await this.getForeignStateAsync(shortCurrDeviceString + this.arrDev[i].stateValue); // for homematic devices
|
|
728
646
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
this.log.debug(`Function finished: ${this.createBlacklist.name}`);
|
|
734
|
-
}
|
|
647
|
+
// Get battery states
|
|
648
|
+
const deviceBatteryState = await this.getInitValue(currDeviceString + this.arrDev[i].battery);
|
|
649
|
+
const shortDeviceBatteryState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery);
|
|
650
|
+
const shortDeviceBatteryState2 = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery2);
|
|
735
651
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
652
|
+
this.devices.set(deviceName, currDeviceString + this.arrDev[i].reach);
|
|
653
|
+
// List all entries
|
|
654
|
+
//let text = '';
|
|
655
|
+
//this.devices.forEach (function(value, key) {
|
|
656
|
+
// text += key + ' : ' + value;
|
|
657
|
+
// });
|
|
658
|
+
// this.log.warn(text);
|
|
742
659
|
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
const currDeviceString = id.slice(0, (id.lastIndexOf('.') + 1) - 1);
|
|
748
|
-
const shortCurrDeviceString = currDeviceString.slice(0, (currDeviceString.lastIndexOf('.') + 1) - 1);
|
|
749
|
-
|
|
750
|
-
// Get device name
|
|
751
|
-
const deviceObject = await this.getForeignObjectAsync(currDeviceString);
|
|
752
|
-
const shortDeviceObject = await this.getForeignObjectAsync(shortCurrDeviceString);
|
|
753
|
-
let deviceName;
|
|
754
|
-
|
|
755
|
-
switch (this.arrDev[i].adapter) {
|
|
756
|
-
case 'switchbotBle': // Get ID for Switchbot and ESPHome Devices
|
|
757
|
-
case 'esphome':
|
|
758
|
-
deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
|
|
759
|
-
break;
|
|
760
|
-
|
|
761
|
-
case 'hue-extended':
|
|
762
|
-
case 'homematic':
|
|
763
|
-
case 'nuki-extended':
|
|
764
|
-
if (shortDeviceObject && typeof shortDeviceObject === 'object') {
|
|
765
|
-
deviceName = shortDeviceObject.common.name;
|
|
766
|
-
}
|
|
767
|
-
break;
|
|
660
|
+
// Get link quality
|
|
661
|
+
let deviceQualityState;
|
|
662
|
+
let linkQuality;
|
|
768
663
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
664
|
+
switch (this.arrDev[i].adapter) {
|
|
665
|
+
case 'sonoff':
|
|
666
|
+
case 'hmiP':
|
|
667
|
+
case 'homematic':
|
|
668
|
+
case 'wled':
|
|
669
|
+
case 'shelly':
|
|
670
|
+
deviceQualityState = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rssiState);
|
|
671
|
+
break;
|
|
772
672
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
}
|
|
777
|
-
break;
|
|
778
|
-
}
|
|
673
|
+
case 'mihomeVacuum':
|
|
674
|
+
deviceQualityState = await this.getForeignStateAsync(shortCurrDeviceString + this.arrDev[i].rssiState);
|
|
675
|
+
break;
|
|
779
676
|
|
|
780
|
-
|
|
677
|
+
case 'tradfri':
|
|
678
|
+
case 'ham':
|
|
679
|
+
case 'meross':
|
|
680
|
+
case 'nut':
|
|
681
|
+
case 'miHome':
|
|
682
|
+
case 'unifi':
|
|
683
|
+
deviceQualityState;
|
|
684
|
+
break;
|
|
781
685
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
686
|
+
case 'netatmo':
|
|
687
|
+
deviceQualityState = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rssiState);
|
|
688
|
+
if (!deviceQualityState) {
|
|
689
|
+
deviceQualityState = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rfState);
|
|
690
|
+
}
|
|
691
|
+
break;
|
|
786
692
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
693
|
+
default:
|
|
694
|
+
deviceQualityState = await this.getForeignStateAsync(id);
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
790
697
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
698
|
+
if ((deviceQualityState) && (typeof deviceQualityState.val === 'number')) {
|
|
699
|
+
if (this.config.trueState) {
|
|
700
|
+
linkQuality = deviceQualityState.val;
|
|
701
|
+
} else {
|
|
702
|
+
// If Quality State is already an percent value
|
|
703
|
+
switch (this.arrDev[i].adapter) {
|
|
704
|
+
case 'roomba':
|
|
705
|
+
linkQuality = deviceQualityState.val + '%';
|
|
706
|
+
break;
|
|
796
707
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
708
|
+
default:
|
|
709
|
+
// If Quality State is an RSSI vaulue calculate in percent:
|
|
710
|
+
if (deviceQualityState.val == -255) {
|
|
711
|
+
linkQuality = ' - ';
|
|
712
|
+
} else if (deviceQualityState.val < 0) {
|
|
713
|
+
linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
|
|
800
714
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
715
|
+
// If Quality State is an value between 0-255 (zigbee) calculate in percent:
|
|
716
|
+
} else if ((deviceQualityState.val) >= 0) {
|
|
717
|
+
linkQuality = parseFloat((100 / 255 * deviceQualityState.val).toFixed(0)) + '%';
|
|
718
|
+
}
|
|
719
|
+
break;
|
|
720
|
+
}
|
|
805
721
|
|
|
806
|
-
if ((deviceQualityState) && (typeof deviceQualityState.val === 'number')) {
|
|
807
|
-
if (this.config.trueState) {
|
|
808
|
-
linkQuality = deviceQualityState.val;
|
|
809
|
-
} else {
|
|
810
|
-
if (deviceQualityState.val < 0) {
|
|
811
|
-
linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
|
|
812
|
-
} else if ((deviceQualityState.val) >= 0) {
|
|
813
|
-
linkQuality = parseFloat((100 / 255 * deviceQualityState.val).toFixed(0)) + '%';
|
|
814
722
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
723
|
+
if (this.config.listOnlyBattery) {
|
|
724
|
+
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
725
|
+
this.linkQualityDevices.push(
|
|
726
|
+
{
|
|
727
|
+
'Device': deviceName,
|
|
728
|
+
'Adapter': deviceAdapterName,
|
|
729
|
+
'Signal strength': linkQuality
|
|
730
|
+
}
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
} else {
|
|
818
734
|
this.linkQualityDevices.push(
|
|
819
735
|
{
|
|
820
736
|
'Device': deviceName,
|
|
@@ -823,85 +739,136 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
823
739
|
}
|
|
824
740
|
);
|
|
825
741
|
}
|
|
826
|
-
} else {
|
|
827
|
-
this.
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
742
|
+
} else if ((deviceQualityState) && (typeof deviceQualityState.val === 'string')) {
|
|
743
|
+
switch (this.arrDev[i].adapter) {
|
|
744
|
+
case 'netatmo':
|
|
745
|
+
// for Netatmo devices
|
|
746
|
+
linkQuality = deviceQualityState.val;
|
|
747
|
+
break;
|
|
748
|
+
case 'nuki-extended':
|
|
749
|
+
linkQuality = ' - ';
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
if (this.config.listOnlyBattery) {
|
|
754
|
+
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
755
|
+
this.linkQualityDevices.push(
|
|
756
|
+
{
|
|
757
|
+
'Device': deviceName,
|
|
758
|
+
'Adapter': deviceAdapterName,
|
|
759
|
+
'Signal strength': linkQuality
|
|
760
|
+
}
|
|
761
|
+
);
|
|
832
762
|
}
|
|
833
|
-
|
|
763
|
+
} else {
|
|
764
|
+
this.linkQualityDevices.push(
|
|
765
|
+
{
|
|
766
|
+
'Device': deviceName,
|
|
767
|
+
'Adapter': deviceAdapterName,
|
|
768
|
+
'Signal strength': linkQuality
|
|
769
|
+
}
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
else {
|
|
774
|
+
linkQuality = ' - '; // no linkQuality available for powered devices
|
|
834
775
|
}
|
|
835
|
-
} else {
|
|
836
|
-
linkQuality = ' - '; // no linkQuality available for powered devices
|
|
837
|
-
}
|
|
838
776
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
// When was the last contact to the device?
|
|
843
|
-
let lastContactString;
|
|
844
|
-
|
|
845
|
-
let deviceState = 'Online';
|
|
846
|
-
if (deviceMainSelector) {
|
|
847
|
-
try {
|
|
848
|
-
const time = new Date();
|
|
849
|
-
const lastContact = Math.round((time.getTime() - deviceMainSelector.ts) / 1000 / 60);
|
|
850
|
-
const lastStateChange = Math.round((time.getTime() - deviceMainSelector.lc) / 1000 / 60);
|
|
851
|
-
const deviceUnreachState = await this.getInitValue(currDeviceString + this.arrDev[i].reach);
|
|
852
|
-
const shortDeviceUnreachState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].reach);
|
|
853
|
-
|
|
854
|
-
const getLastContact = async () => {
|
|
855
|
-
lastContactString = this.formatDate(new Date((deviceMainSelector.ts)), 'hh:mm') + ' Uhr';
|
|
856
|
-
if (Math.round(lastContact) > 100) {
|
|
857
|
-
lastContactString = Math.round(lastContact / 60) + ' Stunden';
|
|
858
|
-
}
|
|
859
|
-
if (Math.round(lastContact / 60) > 48) {
|
|
860
|
-
lastContactString = Math.round(lastContact / 60 / 24) + ' Tagen';
|
|
861
|
-
}
|
|
862
|
-
return lastContactString;
|
|
863
|
-
};
|
|
777
|
+
// Count how many devices with link Quality
|
|
778
|
+
this.linkQualityCount = this.linkQualityDevices.length;
|
|
864
779
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
if (Math.round(lastStateChange) > 100) {
|
|
868
|
-
lastContactString = Math.round(lastStateChange / 60) + ' Stunden';
|
|
869
|
-
}
|
|
870
|
-
if (Math.round(lastStateChange / 60) > 48) {
|
|
871
|
-
lastContactString = Math.round(lastStateChange / 60 / 24) + ' Tagen';
|
|
872
|
-
}
|
|
873
|
-
return lastContactString;
|
|
874
|
-
};
|
|
875
|
-
|
|
876
|
-
// If there is no contact since user sets minutes add device in offline list
|
|
877
|
-
// calculate to days after 48 hours
|
|
878
|
-
switch (this.arrDev[i].reach) {
|
|
879
|
-
case 'none':
|
|
880
|
-
await getLastContact();
|
|
881
|
-
break;
|
|
780
|
+
// When was the last contact to the device?
|
|
781
|
+
let lastContactString;
|
|
882
782
|
|
|
883
|
-
|
|
783
|
+
let deviceState = 'Online';
|
|
784
|
+
if (deviceMainSelector) {
|
|
785
|
+
try {
|
|
786
|
+
const time = new Date();
|
|
787
|
+
const lastContact = Math.round((time.getTime() - deviceMainSelector.ts) / 1000 / 60);
|
|
788
|
+
const lastStateChange = Math.round((time.getTime() - deviceMainSelector.lc) / 1000 / 60);
|
|
789
|
+
const deviceUnreachState = await this.getInitValue(currDeviceString + this.arrDev[i].reach);
|
|
790
|
+
const shortDeviceUnreachState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].reach);
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
const getLastContact = async () => {
|
|
794
|
+
lastContactString = this.formatDate(new Date((deviceMainSelector.ts)), 'hh:mm') + ' Uhr';
|
|
795
|
+
if (Math.round(lastContact) > 100) {
|
|
796
|
+
lastContactString = Math.round(lastContact / 60) + ' Stunden';
|
|
797
|
+
}
|
|
798
|
+
if (Math.round(lastContact / 60) > 48) {
|
|
799
|
+
lastContactString = Math.round(lastContact / 60 / 24) + ' Tagen';
|
|
800
|
+
}
|
|
801
|
+
return lastContactString;
|
|
802
|
+
};
|
|
803
|
+
|
|
804
|
+
const getLastStateChange = async () => {
|
|
805
|
+
lastContactString = this.formatDate(new Date((deviceMainSelector.lc)), 'hh:mm') + ' Uhr';
|
|
806
|
+
if (Math.round(lastStateChange) > 100) {
|
|
807
|
+
lastContactString = Math.round(lastStateChange / 60) + ' Stunden';
|
|
808
|
+
}
|
|
809
|
+
if (Math.round(lastStateChange / 60) > 48) {
|
|
810
|
+
lastContactString = Math.round(lastStateChange / 60 / 24) + ' Tagen';
|
|
811
|
+
}
|
|
812
|
+
return lastContactString;
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
// If there is no contact since user sets minutes add device in offline list
|
|
817
|
+
// calculate to days after 48 hours
|
|
818
|
+
switch (this.arrDev[i].reach) {
|
|
819
|
+
case 'none':
|
|
820
|
+
await getLastContact();
|
|
821
|
+
break;
|
|
822
|
+
|
|
823
|
+
default:
|
|
884
824
|
//State changed
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
825
|
+
if (this.arrDev[i].adapter == 'homematic') {
|
|
826
|
+
if (linkQuality != ' - ') {
|
|
827
|
+
if (deviceUnreachState) {
|
|
828
|
+
await getLastStateChange();
|
|
829
|
+
} else {
|
|
830
|
+
await getLastContact();
|
|
831
|
+
}
|
|
832
|
+
} else {
|
|
833
|
+
if (deviceStateSelector) { // because old hm devices don't send rssi states
|
|
834
|
+
const lastContactOfState = Math.round((time.getTime() - deviceStateSelector.ts) / 1000 / 60);
|
|
835
|
+
const getLastContactOfState = async () => {
|
|
836
|
+
lastContactString = this.formatDate(new Date((deviceStateSelector.ts)), 'hh:mm') + ' Uhr';
|
|
837
|
+
if (Math.round(lastContactOfState) > 100) {
|
|
838
|
+
lastContactString = Math.round(lastContactOfState / 60) + ' Stunden';
|
|
839
|
+
}
|
|
840
|
+
if (Math.round(lastContactOfState / 60) > 48) {
|
|
841
|
+
lastContactString = Math.round(lastContactOfState / 60 / 24) + ' Tagen';
|
|
842
|
+
}
|
|
843
|
+
return lastContactString;
|
|
844
|
+
};
|
|
845
|
+
await getLastContactOfState();
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
894
849
|
} else {
|
|
895
|
-
|
|
850
|
+
if ((!deviceUnreachState)) {
|
|
851
|
+
await getLastStateChange();
|
|
852
|
+
} else {
|
|
853
|
+
await getLastContact();
|
|
854
|
+
}
|
|
855
|
+
break;
|
|
896
856
|
}
|
|
897
|
-
|
|
898
|
-
}
|
|
899
|
-
}
|
|
857
|
+
}
|
|
900
858
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
859
|
+
const pushOfflineDevice = async () => {
|
|
860
|
+
if (this.config.listOnlyBattery) { //if checked, list only battery devices
|
|
861
|
+
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
862
|
+
this.offlineDevices.push(
|
|
863
|
+
{
|
|
864
|
+
'Device': deviceName,
|
|
865
|
+
'Adapter': deviceAdapterName,
|
|
866
|
+
'Last contact': lastContactString
|
|
867
|
+
}
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
} else {
|
|
871
|
+
this.offlineDevices.push( //else push all devices
|
|
905
872
|
{
|
|
906
873
|
'Device': deviceName,
|
|
907
874
|
'Adapter': deviceAdapterName,
|
|
@@ -909,312 +876,414 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
909
876
|
}
|
|
910
877
|
);
|
|
911
878
|
}
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
879
|
+
};
|
|
880
|
+
|
|
881
|
+
switch (this.arrDev[i].adapter) {
|
|
882
|
+
case 'alexa2':
|
|
883
|
+
if (this.config.alexa2MaxMinutes === -1) {
|
|
884
|
+
if (!deviceUnreachState) {
|
|
885
|
+
deviceState = 'Offline'; //set online state to offline
|
|
886
|
+
await pushOfflineDevice();
|
|
887
|
+
}
|
|
888
|
+
} else if (lastContact > this.config.alexa2MaxMinutes) {
|
|
889
|
+
deviceState = 'Offline'; //set online state to offline
|
|
890
|
+
await pushOfflineDevice();
|
|
918
891
|
}
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
892
|
+
break;
|
|
893
|
+
case 'ble':
|
|
894
|
+
if (this.config.bleMaxMinutes === -1) {
|
|
895
|
+
if (!deviceUnreachState) {
|
|
896
|
+
deviceState = 'Offline'; //set online state to offline
|
|
897
|
+
await pushOfflineDevice();
|
|
898
|
+
}
|
|
899
|
+
} else if (lastContact > this.config.bleMaxMinutes) {
|
|
900
|
+
deviceState = 'Offline'; //set online state to offline
|
|
901
|
+
await pushOfflineDevice();
|
|
902
|
+
}
|
|
903
|
+
break;
|
|
904
|
+
case 'deconz':
|
|
905
|
+
if (this.config.deconzMaxMinutes === -1) {
|
|
906
|
+
if (!deviceUnreachState) {
|
|
907
|
+
deviceState = 'Offline'; //set online state to offline
|
|
908
|
+
await pushOfflineDevice();
|
|
909
|
+
}
|
|
910
|
+
} else if (lastContact > this.config.deconzMaxMinutes) {
|
|
911
|
+
deviceState = 'Offline'; //set online state to offline
|
|
912
|
+
await pushOfflineDevice();
|
|
913
|
+
}
|
|
914
|
+
break;
|
|
915
|
+
case 'enocean':
|
|
916
|
+
if (this.config.enoceanMaxMinutes === -1) {
|
|
917
|
+
if (!deviceUnreachState) {
|
|
918
|
+
deviceState = 'Offline'; //set online state to offline
|
|
919
|
+
await pushOfflineDevice();
|
|
920
|
+
}
|
|
921
|
+
} else if (lastContact > this.config.enoceanMaxMinutes) {
|
|
922
|
+
deviceState = 'Offline'; //set online state to offline
|
|
923
|
+
await pushOfflineDevice();
|
|
924
|
+
}
|
|
925
|
+
break;
|
|
926
|
+
case 'esphome':
|
|
927
|
+
if (this.config.esphomeMaxMinutes === -1) {
|
|
928
|
+
if (!deviceUnreachState) {
|
|
929
|
+
deviceState = 'Offline'; //set online state to offline
|
|
930
|
+
await pushOfflineDevice();
|
|
931
|
+
}
|
|
932
|
+
} else if (lastContact > this.config.esphomeMaxMinutes) {
|
|
933
|
+
deviceState = 'Offline'; //set online state to offline
|
|
934
|
+
await pushOfflineDevice();
|
|
935
|
+
}
|
|
936
|
+
break;
|
|
937
|
+
case 'fritzDect':
|
|
938
|
+
if (this.config.fritzdectMaxMinutes === -1) {
|
|
939
|
+
if (!deviceUnreachState) {
|
|
940
|
+
deviceState = 'Offline'; //set online state to offline
|
|
941
|
+
await pushOfflineDevice();
|
|
942
|
+
}
|
|
943
|
+
} else if (lastContact > this.config.fritzdectMaxMinutes) {
|
|
944
|
+
deviceState = 'Offline'; //set online state to offline
|
|
945
|
+
await pushOfflineDevice();
|
|
946
|
+
}
|
|
947
|
+
break;
|
|
948
|
+
case 'harmony':
|
|
949
|
+
if (this.config.harmonyMaxMinutes === -1) {
|
|
950
|
+
if (!deviceUnreachState) {
|
|
951
|
+
deviceState = 'Offline'; //set online state to offline
|
|
952
|
+
await pushOfflineDevice();
|
|
953
|
+
}
|
|
954
|
+
} else if (lastContact > this.config.harmonyMaxMinutes) {
|
|
955
|
+
deviceState = 'Offline'; //set online state to offline
|
|
956
|
+
await pushOfflineDevice();
|
|
957
|
+
}
|
|
958
|
+
break;
|
|
959
|
+
case 'ham':
|
|
960
|
+
if (this.config.hamMaxMinutes === -1) {
|
|
961
|
+
if (!deviceUnreachState) {
|
|
962
|
+
deviceState = 'Offline'; //set online state to offline
|
|
963
|
+
await pushOfflineDevice();
|
|
964
|
+
}
|
|
965
|
+
} else if (lastContact > this.config.hamMaxMinutes) {
|
|
966
|
+
deviceState = 'Offline'; //set online state to offline
|
|
967
|
+
await pushOfflineDevice();
|
|
968
|
+
}
|
|
969
|
+
break;
|
|
970
|
+
case 'hmiP':
|
|
971
|
+
if (this.config.hmiPMaxMinutes === -1) {
|
|
972
|
+
if (deviceUnreachState) {
|
|
973
|
+
deviceState = 'Offline'; //set online state to offline
|
|
974
|
+
await pushOfflineDevice();
|
|
975
|
+
}
|
|
976
|
+
} else if (lastContact > this.config.hmiPMaxMinutes) {
|
|
977
|
+
deviceState = 'Offline'; //set online state to offline
|
|
978
|
+
await pushOfflineDevice();
|
|
979
|
+
}
|
|
980
|
+
break;
|
|
981
|
+
case 'homematic':
|
|
982
|
+
if (this.config.homematicMaxMinutes === -1) {
|
|
983
|
+
if (deviceUnreachState) {
|
|
984
|
+
deviceState = 'Offline'; //set online state to offline
|
|
985
|
+
await pushOfflineDevice();
|
|
986
|
+
}
|
|
987
|
+
} else if (lastContact > this.config.homematicMaxMinutes) {
|
|
988
|
+
deviceState = 'Offline'; //set online state to offline
|
|
989
|
+
await pushOfflineDevice();
|
|
990
|
+
}
|
|
991
|
+
break;
|
|
992
|
+
case 'hue':
|
|
993
|
+
if (this.config.hueMaxMinutes === -1) {
|
|
994
|
+
if (!deviceUnreachState) {
|
|
995
|
+
deviceState = 'Offline'; //set online state to offline
|
|
996
|
+
await pushOfflineDevice();
|
|
997
|
+
}
|
|
998
|
+
} else if (lastContact > this.config.hueMaxMinutes) {
|
|
999
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1000
|
+
await pushOfflineDevice();
|
|
1001
|
+
}
|
|
1002
|
+
break;
|
|
1003
|
+
case 'hue-extended':
|
|
1004
|
+
if (this.config.hueextMaxMinutes === -1) {
|
|
1005
|
+
if (!deviceUnreachState) {
|
|
1006
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1007
|
+
await pushOfflineDevice();
|
|
1008
|
+
}
|
|
1009
|
+
} else if (lastContact > this.config.hueextMaxMinutes) {
|
|
1010
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1011
|
+
await pushOfflineDevice();
|
|
1012
|
+
}
|
|
1013
|
+
break;
|
|
1014
|
+
case 'jeelink':
|
|
1015
|
+
if (this.config.jeelinkMaxMinutes === -1) {
|
|
1016
|
+
if (!deviceUnreachState) {
|
|
1017
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1018
|
+
await pushOfflineDevice();
|
|
1019
|
+
}
|
|
1020
|
+
} else if (lastContact > this.config.jeelinkMaxMinutes) {
|
|
929
1021
|
deviceState = 'Offline'; //set online state to offline
|
|
930
1022
|
await pushOfflineDevice();
|
|
931
1023
|
}
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
if (
|
|
1024
|
+
break;
|
|
1025
|
+
case 'meross':
|
|
1026
|
+
if (this.config.merossMaxMinutes === -1) {
|
|
1027
|
+
if (!deviceUnreachState) {
|
|
1028
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1029
|
+
await pushOfflineDevice();
|
|
1030
|
+
}
|
|
1031
|
+
} else if (lastContact > this.config.merossMaxMinutes) {
|
|
940
1032
|
deviceState = 'Offline'; //set online state to offline
|
|
941
1033
|
await pushOfflineDevice();
|
|
942
1034
|
}
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
if (
|
|
1035
|
+
break;
|
|
1036
|
+
case 'miHome':
|
|
1037
|
+
if (this.config.mihomeMaxMinutes === -1) {
|
|
1038
|
+
if (!deviceUnreachState) {
|
|
1039
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1040
|
+
await pushOfflineDevice();
|
|
1041
|
+
}
|
|
1042
|
+
} else if (lastContact > this.config.mihomeMaxMinutes) {
|
|
951
1043
|
deviceState = 'Offline'; //set online state to offline
|
|
952
1044
|
await pushOfflineDevice();
|
|
953
1045
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
if (
|
|
1046
|
+
break;
|
|
1047
|
+
case 'mihomeVacuum':
|
|
1048
|
+
if (this.config.mihomeVacuumMaxMinutes === -1) {
|
|
1049
|
+
if (!shortDeviceUnreachState) {
|
|
1050
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1051
|
+
await pushOfflineDevice();
|
|
1052
|
+
}
|
|
1053
|
+
} else if (lastContact > this.config.mihomeVacuumMaxMinutes) {
|
|
962
1054
|
deviceState = 'Offline'; //set online state to offline
|
|
963
1055
|
await pushOfflineDevice();
|
|
964
1056
|
}
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
if (
|
|
1057
|
+
break;
|
|
1058
|
+
case 'netatmo':
|
|
1059
|
+
if (this.config.netatmoMaxMinutes === -1) {
|
|
1060
|
+
if (!deviceUnreachState) {
|
|
1061
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1062
|
+
await pushOfflineDevice();
|
|
1063
|
+
}
|
|
1064
|
+
} else if (lastContact > this.config.netatmoMaxMinutes) {
|
|
973
1065
|
deviceState = 'Offline'; //set online state to offline
|
|
974
1066
|
await pushOfflineDevice();
|
|
975
1067
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
if (
|
|
1068
|
+
break;
|
|
1069
|
+
case 'nuki-extended':
|
|
1070
|
+
if (this.config.nukiextendMaxMinutes === -1) {
|
|
1071
|
+
if (!deviceUnreachState) {
|
|
1072
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1073
|
+
await pushOfflineDevice();
|
|
1074
|
+
}
|
|
1075
|
+
} else if (lastContact > this.config.nukiextendMaxMinutes) {
|
|
984
1076
|
deviceState = 'Offline'; //set online state to offline
|
|
985
1077
|
await pushOfflineDevice();
|
|
986
1078
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
if (
|
|
1079
|
+
break;
|
|
1080
|
+
case 'nut':
|
|
1081
|
+
if (this.config.nutMaxMinutes === -1) {
|
|
1082
|
+
if (!deviceUnreachState) {
|
|
1083
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1084
|
+
await pushOfflineDevice();
|
|
1085
|
+
}
|
|
1086
|
+
} else if (lastContact > this.config.nutMaxMinutes) {
|
|
995
1087
|
deviceState = 'Offline'; //set online state to offline
|
|
996
1088
|
await pushOfflineDevice();
|
|
997
1089
|
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
if (deviceUnreachState) {
|
|
1090
|
+
break;
|
|
1091
|
+
case 'ping':
|
|
1092
|
+
if (this.config.pingMaxMinutes === -1) {
|
|
1093
|
+
if (!deviceUnreachState) {
|
|
1094
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1095
|
+
await pushOfflineDevice();
|
|
1096
|
+
}
|
|
1097
|
+
} else if ((lastStateChange > this.config.pingMaxMinutes) && (!deviceUnreachState)) {
|
|
1006
1098
|
deviceState = 'Offline'; //set online state to offline
|
|
1007
1099
|
await pushOfflineDevice();
|
|
1008
1100
|
}
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
if (
|
|
1101
|
+
break;
|
|
1102
|
+
case 'roomba':
|
|
1103
|
+
if (this.config.roombaMaxMinutes === -1) {
|
|
1104
|
+
if (!deviceUnreachState) {
|
|
1105
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1106
|
+
await pushOfflineDevice();
|
|
1107
|
+
}
|
|
1108
|
+
} else if (lastContact > this.config.roombaMaxMinutes) {
|
|
1017
1109
|
deviceState = 'Offline'; //set online state to offline
|
|
1018
1110
|
await pushOfflineDevice();
|
|
1019
1111
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
if (
|
|
1112
|
+
break;
|
|
1113
|
+
case 'shelly':
|
|
1114
|
+
if (this.config.shellyMaxMinutes === -1) {
|
|
1115
|
+
if (!deviceUnreachState) {
|
|
1116
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1117
|
+
await pushOfflineDevice();
|
|
1118
|
+
}
|
|
1119
|
+
} else if (lastContact > this.config.shellyMaxMinutes) {
|
|
1028
1120
|
deviceState = 'Offline'; //set online state to offline
|
|
1029
1121
|
await pushOfflineDevice();
|
|
1030
1122
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
if (
|
|
1123
|
+
break;
|
|
1124
|
+
case 'sonoff':
|
|
1125
|
+
if (this.config.sonoffMaxMinutes === -1) {
|
|
1126
|
+
if (!deviceUnreachState) {
|
|
1127
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1128
|
+
await pushOfflineDevice();
|
|
1129
|
+
}
|
|
1130
|
+
} else if (lastContact > this.config.sonoffMaxMinutes) {
|
|
1039
1131
|
deviceState = 'Offline'; //set online state to offline
|
|
1040
1132
|
await pushOfflineDevice();
|
|
1041
1133
|
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
if (
|
|
1134
|
+
break;
|
|
1135
|
+
case 'sonos':
|
|
1136
|
+
if (this.config.sonosMaxMinutes === -1) {
|
|
1137
|
+
if (!deviceUnreachState) {
|
|
1138
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1139
|
+
await pushOfflineDevice();
|
|
1140
|
+
}
|
|
1141
|
+
} else if (lastContact > this.config.sonosMaxMinutes) {
|
|
1050
1142
|
deviceState = 'Offline'; //set online state to offline
|
|
1051
1143
|
await pushOfflineDevice();
|
|
1052
1144
|
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
if (
|
|
1145
|
+
break;
|
|
1146
|
+
case 'switchbotBle':
|
|
1147
|
+
if (this.config.switchbotMaxMinutes === -1) {
|
|
1148
|
+
if (!deviceUnreachState) {
|
|
1149
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1150
|
+
await pushOfflineDevice();
|
|
1151
|
+
}
|
|
1152
|
+
} else if (lastContact > this.config.switchbotMaxMinutes) {
|
|
1061
1153
|
deviceState = 'Offline'; //set online state to offline
|
|
1062
1154
|
await pushOfflineDevice();
|
|
1063
1155
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
if (
|
|
1156
|
+
break;
|
|
1157
|
+
case 'tado':
|
|
1158
|
+
if (this.config.tadoMaxMinutes === -1) {
|
|
1159
|
+
if (!deviceUnreachState) {
|
|
1160
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1161
|
+
await pushOfflineDevice();
|
|
1162
|
+
}
|
|
1163
|
+
} else if (lastContact > this.config.tadoMaxMinutes) {
|
|
1072
1164
|
deviceState = 'Offline'; //set online state to offline
|
|
1073
1165
|
await pushOfflineDevice();
|
|
1074
1166
|
}
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
if (
|
|
1167
|
+
break;
|
|
1168
|
+
case 'tradfri':
|
|
1169
|
+
if (this.config.tradfriMaxMinutes === -1) {
|
|
1170
|
+
if (!deviceUnreachState) {
|
|
1171
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1172
|
+
await pushOfflineDevice();
|
|
1173
|
+
}
|
|
1174
|
+
} else if (lastContact > this.config.tradfriMaxMinutes) {
|
|
1083
1175
|
deviceState = 'Offline'; //set online state to offline
|
|
1084
1176
|
await pushOfflineDevice();
|
|
1085
1177
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
if (
|
|
1178
|
+
break;
|
|
1179
|
+
case 'unifi':
|
|
1180
|
+
if (this.config.unifiMaxMinutes === -1) {
|
|
1181
|
+
if (deviceUnreachState === 0) {
|
|
1182
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1183
|
+
await pushOfflineDevice();
|
|
1184
|
+
}
|
|
1185
|
+
} else if (lastContact > this.config.unifiMaxMinutes) {
|
|
1094
1186
|
deviceState = 'Offline'; //set online state to offline
|
|
1095
1187
|
await pushOfflineDevice();
|
|
1096
1188
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
if (
|
|
1189
|
+
break;
|
|
1190
|
+
case 'wled':
|
|
1191
|
+
if (this.config.wledMaxMinutes === -1) {
|
|
1192
|
+
if (!deviceUnreachState) {
|
|
1193
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1194
|
+
await pushOfflineDevice();
|
|
1195
|
+
}
|
|
1196
|
+
} else if (lastContact > this.config.wledMaxMinutes) {
|
|
1105
1197
|
deviceState = 'Offline'; //set online state to offline
|
|
1106
1198
|
await pushOfflineDevice();
|
|
1107
1199
|
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
if (
|
|
1200
|
+
break;
|
|
1201
|
+
case 'yeelight-2':
|
|
1202
|
+
if (this.config.yeelightMaxMinutes === -1) {
|
|
1203
|
+
if (!deviceUnreachState) {
|
|
1204
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1205
|
+
await pushOfflineDevice();
|
|
1206
|
+
}
|
|
1207
|
+
} else if (lastContact > this.config.yeelightMaxMinutes) {
|
|
1116
1208
|
deviceState = 'Offline'; //set online state to offline
|
|
1117
1209
|
await pushOfflineDevice();
|
|
1118
1210
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
if (
|
|
1211
|
+
break;
|
|
1212
|
+
case 'zigbee':
|
|
1213
|
+
if (this.config.zigbeeMaxMinutes === -1) {
|
|
1214
|
+
if (!deviceUnreachState) {
|
|
1215
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1216
|
+
await pushOfflineDevice();
|
|
1217
|
+
}
|
|
1218
|
+
} else if (lastContact > this.config.zigbeeMaxMinutes) {
|
|
1127
1219
|
deviceState = 'Offline'; //set online state to offline
|
|
1128
1220
|
await pushOfflineDevice();
|
|
1129
1221
|
}
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
if (
|
|
1222
|
+
break;
|
|
1223
|
+
case 'zigbee2MQTT':
|
|
1224
|
+
if (this.config.zigbee2mqttMaxMinutes === -1) {
|
|
1225
|
+
if (!deviceUnreachState) {
|
|
1226
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1227
|
+
await pushOfflineDevice();
|
|
1228
|
+
}
|
|
1229
|
+
} else if (lastContact > this.config.zigbee2mqttMaxMinutes) {
|
|
1138
1230
|
deviceState = 'Offline'; //set online state to offline
|
|
1139
1231
|
await pushOfflineDevice();
|
|
1140
1232
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
if (
|
|
1233
|
+
break;
|
|
1234
|
+
case 'zwave':
|
|
1235
|
+
if (this.config.zwaveMaxMinutes === -1) {
|
|
1236
|
+
if (!deviceUnreachState) {
|
|
1237
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1238
|
+
await pushOfflineDevice();
|
|
1239
|
+
}
|
|
1240
|
+
} else if (lastContact > this.config.zwaveMaxMinutes) {
|
|
1149
1241
|
deviceState = 'Offline'; //set online state to offline
|
|
1150
1242
|
await pushOfflineDevice();
|
|
1151
1243
|
}
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
break;
|
|
1244
|
+
break;
|
|
1245
|
+
}
|
|
1246
|
+
} catch (error) {
|
|
1247
|
+
this.errorReporting('[getLastContact]', error);
|
|
1157
1248
|
}
|
|
1158
|
-
} catch (error) {
|
|
1159
|
-
this.errorReporting('[getLastContact]', error);
|
|
1160
1249
|
}
|
|
1161
|
-
}
|
|
1162
1250
|
|
|
1163
1251
|
|
|
1164
1252
|
|
|
1165
|
-
|
|
1166
|
-
|
|
1253
|
+
// Count how many devcies are offline
|
|
1254
|
+
this.offlineDevicesCount = this.offlineDevices.length;
|
|
1167
1255
|
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1256
|
+
// Get battery states
|
|
1257
|
+
let batteryHealth;
|
|
1258
|
+
const deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat);
|
|
1259
|
+
const deviceLowBatStateHM = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat2);
|
|
1172
1260
|
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
}
|
|
1187
|
-
switch (this.arrDev[i].isLowBat2) {
|
|
1188
|
-
case 'none':
|
|
1189
|
-
batteryHealth = ' - ';
|
|
1190
|
-
break;
|
|
1191
|
-
default:
|
|
1192
|
-
if (!deviceLowBatState) {
|
|
1193
|
-
batteryHealth = 'ok';
|
|
1194
|
-
} else {
|
|
1195
|
-
batteryHealth = 'low';
|
|
1196
|
-
}
|
|
1197
|
-
break;
|
|
1198
|
-
}
|
|
1199
|
-
this.batteryPowered.push(
|
|
1200
|
-
{
|
|
1201
|
-
'Device': deviceName,
|
|
1202
|
-
'Adapter': deviceAdapterName,
|
|
1203
|
-
'Battery': batteryHealth
|
|
1261
|
+
if ((!deviceBatteryState) && (!shortDeviceBatteryState) && (!shortDeviceBatteryState2)) {
|
|
1262
|
+
if ((deviceLowBatState !== undefined) || (deviceLowBatState !== undefined) || (deviceLowBatStateHM !== undefined)) {
|
|
1263
|
+
switch (this.arrDev[i].isLowBat) {
|
|
1264
|
+
case 'none':
|
|
1265
|
+
batteryHealth = ' - ';
|
|
1266
|
+
break;
|
|
1267
|
+
default:
|
|
1268
|
+
if ((!deviceLowBatState) || (deviceLowBatState == 'NORMAL')) {
|
|
1269
|
+
batteryHealth = 'ok';
|
|
1270
|
+
} else {
|
|
1271
|
+
batteryHealth = 'low';
|
|
1272
|
+
}
|
|
1273
|
+
break;
|
|
1204
1274
|
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1275
|
+
switch (this.arrDev[i].isLowBat2) {
|
|
1276
|
+
case 'none':
|
|
1277
|
+
batteryHealth = ' - ';
|
|
1278
|
+
break;
|
|
1279
|
+
default:
|
|
1280
|
+
if ((!deviceLowBatState) || (deviceLowBatState == 'NORMAL')) {
|
|
1281
|
+
batteryHealth = 'ok';
|
|
1282
|
+
} else {
|
|
1283
|
+
batteryHealth = 'low';
|
|
1284
|
+
}
|
|
1285
|
+
break;
|
|
1216
1286
|
}
|
|
1217
|
-
|
|
1218
1287
|
this.batteryPowered.push(
|
|
1219
1288
|
{
|
|
1220
1289
|
'Device': deviceName,
|
|
@@ -1222,10 +1291,18 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1222
1291
|
'Battery': batteryHealth
|
|
1223
1292
|
}
|
|
1224
1293
|
);
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1294
|
+
} else {
|
|
1295
|
+
batteryHealth = ' - ';
|
|
1296
|
+
}
|
|
1297
|
+
} else {
|
|
1298
|
+
switch (this.arrDev[i].adapter) {
|
|
1299
|
+
case 'homematic':
|
|
1300
|
+
if (deviceBatteryState === 0) {
|
|
1301
|
+
batteryHealth = ' - ';
|
|
1302
|
+
} else {
|
|
1303
|
+
batteryHealth = deviceBatteryState + 'V';
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1229
1306
|
this.batteryPowered.push(
|
|
1230
1307
|
{
|
|
1231
1308
|
'Device': deviceName,
|
|
@@ -1233,11 +1310,42 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1233
1310
|
'Battery': batteryHealth
|
|
1234
1311
|
}
|
|
1235
1312
|
);
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1313
|
+
break;
|
|
1314
|
+
case 'hue-extended':
|
|
1315
|
+
if (shortDeviceBatteryState) {
|
|
1316
|
+
batteryHealth = shortDeviceBatteryState + '%';
|
|
1317
|
+
this.batteryPowered.push(
|
|
1318
|
+
{
|
|
1319
|
+
'Device': deviceName,
|
|
1320
|
+
'Adapter': deviceAdapterName,
|
|
1321
|
+
'Battery': batteryHealth
|
|
1322
|
+
}
|
|
1323
|
+
);
|
|
1324
|
+
}
|
|
1325
|
+
break;
|
|
1326
|
+
case 'mihomeVacuum':
|
|
1327
|
+
if (shortDeviceBatteryState) {
|
|
1328
|
+
batteryHealth = shortDeviceBatteryState + '%';
|
|
1329
|
+
this.batteryPowered.push(
|
|
1330
|
+
{
|
|
1331
|
+
'Device': deviceName,
|
|
1332
|
+
'Adapter': deviceAdapterName,
|
|
1333
|
+
'Battery': batteryHealth
|
|
1334
|
+
}
|
|
1335
|
+
);
|
|
1336
|
+
} else if (shortDeviceBatteryState2) {
|
|
1337
|
+
batteryHealth = shortDeviceBatteryState2 + '%';
|
|
1338
|
+
this.batteryPowered.push(
|
|
1339
|
+
{
|
|
1340
|
+
'Device': deviceName,
|
|
1341
|
+
'Adapter': deviceAdapterName,
|
|
1342
|
+
'Battery': batteryHealth
|
|
1343
|
+
}
|
|
1344
|
+
);
|
|
1345
|
+
}
|
|
1346
|
+
break;
|
|
1347
|
+
default:
|
|
1348
|
+
batteryHealth = (deviceBatteryState) + '%';
|
|
1241
1349
|
this.batteryPowered.push(
|
|
1242
1350
|
{
|
|
1243
1351
|
'Device': deviceName,
|
|
@@ -1245,9 +1353,20 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1245
1353
|
'Battery': batteryHealth
|
|
1246
1354
|
}
|
|
1247
1355
|
);
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
// Count how many devices are with battery
|
|
1360
|
+
this.batteryPoweredCount = this.batteryPowered.length;
|
|
1361
|
+
|
|
1362
|
+
// Count how many devices are with low battery
|
|
1363
|
+
const batteryWarningMin = this.config.minWarnBatterie;
|
|
1364
|
+
|
|
1365
|
+
// fill list with low battery devices
|
|
1366
|
+
switch (this.arrDev[i].adapter) {
|
|
1367
|
+
case 'homematic': // there are differnt low bat states between hm and hmIp devices
|
|
1368
|
+
if (deviceLowBatState || deviceLowBatStateHM) {
|
|
1369
|
+
this.batteryLowPowered.push(
|
|
1251
1370
|
{
|
|
1252
1371
|
'Device': deviceName,
|
|
1253
1372
|
'Adapter': deviceAdapterName,
|
|
@@ -1256,63 +1375,56 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1256
1375
|
);
|
|
1257
1376
|
}
|
|
1258
1377
|
break;
|
|
1259
|
-
default:
|
|
1260
|
-
batteryHealth = (deviceBatteryState) + '%';
|
|
1261
|
-
this.batteryPowered.push(
|
|
1262
|
-
{
|
|
1263
|
-
'Device': deviceName,
|
|
1264
|
-
'Adapter': deviceAdapterName,
|
|
1265
|
-
'Battery': batteryHealth
|
|
1266
|
-
}
|
|
1267
|
-
);
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
1378
|
|
|
1271
|
-
|
|
1272
|
-
|
|
1379
|
+
case 'tado': // there is an string as indicator
|
|
1380
|
+
if (deviceLowBatState != 'NORMAL') {
|
|
1381
|
+
this.batteryLowPowered.push(
|
|
1382
|
+
{
|
|
1383
|
+
'Device': deviceName,
|
|
1384
|
+
'Adapter': deviceAdapterName,
|
|
1385
|
+
'Battery': batteryHealth
|
|
1386
|
+
}
|
|
1387
|
+
);
|
|
1388
|
+
}
|
|
1389
|
+
break;
|
|
1273
1390
|
|
|
1274
|
-
|
|
1275
|
-
|
|
1391
|
+
default: // for all other devices with low bat states
|
|
1392
|
+
if (deviceLowBatState) {
|
|
1393
|
+
this.batteryLowPowered.push(
|
|
1394
|
+
{
|
|
1395
|
+
'Device': deviceName,
|
|
1396
|
+
'Adapter': deviceAdapterName,
|
|
1397
|
+
'Battery': batteryHealth
|
|
1398
|
+
}
|
|
1399
|
+
);
|
|
1400
|
+
} else if (deviceBatteryState && (deviceBatteryState < batteryWarningMin)) { // if the battery state is under the set limit
|
|
1401
|
+
this.batteryLowPowered.push(
|
|
1402
|
+
{
|
|
1403
|
+
'Device': deviceName,
|
|
1404
|
+
'Adapter': deviceAdapterName,
|
|
1405
|
+
'Battery': batteryHealth
|
|
1406
|
+
}
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1276
1410
|
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
case 'homematic': // there are differnt low bat states between hm and hmIp devices
|
|
1280
|
-
if (deviceLowBatState || deviceLowBatStateHM) {
|
|
1281
|
-
this.batteryLowPowered.push(
|
|
1282
|
-
{
|
|
1283
|
-
'Device': deviceName,
|
|
1284
|
-
'Adapter': deviceAdapterName,
|
|
1285
|
-
'Battery': batteryHealth
|
|
1286
|
-
}
|
|
1287
|
-
);
|
|
1288
|
-
}
|
|
1289
|
-
break;
|
|
1411
|
+
// 3d. Count how many devices are with low battery
|
|
1412
|
+
this.lowBatteryPoweredCount = this.batteryLowPowered.length;
|
|
1290
1413
|
|
|
1291
|
-
|
|
1292
|
-
if (
|
|
1293
|
-
this.
|
|
1294
|
-
{
|
|
1295
|
-
'Device': deviceName,
|
|
1296
|
-
'Adapter': deviceAdapterName,
|
|
1297
|
-
'Battery': batteryHealth
|
|
1298
|
-
}
|
|
1299
|
-
);
|
|
1300
|
-
} else if (deviceBatteryState && (deviceBatteryState < batteryWarningMin)) { // if the battery state is under the set limit
|
|
1301
|
-
this.batteryLowPowered.push(
|
|
1414
|
+
if (this.config.listOnlyBattery) { // 4. Add only devices with battery in the list
|
|
1415
|
+
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
1416
|
+
this.listAllDevices.push(
|
|
1302
1417
|
{
|
|
1303
1418
|
'Device': deviceName,
|
|
1304
1419
|
'Adapter': deviceAdapterName,
|
|
1305
|
-
'Battery': batteryHealth
|
|
1420
|
+
'Battery': batteryHealth,
|
|
1421
|
+
'Signal strength': linkQuality,
|
|
1422
|
+
'Last contact': lastContactString,
|
|
1423
|
+
'Status': deviceState
|
|
1306
1424
|
}
|
|
1307
1425
|
);
|
|
1308
1426
|
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
// 3d. Count how many devices are with low battery
|
|
1312
|
-
this.lowBatteryPoweredCount = this.batteryLowPowered.length;
|
|
1313
|
-
|
|
1314
|
-
if (this.config.listOnlyBattery) { // 4. Add only devices with battery in the list
|
|
1315
|
-
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
1427
|
+
} else if (!this.config.listOnlyBattery) { // 4. Add all devices
|
|
1316
1428
|
this.listAllDevices.push(
|
|
1317
1429
|
{
|
|
1318
1430
|
'Device': deviceName,
|
|
@@ -1324,22 +1436,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1324
1436
|
}
|
|
1325
1437
|
);
|
|
1326
1438
|
}
|
|
1327
|
-
} else if (!this.config.listOnlyBattery) { // 4. Add all devices
|
|
1328
|
-
this.listAllDevices.push(
|
|
1329
|
-
{
|
|
1330
|
-
'Device': deviceName,
|
|
1331
|
-
'Adapter': deviceAdapterName,
|
|
1332
|
-
'Battery': batteryHealth,
|
|
1333
|
-
'Signal strength': linkQuality,
|
|
1334
|
-
'Last contact': lastContactString,
|
|
1335
|
-
'Status': deviceState
|
|
1336
|
-
}
|
|
1337
|
-
);
|
|
1338
|
-
}
|
|
1339
1439
|
|
|
1340
1440
|
|
|
1341
|
-
|
|
1342
|
-
|
|
1441
|
+
// 4a. Count how many devices are exists
|
|
1442
|
+
this.deviceCounter = this.listAllDevices.length;
|
|
1443
|
+
}
|
|
1444
|
+
} else {
|
|
1445
|
+
return; // cancel run if unloaded was called.
|
|
1343
1446
|
}
|
|
1344
1447
|
} // <-- end of loop
|
|
1345
1448
|
} // <-- end of createData
|
|
@@ -1377,15 +1480,18 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1377
1480
|
await this.resetVars(); // reset the arrays and counts
|
|
1378
1481
|
|
|
1379
1482
|
for (let i = 0; i < this.arrDev.length; i++) {
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1483
|
+
if (!isUnloaded) {
|
|
1484
|
+
await this.createData(i);
|
|
1485
|
+
} else {
|
|
1486
|
+
return; // cancel run if unloaded was called.
|
|
1487
|
+
}
|
|
1383
1488
|
}
|
|
1384
1489
|
|
|
1385
|
-
|
|
1386
|
-
if (this.config.
|
|
1387
|
-
|
|
1388
|
-
|
|
1490
|
+
// send message if new devices are offline
|
|
1491
|
+
if (this.config.checkSendOfflineMsg) await this.sendOfflineNotifications();
|
|
1492
|
+
|
|
1493
|
+
// fill the datapoints
|
|
1494
|
+
await this.writeDatapoints();
|
|
1389
1495
|
} catch (error) {
|
|
1390
1496
|
this.errorReporting('[createDataOfAllAdapter]', error);
|
|
1391
1497
|
}
|
|
@@ -1515,172 +1621,132 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1515
1621
|
}
|
|
1516
1622
|
} // <-- End of sendNotification function
|
|
1517
1623
|
|
|
1624
|
+
async sendBatteryNotifyShedule() {
|
|
1625
|
+
// send message for low battery devices
|
|
1518
1626
|
|
|
1519
|
-
|
|
1520
|
-
// send message if an device is offline
|
|
1521
|
-
|
|
1522
|
-
this.log.debug(`Start the function: ${this.sendOfflineNotifications.name}`);
|
|
1523
|
-
|
|
1524
|
-
try {
|
|
1525
|
-
let msg = '';
|
|
1526
|
-
const offlineDevicesCountOld = await this.getOwnInitValue('offlineCount');
|
|
1627
|
+
const time = (this.config.checkSendBatteryTime).split(':');
|
|
1527
1628
|
|
|
1528
|
-
|
|
1529
|
-
if (this.offlineDevicesCount == 0) {
|
|
1530
|
-
msg = 'Alle Geräte sind Online.';
|
|
1531
|
-
} else if (this.offlineDevicesCount == 1) { // make singular if it is only one device
|
|
1532
|
-
msg = 'Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n';
|
|
1533
|
-
} else if (this.offlineDevicesCount >= 2) { //make plural if it is more than one device
|
|
1534
|
-
msg = `Folgende ${this.offlineDevicesCount} Geräte sind seit einiger Zeit nicht erreichbar: \n`;
|
|
1535
|
-
}
|
|
1629
|
+
const checkDays = []; // list of selected days
|
|
1536
1630
|
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1631
|
+
// push the selected days in list
|
|
1632
|
+
if (this.config.checkMonday) checkDays.push(1);
|
|
1633
|
+
if (this.config.checkTuesday) checkDays.push(2);
|
|
1634
|
+
if (this.config.checkWednesday) checkDays.push(3);
|
|
1635
|
+
if (this.config.checkThursday) checkDays.push(4);
|
|
1636
|
+
if (this.config.checkFriday) checkDays.push(5);
|
|
1637
|
+
if (this.config.checkSaturday) checkDays.push(6);
|
|
1638
|
+
if (this.config.checkSunday) checkDays.push(0);
|
|
1540
1639
|
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
this.errorReporting('[sendOfflineMessage]', error);
|
|
1640
|
+
if (checkDays.length >= 1) { // check if an day is selected
|
|
1641
|
+
this.log.debug(`Number of selected days for daily battery message: ${checkDays.length}. Send Message on: ${(checkDays).join(', ')} ...`);
|
|
1642
|
+
} else {
|
|
1643
|
+
this.log.warn(`No days selected for daily battery message. Please check the instance configuration!`);
|
|
1644
|
+
return; // cancel function if no day is selected
|
|
1547
1645
|
}
|
|
1548
1646
|
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
const lastOfflineNotifyIndicator = await this.getOwnInitValue('info.lastOfflineNotification');
|
|
1554
|
-
const now = new Date(); // get date
|
|
1555
|
-
|
|
1556
|
-
// set indicator for send message first to 'false', after sending to 'true'
|
|
1557
|
-
if (now.getHours() < 11) await this.setStateAsync('info.lastOfflineNotification', false, true);
|
|
1558
|
-
|
|
1559
|
-
// if time is > 11 (12:00 pm create message for offline devices devices)
|
|
1560
|
-
if ((now.getHours() > 11) && (!lastOfflineNotifyIndicator)) {
|
|
1647
|
+
if (!isUnloaded) {
|
|
1648
|
+
const cron = '10 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
1649
|
+
schedule.scheduleJob(cron, () => {
|
|
1650
|
+
try {
|
|
1561
1651
|
let msg = '';
|
|
1562
1652
|
|
|
1563
|
-
for (const id of this.
|
|
1564
|
-
msg = `${msg}
|
|
1653
|
+
for (const id of this.batteryLowPowered) {
|
|
1654
|
+
msg = `${msg}\n${id['Device']} (${id['Battery']})`;
|
|
1565
1655
|
}
|
|
1566
1656
|
|
|
1567
|
-
if (this.
|
|
1568
|
-
this.log.info(`
|
|
1569
|
-
|
|
1657
|
+
if (this.lowBatteryPoweredCount > 0) {
|
|
1658
|
+
this.log.info(`Niedrige Batteriezustände: ${msg}`);
|
|
1659
|
+
this.setStateAsync('lastNotification', `Niedrige Batteriezustände: ${msg}`, true);
|
|
1570
1660
|
|
|
1571
|
-
|
|
1661
|
+
this.sendNotification(`Niedriege Batteriezustände: ${msg}`);
|
|
1572
1662
|
|
|
1573
|
-
await this.setStateAsync('info.lastOfflineNotification', true, true);
|
|
1574
1663
|
}
|
|
1664
|
+
|
|
1665
|
+
} catch (error) {
|
|
1666
|
+
this.errorReporting('[sendBatteryNotifyShedule]', error);
|
|
1575
1667
|
}
|
|
1576
|
-
}
|
|
1577
|
-
} catch (error) {
|
|
1578
|
-
this.errorReporting('[sendOfflineMessage - daily message]', error);
|
|
1668
|
+
});
|
|
1579
1669
|
}
|
|
1580
|
-
|
|
1581
|
-
}//<--End of offline notification
|
|
1670
|
+
} //<--End of battery notification
|
|
1582
1671
|
|
|
1583
|
-
async
|
|
1584
|
-
// send
|
|
1672
|
+
async sendOfflineNotifications() {
|
|
1673
|
+
// send message if an device is offline
|
|
1585
1674
|
|
|
1586
|
-
this.log.debug(`Start the function: ${this.
|
|
1675
|
+
this.log.debug(`Start the function: ${this.sendOfflineNotifications.name}`);
|
|
1587
1676
|
|
|
1588
1677
|
try {
|
|
1589
|
-
|
|
1590
|
-
const
|
|
1591
|
-
const now = new Date(); // get date
|
|
1592
|
-
|
|
1593
|
-
// set indicator for send message first to 'false', after sending to 'true'
|
|
1594
|
-
if (now.getHours() < 11) await this.setStateAsync('info.lastOfflineNotification', false, true);
|
|
1678
|
+
let msg = '';
|
|
1679
|
+
const offlineDevicesCountOld = await this.getOwnInitValue('offlineCount');
|
|
1595
1680
|
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1681
|
+
if ((this.offlineDevicesCount !== offlineDevicesCountOld)) {
|
|
1682
|
+
if (this.offlineDevicesCount == 0) {
|
|
1683
|
+
msg = 'Alle Geräte sind Online.';
|
|
1684
|
+
} else if (this.offlineDevicesCount == 1) { // make singular if it is only one device
|
|
1685
|
+
msg = 'Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n';
|
|
1686
|
+
} else if (this.offlineDevicesCount >= 2) { //make plural if it is more than one device
|
|
1687
|
+
msg = `Folgende ${this.offlineDevicesCount} Geräte sind seit einiger Zeit nicht erreichbar: \n`;
|
|
1688
|
+
}
|
|
1599
1689
|
|
|
1600
1690
|
for (const id of this.offlineDevices) {
|
|
1601
|
-
msg = `${msg}
|
|
1691
|
+
msg = `${msg}\n${id['Device']} (${id['Last contact']})`;
|
|
1602
1692
|
}
|
|
1603
1693
|
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
await this.sendNotification(`Geräte Offline: ${msg}`);
|
|
1609
|
-
|
|
1610
|
-
await this.setStateAsync('info.lastOfflineNotification', true, true);
|
|
1611
|
-
}
|
|
1694
|
+
this.log.info(msg);
|
|
1695
|
+
await this.setStateAsync('lastNotification', msg, true);
|
|
1696
|
+
await this.sendNotification(msg);
|
|
1612
1697
|
}
|
|
1613
1698
|
} catch (error) {
|
|
1614
|
-
this.errorReporting('[
|
|
1699
|
+
this.errorReporting('[sendOfflineMessage]', error);
|
|
1615
1700
|
}
|
|
1616
|
-
this.log.debug(`Finished the function: ${this.
|
|
1617
|
-
}//<--End of
|
|
1618
|
-
|
|
1619
|
-
async sendBatteryNotifications() {
|
|
1620
|
-
// send message for low battery devices
|
|
1621
|
-
|
|
1622
|
-
this.log.debug(`Start the function: ${this.sendBatteryNotifications.name}`);
|
|
1701
|
+
this.log.debug(`Finished the function: ${this.sendOfflineNotifications.name}`);
|
|
1702
|
+
}//<--End of offline notification
|
|
1623
1703
|
|
|
1624
|
-
|
|
1704
|
+
async sendOfflineNotificationsShedule() {
|
|
1705
|
+
// send daily an overview with offline devices
|
|
1625
1706
|
|
|
1626
|
-
|
|
1627
|
-
const today = now.getDay();
|
|
1628
|
-
const checkDays = []; // list of selected days
|
|
1629
|
-
let checkToday; // indicator if selected day is today
|
|
1630
|
-
|
|
1631
|
-
// push the selected days in list
|
|
1632
|
-
if (this.config.checkMonday) checkDays.push(1);
|
|
1633
|
-
if (this.config.checkTuesday) checkDays.push(2);
|
|
1634
|
-
if (this.config.checkWednesday) checkDays.push(3);
|
|
1635
|
-
if (this.config.checkThursday) checkDays.push(4);
|
|
1636
|
-
if (this.config.checkFriday) checkDays.push(5);
|
|
1637
|
-
if (this.config.checkSaturday) checkDays.push(6);
|
|
1638
|
-
if (this.config.checkSunday) checkDays.push(0);
|
|
1639
|
-
|
|
1640
|
-
//Check if the message should be send today
|
|
1641
|
-
checkDays.forEach(object => {
|
|
1642
|
-
if ((object >= 0) && today == object) {
|
|
1643
|
-
checkToday = true;
|
|
1644
|
-
}
|
|
1645
|
-
});
|
|
1707
|
+
const time = (this.config.checkSendOfflineTime).split(':');
|
|
1646
1708
|
|
|
1647
|
-
|
|
1648
|
-
this.log.debug(`Number of selected days: ${checkDays.length}. Send Message on: ${(checkDays).join(', ')} ...`);
|
|
1649
|
-
} else {
|
|
1650
|
-
this.log.warn(`No days selected. Please check the instance configuration!`);
|
|
1651
|
-
return; // break off function if no day is selected
|
|
1652
|
-
}
|
|
1709
|
+
const checkDays = []; // list of selected days
|
|
1653
1710
|
|
|
1654
|
-
|
|
1655
|
-
|
|
1711
|
+
// push the selected days in list
|
|
1712
|
+
if (this.config.checkOfflineMonday) checkDays.push(1);
|
|
1713
|
+
if (this.config.checkOfflineTuesday) checkDays.push(2);
|
|
1714
|
+
if (this.config.checkOfflineWednesday) checkDays.push(3);
|
|
1715
|
+
if (this.config.checkOfflineThursday) checkDays.push(4);
|
|
1716
|
+
if (this.config.checkOfflineFriday) checkDays.push(5);
|
|
1717
|
+
if (this.config.checkOfflineSaturday) checkDays.push(6);
|
|
1718
|
+
if (this.config.checkOfflineSunday) checkDays.push(0);
|
|
1656
1719
|
|
|
1657
|
-
|
|
1658
|
-
|
|
1720
|
+
if (checkDays.length >= 1) { // check if an day is selected
|
|
1721
|
+
this.log.debug(`Number of selected days for daily offline message: ${checkDays.length}. Send Message on: ${(checkDays).join(', ')} ...`);
|
|
1722
|
+
} else {
|
|
1723
|
+
this.log.warn(`No days selected for daily offline message. Please check the instance configuration!`);
|
|
1724
|
+
return; // cancel function if no day is selected
|
|
1725
|
+
}
|
|
1659
1726
|
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1727
|
+
if (!isUnloaded) {
|
|
1728
|
+
const cron = '10 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
1729
|
+
schedule.scheduleJob(cron, () => {
|
|
1730
|
+
try {
|
|
1731
|
+
let msg = '';
|
|
1663
1732
|
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1733
|
+
for (const id of this.offlineDevices) {
|
|
1734
|
+
msg = `${msg}\n${id['Device']} (${id['Last contact']})`;
|
|
1735
|
+
}
|
|
1667
1736
|
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1737
|
+
if (this.offlineDevicesCount > 0) {
|
|
1738
|
+
this.log.info(`Geräte Offline: ${msg}`);
|
|
1739
|
+
this.setStateAsync('lastNotification', `Geräte Offline: ${msg}`, true);
|
|
1671
1740
|
|
|
1672
|
-
|
|
1741
|
+
this.sendNotification(`Geräte Offline: ${msg}`);
|
|
1742
|
+
}
|
|
1673
1743
|
|
|
1674
|
-
|
|
1744
|
+
} catch (error) {
|
|
1745
|
+
this.errorReporting('[sendOfflineNotificationsShedule]', error);
|
|
1675
1746
|
}
|
|
1676
|
-
}
|
|
1677
|
-
} catch (error) {
|
|
1678
|
-
this.errorReporting('[sendOfflineMessage]', error);
|
|
1747
|
+
});
|
|
1679
1748
|
}
|
|
1680
|
-
|
|
1681
|
-
this.log.debug(`Finished the function: ${this.sendBatteryNotifications.name}`);
|
|
1682
|
-
}//<--End of battery notification
|
|
1683
|
-
|
|
1749
|
+
}//<--End of daily offline notification
|
|
1684
1750
|
|
|
1685
1751
|
async resetVars() {
|
|
1686
1752
|
//Reset all arrays and counts
|
|
@@ -1809,79 +1875,407 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1809
1875
|
</tr>`;
|
|
1810
1876
|
}
|
|
1811
1877
|
|
|
1812
|
-
html += '</table>';
|
|
1813
|
-
return html;
|
|
1814
|
-
}
|
|
1878
|
+
html += '</table>';
|
|
1879
|
+
return html;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
/**
|
|
1883
|
+
* @param {object} devices - Device
|
|
1884
|
+
* @param {number} deviceCount - Counted devices
|
|
1885
|
+
*/
|
|
1886
|
+
async createOfflineListHTML(devices, deviceCount) {
|
|
1887
|
+
devices = devices.sort((a, b) => { return a.Device.localeCompare(b.Device); });
|
|
1888
|
+
let html = `<center>
|
|
1889
|
+
<b>Offline Devices: <font color=${deviceCount == 0 ? '#3bcf0e' : 'orange'}>${deviceCount}</b><small></small></font>
|
|
1890
|
+
<p></p>
|
|
1891
|
+
</center>
|
|
1892
|
+
<table width=100%>
|
|
1893
|
+
<tr>
|
|
1894
|
+
<th align=left>Device</th>
|
|
1895
|
+
<th align=center width=120>Adapter</th>
|
|
1896
|
+
<th align=center>Letzter Kontakt</th>
|
|
1897
|
+
</tr>
|
|
1898
|
+
<tr>
|
|
1899
|
+
<td colspan="5"><hr></td>
|
|
1900
|
+
</tr>`;
|
|
1901
|
+
|
|
1902
|
+
for (const device of devices) {
|
|
1903
|
+
html += `<tr>
|
|
1904
|
+
<td><font>${device.Device}</font></td>
|
|
1905
|
+
<td align=center><font>${device.Adapter}</font></td>
|
|
1906
|
+
<td align=center><font color=orange>${device['Last contact']}</font></td>
|
|
1907
|
+
</tr>`;
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
html += '</table>';
|
|
1911
|
+
return html;
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
/**
|
|
1915
|
+
* @param {object} [devices] - Device
|
|
1916
|
+
* @param {object} [deviceCount] - Counted devices
|
|
1917
|
+
* @param {object} [isLowBatteryList] - list Low Battery Devices
|
|
1918
|
+
*/
|
|
1919
|
+
async createBatteryListHTML(devices, deviceCount, isLowBatteryList) {
|
|
1920
|
+
devices = devices.sort((a, b) => { return a.Device.localeCompare(b.Device); });
|
|
1921
|
+
let html = `<center>
|
|
1922
|
+
<b>${isLowBatteryList == true ? 'Schwache ' : ''}Batterie Devices: <font color=${isLowBatteryList == true ? (deviceCount > 0 ? 'orange' : '#3bcf0e') : ''}>${deviceCount}</b></font>
|
|
1923
|
+
<p></p>
|
|
1924
|
+
</center>
|
|
1925
|
+
<table width=100%>
|
|
1926
|
+
<tr>
|
|
1927
|
+
<th align=left>Device</th>
|
|
1928
|
+
<th align=center width=120>Adapter</th>
|
|
1929
|
+
<th align=${isLowBatteryList ? 'center' : 'right'}>Batterie</th>
|
|
1930
|
+
</tr>
|
|
1931
|
+
<tr>
|
|
1932
|
+
<td colspan="5"><hr></td>
|
|
1933
|
+
</tr>`;
|
|
1934
|
+
|
|
1935
|
+
for (const device of devices) {
|
|
1936
|
+
html += `<tr>
|
|
1937
|
+
<td><font>${device.Device}</font></td>
|
|
1938
|
+
<td align=center><font>${device.Adapter}</font></td>`;
|
|
1939
|
+
|
|
1940
|
+
if (isLowBatteryList) {
|
|
1941
|
+
html += `<td align=center><font color=orange>${device.Battery}</font></td>`;
|
|
1942
|
+
} else {
|
|
1943
|
+
html += `<td align=right><font color=#3bcf0e>${device.Battery}</font></td>`;
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
html += `</tr>`;
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
html += '</table>';
|
|
1950
|
+
return html;
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
// create datapoints for each adapter
|
|
1954
|
+
/**
|
|
1955
|
+
* @param {object} adptName - Adaptername of devices
|
|
1956
|
+
**/
|
|
1957
|
+
async createDPsForEachAdapter(adptName) {
|
|
1958
|
+
|
|
1959
|
+
await this.setObjectNotExistsAsync(`${adptName}`, {
|
|
1960
|
+
type: 'channel',
|
|
1961
|
+
common: {
|
|
1962
|
+
name: adptName,
|
|
1963
|
+
},
|
|
1964
|
+
native: {},
|
|
1965
|
+
});
|
|
1966
|
+
|
|
1967
|
+
await this.setObjectNotExistsAsync(`${adptName}.offlineCount`, {
|
|
1968
|
+
'type': 'state',
|
|
1969
|
+
'common': {
|
|
1970
|
+
'name': {
|
|
1971
|
+
'en': 'Number of devices offline',
|
|
1972
|
+
'de': 'Anzahl der Geräte offline',
|
|
1973
|
+
'ru': 'Количество устройств offline',
|
|
1974
|
+
'pt': 'Número de dispositivos offline',
|
|
1975
|
+
'nl': 'Nummer van apparatuur offline',
|
|
1976
|
+
'fr': 'Nombre de dispositifs hors ligne',
|
|
1977
|
+
'it': 'Numero di dispositivi offline',
|
|
1978
|
+
'es': 'Número de dispositivos sin conexión',
|
|
1979
|
+
'pl': 'Ilość urządzeń offline',
|
|
1980
|
+
'zh-cn': '线内装置数量'
|
|
1981
|
+
},
|
|
1982
|
+
'type': 'number',
|
|
1983
|
+
'role': 'value',
|
|
1984
|
+
'read': true,
|
|
1985
|
+
'write': false,
|
|
1986
|
+
},
|
|
1987
|
+
'native': {}
|
|
1988
|
+
});
|
|
1989
|
+
|
|
1990
|
+
await this.setObjectNotExistsAsync(`${adptName}.offlineList`, {
|
|
1991
|
+
'type': 'state',
|
|
1992
|
+
'common': {
|
|
1993
|
+
'name': {
|
|
1994
|
+
'en': 'List of offline devices',
|
|
1995
|
+
'de': 'Liste der Offline-Geräte',
|
|
1996
|
+
'ru': 'Список оффлайн устройств',
|
|
1997
|
+
'pt': 'Lista de dispositivos off-line',
|
|
1998
|
+
'nl': 'List van offline apparatuur',
|
|
1999
|
+
'fr': 'Liste des dispositifs hors ligne',
|
|
2000
|
+
'it': 'Elenco dei dispositivi offline',
|
|
2001
|
+
'es': 'Lista de dispositivos sin conexión',
|
|
2002
|
+
'pl': 'Lista urządzeń offline',
|
|
2003
|
+
'zh-cn': '线装置清单'
|
|
2004
|
+
},
|
|
2005
|
+
'type': 'array',
|
|
2006
|
+
'role': 'json',
|
|
2007
|
+
'read': true,
|
|
2008
|
+
'write': false,
|
|
2009
|
+
},
|
|
2010
|
+
'native': {}
|
|
2011
|
+
});
|
|
2012
|
+
|
|
2013
|
+
await this.setObjectNotExistsAsync(`${adptName}.listAll`, {
|
|
2014
|
+
'type': 'state',
|
|
2015
|
+
'common': {
|
|
2016
|
+
'name': {
|
|
2017
|
+
'en': 'List of all devices',
|
|
2018
|
+
'de': 'Liste aller Geräte',
|
|
2019
|
+
'ru': 'Список всех устройств',
|
|
2020
|
+
'pt': 'Lista de todos os dispositivos',
|
|
2021
|
+
'nl': 'List van alle apparaten',
|
|
2022
|
+
'fr': 'Liste de tous les dispositifs',
|
|
2023
|
+
'it': 'Elenco di tutti i dispositivi',
|
|
2024
|
+
'es': 'Lista de todos los dispositivos',
|
|
2025
|
+
'pl': 'Lista wszystkich urządzeń',
|
|
2026
|
+
'zh-cn': '所有装置清单'
|
|
2027
|
+
},
|
|
2028
|
+
'type': 'array',
|
|
2029
|
+
'role': 'json',
|
|
2030
|
+
'read': true,
|
|
2031
|
+
'write': false,
|
|
2032
|
+
},
|
|
2033
|
+
'native': {}
|
|
2034
|
+
});
|
|
2035
|
+
|
|
2036
|
+
await this.setObjectNotExistsAsync(`${adptName}.linkQualityList`, {
|
|
2037
|
+
'type': 'state',
|
|
2038
|
+
'common': {
|
|
2039
|
+
'name': {
|
|
2040
|
+
'en': 'List of devices with signal strength',
|
|
2041
|
+
'de': 'Liste der Geräte mit Signalstärke',
|
|
2042
|
+
'ru': 'Список устройств с силой сигнала',
|
|
2043
|
+
'pt': 'Lista de dispositivos com força de sinal',
|
|
2044
|
+
'nl': 'List van apparaten met signaalkracht',
|
|
2045
|
+
'fr': 'Liste des dispositifs avec force de signal',
|
|
2046
|
+
'it': 'Elenco dei dispositivi con forza del segnale',
|
|
2047
|
+
'es': 'Lista de dispositivos con fuerza de señal',
|
|
2048
|
+
'pl': 'Lista urządzeń z siłą sygnałową',
|
|
2049
|
+
'zh-cn': '具有信号实力的装置清单'
|
|
2050
|
+
},
|
|
2051
|
+
'type': 'array',
|
|
2052
|
+
'role': 'json',
|
|
2053
|
+
'read': true,
|
|
2054
|
+
'write': false,
|
|
2055
|
+
},
|
|
2056
|
+
'native': {}
|
|
2057
|
+
});
|
|
2058
|
+
|
|
2059
|
+
await this.setObjectNotExistsAsync(`${adptName}.countAll`, {
|
|
2060
|
+
'type': 'state',
|
|
2061
|
+
'common': {
|
|
2062
|
+
'name': {
|
|
2063
|
+
'en': 'Number of all devices',
|
|
2064
|
+
'de': 'Anzahl aller Geräte',
|
|
2065
|
+
'ru': 'Количество всех устройств',
|
|
2066
|
+
'pt': 'Número de todos os dispositivos',
|
|
2067
|
+
'nl': 'Nummer van alle apparaten',
|
|
2068
|
+
'fr': 'Nombre de tous les appareils',
|
|
2069
|
+
'it': 'Numero di tutti i dispositivi',
|
|
2070
|
+
'es': 'Número de todos los dispositivos',
|
|
2071
|
+
'pl': 'Ilość wszystkich urządzeń',
|
|
2072
|
+
'zh-cn': '所有装置的数目'
|
|
2073
|
+
},
|
|
2074
|
+
'type': 'number',
|
|
2075
|
+
'role': 'value',
|
|
2076
|
+
'read': true,
|
|
2077
|
+
'write': false,
|
|
2078
|
+
},
|
|
2079
|
+
'native': {}
|
|
2080
|
+
});
|
|
2081
|
+
|
|
2082
|
+
await this.setObjectNotExistsAsync(`${adptName}.batteryList`, {
|
|
2083
|
+
'type': 'state',
|
|
2084
|
+
'common': {
|
|
2085
|
+
'name': {
|
|
2086
|
+
'en': 'List of devices with battery state',
|
|
2087
|
+
'de': 'Liste der Geräte mit Batteriezustand',
|
|
2088
|
+
'ru': 'Список устройств с состоянием батареи',
|
|
2089
|
+
'pt': 'Lista de dispositivos com estado da bateria',
|
|
2090
|
+
'nl': 'List van apparaten met batterij staat',
|
|
2091
|
+
'fr': 'Liste des appareils avec état de batterie',
|
|
2092
|
+
'it': 'Elenco dei dispositivi con stato della batteria',
|
|
2093
|
+
'es': 'Lista de dispositivos con estado de batería',
|
|
2094
|
+
'pl': 'Lista urządzeń z baterią stanową',
|
|
2095
|
+
'zh-cn': '电池国装置清单'
|
|
2096
|
+
},
|
|
2097
|
+
'type': 'array',
|
|
2098
|
+
'role': 'json',
|
|
2099
|
+
'read': true,
|
|
2100
|
+
'write': false,
|
|
2101
|
+
},
|
|
2102
|
+
'native': {}
|
|
2103
|
+
});
|
|
1815
2104
|
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
2105
|
+
await this.setObjectNotExistsAsync(`${adptName}.lowBatteryList`, {
|
|
2106
|
+
'type': 'state',
|
|
2107
|
+
'common': {
|
|
2108
|
+
'name': {
|
|
2109
|
+
'en': 'List of devices with low battery state',
|
|
2110
|
+
'de': 'Liste der Geräte mit niedrigem Batteriezustand',
|
|
2111
|
+
'ru': 'Список устройств с низким состоянием батареи',
|
|
2112
|
+
'pt': 'Lista de dispositivos com baixo estado da bateria',
|
|
2113
|
+
'nl': 'List van apparaten met lage batterij staat',
|
|
2114
|
+
'fr': 'Liste des appareils à faible état de batterie',
|
|
2115
|
+
'it': 'Elenco di dispositivi con stato di batteria basso',
|
|
2116
|
+
'es': 'Lista de dispositivos con estado de batería bajo',
|
|
2117
|
+
'pl': 'Lista urządzeń o niskim stanie baterii',
|
|
2118
|
+
'zh-cn': '低电池国家装置清单'
|
|
2119
|
+
},
|
|
2120
|
+
'type': 'array',
|
|
2121
|
+
'role': 'json',
|
|
2122
|
+
'read': true,
|
|
2123
|
+
'write': false,
|
|
2124
|
+
},
|
|
2125
|
+
'native': {}
|
|
2126
|
+
});
|
|
1835
2127
|
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
2128
|
+
await this.setObjectNotExistsAsync(`${adptName}.lowBatteryCount`, {
|
|
2129
|
+
'type': 'state',
|
|
2130
|
+
'common': {
|
|
2131
|
+
'name': {
|
|
2132
|
+
'en': 'Number of devices with low battery',
|
|
2133
|
+
'de': 'Anzahl der Geräte mit niedriger Batterie',
|
|
2134
|
+
'ru': 'Количество устройств c низкой батареей',
|
|
2135
|
+
'pt': 'Número de dispositivos com bateria baixa',
|
|
2136
|
+
'nl': 'Nummer van apparaten met lage batterij',
|
|
2137
|
+
'fr': 'Nombre de dispositifs avec batterie basse',
|
|
2138
|
+
'it': 'Numero di dispositivi con batteria bassa',
|
|
2139
|
+
'es': 'Número de dispositivos con batería baja',
|
|
2140
|
+
'pl': 'Liczba urządzeń z niską baterią',
|
|
2141
|
+
'zh-cn': '低电池的装置数量'
|
|
2142
|
+
},
|
|
2143
|
+
'type': 'number',
|
|
2144
|
+
'role': 'value',
|
|
2145
|
+
'read': true,
|
|
2146
|
+
'write': false,
|
|
2147
|
+
},
|
|
2148
|
+
'native': {}
|
|
2149
|
+
});
|
|
1843
2150
|
|
|
1844
|
-
|
|
1845
|
-
|
|
2151
|
+
await this.setObjectNotExistsAsync(`${adptName}.batteryCount`, {
|
|
2152
|
+
'type': 'state',
|
|
2153
|
+
'common': {
|
|
2154
|
+
'name': {
|
|
2155
|
+
'en': 'Number of devices with battery',
|
|
2156
|
+
'de': 'Anzahl der Geräte mit Batterie',
|
|
2157
|
+
'ru': 'Количество устройств c батареей',
|
|
2158
|
+
'pt': 'Número de dispositivos com bateria',
|
|
2159
|
+
'nl': 'Nummer van apparaten met batterij',
|
|
2160
|
+
'fr': 'Nombre de dispositifs avec batterie',
|
|
2161
|
+
'it': 'Numero di dispositivi con batteria',
|
|
2162
|
+
'es': 'Número de dispositivos con batería',
|
|
2163
|
+
'pl': 'Liczba urządzeń z baterią',
|
|
2164
|
+
'zh-cn': '电池的装置数量'
|
|
2165
|
+
},
|
|
2166
|
+
'type': 'number',
|
|
2167
|
+
'role': 'value',
|
|
2168
|
+
'read': true,
|
|
2169
|
+
'write': false,
|
|
2170
|
+
},
|
|
2171
|
+
'native': {}
|
|
2172
|
+
});
|
|
1846
2173
|
}
|
|
1847
2174
|
|
|
1848
2175
|
/**
|
|
1849
|
-
* @param {object} [
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
*/
|
|
1853
|
-
async createBatteryListHTML(devices, deviceCount, isLowBatteryList) {
|
|
1854
|
-
devices = devices.sort((a, b) => { return a.Device.localeCompare(b.Device); });
|
|
1855
|
-
let html = `<center>
|
|
1856
|
-
<b>${isLowBatteryList == true ? 'Schwache ' : ''}Batterie Devices: <font color=${isLowBatteryList == true ? (deviceCount > 0 ? 'orange' : '#3bcf0e') : ''}>${deviceCount}</b></font>
|
|
1857
|
-
<p></p>
|
|
1858
|
-
</center>
|
|
1859
|
-
<table width=100%>
|
|
1860
|
-
<tr>
|
|
1861
|
-
<th align=left>Device</th>
|
|
1862
|
-
<th align=center width=120>Adapter</th>
|
|
1863
|
-
<th align=${isLowBatteryList ? 'center' : 'right'}>Batterie</th>
|
|
1864
|
-
</tr>
|
|
1865
|
-
<tr>
|
|
1866
|
-
<td colspan="5"><hr></td>
|
|
1867
|
-
</tr>`;
|
|
2176
|
+
* @param {object} [adptName] - Adaptername of devices
|
|
2177
|
+
**/
|
|
2178
|
+
async createHtmlListDatapoints(adptName) {
|
|
1868
2179
|
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
2180
|
+
let dpSubFolder;
|
|
2181
|
+
//write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
|
|
2182
|
+
if (adptName) {
|
|
2183
|
+
dpSubFolder = `${adptName}.`;
|
|
2184
|
+
} else {
|
|
2185
|
+
dpSubFolder = '';
|
|
2186
|
+
}
|
|
1873
2187
|
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
2188
|
+
await this.setObjectNotExistsAsync(`${dpSubFolder}offlineListHTML`, {
|
|
2189
|
+
'type': 'state',
|
|
2190
|
+
'common': {
|
|
2191
|
+
'name': {
|
|
2192
|
+
'en': 'HTML List of offline devices',
|
|
2193
|
+
'de': 'HTML Liste der Offline-Geräte',
|
|
2194
|
+
'ru': 'HTML Список оффлайн устройств',
|
|
2195
|
+
'pt': 'HTML Lista de dispositivos off-line',
|
|
2196
|
+
'nl': 'HTML List van offline apparatuur',
|
|
2197
|
+
'fr': 'HTML Liste des dispositifs hors ligne',
|
|
2198
|
+
'it': 'HTML Elenco dei dispositivi offline',
|
|
2199
|
+
'es': 'HTML Lista de dispositivos sin conexión',
|
|
2200
|
+
'pl': 'HTML Lista urządzeń offline',
|
|
2201
|
+
'zh-cn': 'HTML 线装置清单'
|
|
2202
|
+
},
|
|
2203
|
+
'type': 'string',
|
|
2204
|
+
'role': 'html',
|
|
2205
|
+
'read': true,
|
|
2206
|
+
'write': false,
|
|
2207
|
+
},
|
|
2208
|
+
'native': {}
|
|
2209
|
+
});
|
|
1879
2210
|
|
|
1880
|
-
|
|
1881
|
-
|
|
2211
|
+
await this.setObjectNotExistsAsync(`${dpSubFolder}linkQualityListHTML`, {
|
|
2212
|
+
'type': 'state',
|
|
2213
|
+
'common': {
|
|
2214
|
+
'name': {
|
|
2215
|
+
'en': 'HTML List of devices with signal strength',
|
|
2216
|
+
'de': 'HTML Liste der Geräte mit Signalstärke',
|
|
2217
|
+
'ru': 'HTML Список устройств с силой сигнала',
|
|
2218
|
+
'pt': 'HTML Lista de dispositivos com força de sinal',
|
|
2219
|
+
'nl': 'HTML List van apparaten met signaalkracht',
|
|
2220
|
+
'fr': 'HTML Liste des dispositifs avec force de signal',
|
|
2221
|
+
'it': 'HTML Elenco dei dispositivi con forza del segnale',
|
|
2222
|
+
'es': 'HTML Lista de dispositivos con fuerza de señal',
|
|
2223
|
+
'pl': 'HTML Lista urządzeń z siłą sygnałową',
|
|
2224
|
+
'zh-cn': 'HTML 具有信号实力的装置清单'
|
|
2225
|
+
},
|
|
2226
|
+
'type': 'string',
|
|
2227
|
+
'role': 'value',
|
|
2228
|
+
'read': true,
|
|
2229
|
+
'write': false,
|
|
2230
|
+
},
|
|
2231
|
+
'native': {}
|
|
2232
|
+
});
|
|
1882
2233
|
|
|
1883
|
-
|
|
1884
|
-
|
|
2234
|
+
await this.setObjectNotExistsAsync(`${dpSubFolder}batteryListHTML`, {
|
|
2235
|
+
'type': 'state',
|
|
2236
|
+
'common': {
|
|
2237
|
+
'name': {
|
|
2238
|
+
'en': 'HTML List of devices with battery state',
|
|
2239
|
+
'de': 'HTML Liste der Geräte mit Batteriezustand',
|
|
2240
|
+
'ru': 'HTML Список устройств с состоянием батареи',
|
|
2241
|
+
'pt': 'HTML Lista de dispositivos com estado da bateria',
|
|
2242
|
+
'nl': 'HTML List van apparaten met batterij staat',
|
|
2243
|
+
'fr': 'HTML Liste des appareils avec état de batterie',
|
|
2244
|
+
'it': 'HTML Elenco dei dispositivi con stato della batteria',
|
|
2245
|
+
'es': 'HTML Lista de dispositivos con estado de batería',
|
|
2246
|
+
'pl': 'HTML Lista urządzeń z baterią stanową',
|
|
2247
|
+
'zh-cn': 'HTML 电池国装置清单'
|
|
2248
|
+
},
|
|
2249
|
+
'type': 'string',
|
|
2250
|
+
'role': 'html',
|
|
2251
|
+
'read': true,
|
|
2252
|
+
'write': false,
|
|
2253
|
+
},
|
|
2254
|
+
'native': {}
|
|
2255
|
+
});
|
|
2256
|
+
|
|
2257
|
+
await this.setObjectNotExistsAsync(`${dpSubFolder}lowBatteryListHTML`, {
|
|
2258
|
+
'type': 'state',
|
|
2259
|
+
'common': {
|
|
2260
|
+
'name': {
|
|
2261
|
+
'en': 'HTML List of devices with low battery state',
|
|
2262
|
+
'de': 'HTML Liste der Geräte mit niedrigem Batteriezustand',
|
|
2263
|
+
'ru': 'HTML Список устройств с низким состоянием батареи',
|
|
2264
|
+
'pt': 'HTML Lista de dispositivos com baixo estado da bateria',
|
|
2265
|
+
'nl': 'HTML List van apparaten met lage batterij staat',
|
|
2266
|
+
'fr': 'HTML Liste des appareils à faible état de batterie',
|
|
2267
|
+
'it': 'HTML Elenco di dispositivi con stato di batteria basso',
|
|
2268
|
+
'es': 'HTML Lista de dispositivos con estado de batería bajo',
|
|
2269
|
+
'pl': 'HTML Lista urządzeń o niskim stanie baterii',
|
|
2270
|
+
'zh-cn': 'HTML 低电池国家装置清单'
|
|
2271
|
+
},
|
|
2272
|
+
'type': 'string',
|
|
2273
|
+
'role': 'html',
|
|
2274
|
+
'read': true,
|
|
2275
|
+
'write': false,
|
|
2276
|
+
},
|
|
2277
|
+
'native': {}
|
|
2278
|
+
});
|
|
1885
2279
|
}
|
|
1886
2280
|
|
|
1887
2281
|
/**
|
|
@@ -1909,12 +2303,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1909
2303
|
*/
|
|
1910
2304
|
onUnload(callback) {
|
|
1911
2305
|
try {
|
|
1912
|
-
this.log.info('cleaned everything up...');
|
|
1913
|
-
|
|
1914
2306
|
if (this.refreshDataTimeout) {
|
|
1915
2307
|
this.log.debug('clearing refresh timeout');
|
|
1916
2308
|
this.clearTimeout(this.refreshDataTimeout);
|
|
1917
2309
|
}
|
|
2310
|
+
isUnloaded = true;
|
|
2311
|
+
|
|
2312
|
+
this.log.info('cleaned everything up...');
|
|
1918
2313
|
|
|
1919
2314
|
callback();
|
|
1920
2315
|
} catch (e) {
|