iobroker.device-watcher 0.2.0 → 0.2.4
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/LICENSE +1 -1
- package/README.md +14 -2
- package/admin/i18n/de/translations.json +27 -26
- package/admin/i18n/en/translations.json +4 -4
- package/admin/i18n/es/translations.json +22 -31
- package/admin/i18n/fr/translations.json +23 -32
- package/admin/i18n/it/translations.json +22 -31
- package/admin/i18n/nl/translations.json +24 -33
- package/admin/i18n/pl/translations.json +23 -32
- package/admin/i18n/pt/translations.json +24 -33
- package/admin/i18n/ru/translations.json +22 -31
- package/admin/i18n/zh-cn/translations.json +22 -31
- package/admin/jsonConfig.json +9 -9
- package/admin/words.js +0 -6
- package/io-package.json +235 -51
- package/main.js +622 -629
- package/package.json +21 -18
package/main.js
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
const utils = require('@iobroker/adapter-core');
|
|
8
8
|
const adapterName = require('./package.json').name.split('.').pop();
|
|
9
9
|
|
|
10
|
+
// Sentry error reporting, disable when testing code!
|
|
11
|
+
const enableSendSentry = true;
|
|
12
|
+
|
|
10
13
|
class DeviceWatcher extends utils.Adapter {
|
|
11
14
|
|
|
12
15
|
constructor(options) {
|
|
@@ -39,15 +42,10 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
39
42
|
this.batteryPoweredCount = 0;
|
|
40
43
|
this.lowBatteryPoweredCount = 0;
|
|
41
44
|
|
|
42
|
-
this.deviceReachable
|
|
45
|
+
this.deviceReachable = '';
|
|
43
46
|
|
|
44
47
|
// arrays of supported adapters
|
|
45
48
|
this.arrApart = {
|
|
46
|
-
//**** This Datapoints are only for the dev ****//
|
|
47
|
-
test: {'Selektor':'0_userdata.*.UNREACH', 'adapter':'homematic', 'rssiState':'.RSSI_DEVICE', 'battery':'.OPERATING_VOLTAGE', 'reach':'.UNREACH', 'isLowBat':'.LOW_BAT'},
|
|
48
|
-
test2: {'Selektor':'0_userdata.*.alive', 'adapter':'test2', 'rssiState': '.Wifi_RSSI', 'battery':'none', 'reach':'.alive', 'isLowBat':'none', 'id':'.name'},
|
|
49
|
-
test3: {'Selektor':'0_userdata.*.link_quality', 'adapter':'test3', 'battery':'.battery', 'reach':'available', 'isLowBat':'none'},
|
|
50
|
-
//**** End of Dev Datapoints ****//
|
|
51
49
|
alexa2: {
|
|
52
50
|
'Selektor':'alexa2.*.online',
|
|
53
51
|
'adapter':'alexa2',
|
|
@@ -75,7 +73,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
75
73
|
'adapter':'zigbee',
|
|
76
74
|
'battery':'.battery',
|
|
77
75
|
'reach':'.available',
|
|
78
|
-
'isLowBat':'
|
|
76
|
+
'isLowBat':'.battery_low'
|
|
79
77
|
},
|
|
80
78
|
sonoff: {
|
|
81
79
|
'Selektor':'sonoff.*.Uptime',
|
|
@@ -131,7 +129,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
131
129
|
},
|
|
132
130
|
hueExt: {
|
|
133
131
|
'Selektor':'hue-extended.*.reachable',
|
|
134
|
-
'adapter':'hue
|
|
132
|
+
'adapter':'hue-extended',
|
|
135
133
|
'battery':'.config.battery',
|
|
136
134
|
'reach':'.reachable',
|
|
137
135
|
'isLowBat':'none'
|
|
@@ -174,8 +172,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
174
172
|
},
|
|
175
173
|
nukiExt: {
|
|
176
174
|
'Selektor':'nuki-extended.*.batteryCritical',
|
|
177
|
-
'adapter':'
|
|
178
|
-
'battery':'
|
|
175
|
+
'adapter':'nuki-extended',
|
|
176
|
+
'battery':'.batteryCharge',
|
|
179
177
|
'reach':'none',
|
|
180
178
|
'isLowBat':'.batteryCritical'
|
|
181
179
|
}
|
|
@@ -187,191 +185,334 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
187
185
|
|
|
188
186
|
try {
|
|
189
187
|
await this.main();
|
|
190
|
-
if (this.config.checkSendOfflineMsg) await this.sendOfflineNotifications();
|
|
191
|
-
if (this.config.checkSendBatteryMsg) await this.sendBatteryNotifications();
|
|
192
188
|
await this.writeDatapoints();
|
|
193
189
|
this.log.debug('all done, exiting');
|
|
194
190
|
this.terminate ? this.terminate('Everything done. Going to terminate till next schedule', 11) : process.exit(0);
|
|
195
|
-
} catch (
|
|
196
|
-
this.
|
|
191
|
+
} catch (error) {
|
|
192
|
+
this.errorReporting('[onReady]', error);
|
|
197
193
|
this.terminate ? this.terminate(15) : process.exit(15);
|
|
198
194
|
}
|
|
199
195
|
}
|
|
200
196
|
|
|
201
|
-
|
|
197
|
+
|
|
198
|
+
async main() {
|
|
199
|
+
this.log.debug(`Function started: ${this.main.name}`);
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
this.supAdapter = {
|
|
203
|
+
alexa2: this.config.alexa2Devices,
|
|
204
|
+
esphome: this.config.esphomeDevices,
|
|
205
|
+
zigbee: this.config.zigbeeDevices,
|
|
206
|
+
ble: this.config.bleDevices,
|
|
207
|
+
sonoff: this.config.sonoffDevices,
|
|
208
|
+
shelly: this.config.shellyDevices,
|
|
209
|
+
homematic: this.config.homematicDevices,
|
|
210
|
+
deconz: this.config.deconzDevices,
|
|
211
|
+
zwave: this.config.zwaveDevices,
|
|
212
|
+
dect: this.config.dectDevices,
|
|
213
|
+
hue: this.config.hueDevices,
|
|
214
|
+
hueExt: this.config.hueExtDevices,
|
|
215
|
+
nukiExt: this.config.nukiExtDevices,
|
|
216
|
+
ping: this.config.pingDevices,
|
|
217
|
+
switchbotBle: this.config.switchbotBleDevices,
|
|
218
|
+
sonos: this.config.sonosDevices,
|
|
219
|
+
mihome: this.config.mihomeDevices,
|
|
220
|
+
mihomeGW: this.config.mihomeDevices
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
for(const [id] of Object.entries(this.arrApart)) {
|
|
224
|
+
if (this.supAdapter[id]) {
|
|
225
|
+
this.arrDev.push(this.arrApart[id]);
|
|
226
|
+
this.adapterSelected.push(await this.capitalize(id));
|
|
227
|
+
this.log.debug(JSON.stringify(this.arrDev));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
//Check if an Adapter is selected.
|
|
232
|
+
if (this.adapterSelected.length >= 1) {
|
|
233
|
+
this.log.info(`Number of selected adapters: ${this.adapterSelected.length}. Loading data from: ${(this.adapterSelected).join(', ')} ...`);
|
|
234
|
+
} else {
|
|
235
|
+
this.log.warn(`No adapter selected. Please check the instance configuration!`);
|
|
236
|
+
return; // cancel run if no adapter is selected
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
//create and fill datapoints for each adapter if selected
|
|
240
|
+
try {
|
|
241
|
+
for(const [id] of Object.entries(this.arrApart)) {
|
|
242
|
+
if (this.supAdapter[id]) {
|
|
243
|
+
|
|
244
|
+
if (this.config.createOwnFolder) {
|
|
245
|
+
await this.createDPsForEachAdapter(id);
|
|
246
|
+
this.log.debug(`Created datapoints for ${await this.capitalize(id)}`);
|
|
247
|
+
await this.createDataForEachAdapter(id);
|
|
248
|
+
this.log.debug(`Created and filled data for each adapter`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
} catch (error) {
|
|
253
|
+
this.errorReporting('[main - create and fill datapoints for each adapter]', error);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// creating counts and lists of all selected adapter
|
|
257
|
+
try {
|
|
258
|
+
await this.createDataOfAllAdapter();
|
|
259
|
+
this.log.debug(`Created and filled data for all adapters`);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
this.errorReporting('[main - create data of all adapter]', error);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
} catch (error) {
|
|
265
|
+
this.errorReporting('[main]', error);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
this.log.debug(`Function finished: ${this.main.name}`);
|
|
269
|
+
} //<--End of main function
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* @param {string} [sentence] - Word which should be capitalize
|
|
274
|
+
**/
|
|
202
275
|
async capitalize(sentence)
|
|
203
276
|
{
|
|
204
277
|
//make the first letter uppercase
|
|
205
278
|
return sentence && sentence[0].toUpperCase() + sentence.slice(1);
|
|
206
279
|
}
|
|
207
280
|
|
|
281
|
+
/**
|
|
282
|
+
* @param {object} [obj] - State of datapoint
|
|
283
|
+
**/
|
|
208
284
|
async getInitValue(obj) {
|
|
209
285
|
//state can be null or undefinded
|
|
210
286
|
const foreignState = await this.getForeignStateAsync(obj);
|
|
211
287
|
if (foreignState) return foreignState.val;
|
|
212
288
|
}
|
|
213
289
|
|
|
290
|
+
/**
|
|
291
|
+
* @param {object} [obj] - State of own datapoint
|
|
292
|
+
**/
|
|
214
293
|
async getOwnInitValue(obj) {
|
|
215
294
|
//state can be null or undefinded for own states
|
|
216
295
|
const stateVal = await this.getStateAsync(obj);
|
|
217
296
|
if (stateVal) return stateVal.val;
|
|
218
297
|
}
|
|
219
298
|
|
|
220
|
-
//
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
device: this.config.devicePushover,
|
|
226
|
-
priority: this.config.prioPushover
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
async sendTelegram(text) {
|
|
231
|
-
await this.sendToAsync(this.config.instanceTelegram, 'send', {
|
|
232
|
-
text: text,
|
|
233
|
-
user: this.config.deviceTelegram,
|
|
234
|
-
chatId: this.config.chatIdTelegram
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
async sendWhatsapp(text) {
|
|
239
|
-
await this.sendToAsync(this.config.instanceWhatsapp, 'send', {
|
|
240
|
-
text: text,
|
|
241
|
-
phone: this.config.phoneWhatsapp
|
|
242
|
-
});
|
|
243
|
-
}
|
|
299
|
+
//create datapoints for each adapter
|
|
300
|
+
/**
|
|
301
|
+
* @param {object} [adptName] - Adaptername of devices
|
|
302
|
+
**/
|
|
303
|
+
async createDPsForEachAdapter(adptName) {
|
|
244
304
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
305
|
+
await this.setObjectNotExistsAsync(`${adptName}`, {
|
|
306
|
+
type: 'channel',
|
|
307
|
+
common: {
|
|
308
|
+
name: adptName,
|
|
309
|
+
},
|
|
310
|
+
native: {},
|
|
250
311
|
});
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
async sendJarvis(text) {
|
|
254
|
-
await this.setForeignStateAsync(`${this.config.instanceJarvis}.addNotification`, text);
|
|
255
312
|
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
async sendLovelace(text) {
|
|
259
|
-
await this.setForeignStateAsync(`${this.config.instanceLovelace}.notifications.add`, text);
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
//create datapoints for each adapter
|
|
264
|
-
async createDPsForEachAdapter(adptName) {
|
|
265
313
|
await this.setObjectNotExistsAsync(`${adptName}.offlineCount`, {
|
|
266
314
|
'type': 'state',
|
|
267
315
|
'common': {
|
|
268
|
-
'name':
|
|
316
|
+
'name': {
|
|
317
|
+
'en': 'Number of devices offline',
|
|
318
|
+
'de': 'Anzahl der Geräte offline',
|
|
319
|
+
'ru': 'Количество устройств offline',
|
|
320
|
+
'pt': 'Número de dispositivos offline',
|
|
321
|
+
'nl': 'Nummer van apparatuur offline',
|
|
322
|
+
'fr': 'Nombre de dispositifs hors ligne',
|
|
323
|
+
'it': 'Numero di dispositivi offline',
|
|
324
|
+
'es': 'Número de dispositivos sin conexión',
|
|
325
|
+
'pl': 'Ilość urządzeń offline',
|
|
326
|
+
'zh-cn': '线内装置数量'
|
|
327
|
+
},
|
|
269
328
|
'type': 'number',
|
|
270
329
|
'role': 'value',
|
|
271
330
|
'read': true,
|
|
272
331
|
'write': false,
|
|
273
|
-
'def': 0
|
|
274
332
|
},
|
|
275
333
|
'native': {}
|
|
276
334
|
});
|
|
277
335
|
await this.setObjectNotExistsAsync(`${adptName}.offlineList`, {
|
|
278
336
|
'type': 'state',
|
|
279
337
|
'common': {
|
|
280
|
-
'name':
|
|
338
|
+
'name': {
|
|
339
|
+
'en': 'List of offline devices',
|
|
340
|
+
'de': 'Liste der Offline-Geräte',
|
|
341
|
+
'ru': 'Список оффлайн устройств',
|
|
342
|
+
'pt': 'Lista de dispositivos off-line',
|
|
343
|
+
'nl': 'List van offline apparatuur',
|
|
344
|
+
'fr': 'Liste des dispositifs hors ligne',
|
|
345
|
+
'it': 'Elenco dei dispositivi offline',
|
|
346
|
+
'es': 'Lista de dispositivos sin conexión',
|
|
347
|
+
'pl': 'Lista urządzeń offline',
|
|
348
|
+
'zh-cn': '线装置清单'
|
|
349
|
+
},
|
|
281
350
|
'type': 'array',
|
|
282
351
|
'role': 'json',
|
|
283
352
|
'read': true,
|
|
284
353
|
'write': false,
|
|
285
|
-
'def': [{Device: '--keine--', Adapter: '', Last_contact: ''}]
|
|
286
354
|
},
|
|
287
355
|
'native': {}
|
|
288
356
|
});
|
|
289
357
|
await this.setObjectNotExistsAsync(`${adptName}.listAll`, {
|
|
290
358
|
'type': 'state',
|
|
291
359
|
'common': {
|
|
292
|
-
'name':
|
|
360
|
+
'name': {
|
|
361
|
+
'en': 'List of all devices',
|
|
362
|
+
'de': 'Liste aller Geräte',
|
|
363
|
+
'ru': 'Список всех устройств',
|
|
364
|
+
'pt': 'Lista de todos os dispositivos',
|
|
365
|
+
'nl': 'List van alle apparaten',
|
|
366
|
+
'fr': 'Liste de tous les dispositifs',
|
|
367
|
+
'it': 'Elenco di tutti i dispositivi',
|
|
368
|
+
'es': 'Lista de todos los dispositivos',
|
|
369
|
+
'pl': 'Lista wszystkich urządzeń',
|
|
370
|
+
'zh-cn': '所有装置清单'
|
|
371
|
+
},
|
|
293
372
|
'type': 'array',
|
|
294
373
|
'role': 'json',
|
|
295
374
|
'read': true,
|
|
296
375
|
'write': false,
|
|
297
|
-
'def': [{Device: '--keine--', Adapter: '', Battery: '', Last_contact: '', Link_quality: ''}]
|
|
298
376
|
},
|
|
299
377
|
'native': {}
|
|
300
378
|
});
|
|
301
379
|
await this.setObjectNotExistsAsync(`${adptName}.linkQualityList`, {
|
|
302
380
|
'type': 'state',
|
|
303
381
|
'common': {
|
|
304
|
-
'name':
|
|
382
|
+
'name': {
|
|
383
|
+
'en': 'List of devices with signal strength',
|
|
384
|
+
'de': 'Liste der Geräte mit Signalstärke',
|
|
385
|
+
'ru': 'Список устройств с силой сигнала',
|
|
386
|
+
'pt': 'Lista de dispositivos com força de sinal',
|
|
387
|
+
'nl': 'List van apparaten met signaalkracht',
|
|
388
|
+
'fr': 'Liste des dispositifs avec force de signal',
|
|
389
|
+
'it': 'Elenco dei dispositivi con forza del segnale',
|
|
390
|
+
'es': 'Lista de dispositivos con fuerza de señal',
|
|
391
|
+
'pl': 'Lista urządzeń z siłą sygnałową',
|
|
392
|
+
'zh-cn': '具有信号实力的装置清单'
|
|
393
|
+
},
|
|
305
394
|
'type': 'array',
|
|
306
395
|
'role': 'json',
|
|
307
396
|
'read': true,
|
|
308
397
|
'write': false,
|
|
309
|
-
'def': [{Device: '--keine--', Adapter: '', Link_quality: ''}]
|
|
310
398
|
},
|
|
311
399
|
'native': {}
|
|
312
400
|
});
|
|
313
401
|
await this.setObjectNotExistsAsync(`${adptName}.countAll`, {
|
|
314
402
|
'type': 'state',
|
|
315
403
|
'common': {
|
|
316
|
-
'name':
|
|
404
|
+
'name': {
|
|
405
|
+
'en': 'Number of all devices',
|
|
406
|
+
'de': 'Anzahl aller Geräte',
|
|
407
|
+
'ru': 'Количество всех устройств',
|
|
408
|
+
'pt': 'Número de todos os dispositivos',
|
|
409
|
+
'nl': 'Nummer van alle apparaten',
|
|
410
|
+
'fr': 'Nombre de tous les appareils',
|
|
411
|
+
'it': 'Numero di tutti i dispositivi',
|
|
412
|
+
'es': 'Número de todos los dispositivos',
|
|
413
|
+
'pl': 'Ilość wszystkich urządzeń',
|
|
414
|
+
'zh-cn': '所有装置的数目'
|
|
415
|
+
},
|
|
317
416
|
'type': 'number',
|
|
318
417
|
'role': 'value',
|
|
319
418
|
'read': true,
|
|
320
419
|
'write': false,
|
|
321
|
-
'def': 0
|
|
322
420
|
},
|
|
323
421
|
'native': {}
|
|
324
422
|
});
|
|
325
423
|
await this.setObjectNotExistsAsync(`${adptName}.batteryList`, {
|
|
326
424
|
'type': 'state',
|
|
327
425
|
'common': {
|
|
328
|
-
'name':
|
|
426
|
+
'name': {
|
|
427
|
+
'en': 'List of devices with battery state',
|
|
428
|
+
'de': 'Liste der Geräte mit Batteriezustand',
|
|
429
|
+
'ru': 'Список устройств с состоянием батареи',
|
|
430
|
+
'pt': 'Lista de dispositivos com estado da bateria',
|
|
431
|
+
'nl': 'List van apparaten met batterij staat',
|
|
432
|
+
'fr': 'Liste des appareils avec état de batterie',
|
|
433
|
+
'it': 'Elenco dei dispositivi con stato della batteria',
|
|
434
|
+
'es': 'Lista de dispositivos con estado de batería',
|
|
435
|
+
'pl': 'Lista urządzeń z baterią stanową',
|
|
436
|
+
'zh-cn': '电池国装置清单'
|
|
437
|
+
},
|
|
329
438
|
'type': 'array',
|
|
330
439
|
'role': 'json',
|
|
331
440
|
'read': true,
|
|
332
441
|
'write': false,
|
|
333
|
-
'def': [{Device: '--keine--', Adapter: '', Battery: ''}]
|
|
334
442
|
},
|
|
335
443
|
'native': {}
|
|
336
444
|
});
|
|
337
445
|
await this.setObjectNotExistsAsync(`${adptName}.lowBatteryList`, {
|
|
338
446
|
'type': 'state',
|
|
339
447
|
'common': {
|
|
340
|
-
'name':
|
|
448
|
+
'name': {
|
|
449
|
+
'en': 'List of devices with low battery state',
|
|
450
|
+
'de': 'Liste der Geräte mit niedrigem Batteriezustand',
|
|
451
|
+
'ru': 'Список устройств с низким состоянием батареи',
|
|
452
|
+
'pt': 'Lista de dispositivos com baixo estado da bateria',
|
|
453
|
+
'nl': 'List van apparaten met lage batterij staat',
|
|
454
|
+
'fr': 'Liste des appareils à faible état de batterie',
|
|
455
|
+
'it': 'Elenco di dispositivi con stato di batteria basso',
|
|
456
|
+
'es': 'Lista de dispositivos con estado de batería bajo',
|
|
457
|
+
'pl': 'Lista urządzeń o niskim stanie baterii',
|
|
458
|
+
'zh-cn': '低电池国家装置清单'
|
|
459
|
+
},
|
|
341
460
|
'type': 'array',
|
|
342
461
|
'role': 'json',
|
|
343
462
|
'read': true,
|
|
344
463
|
'write': false,
|
|
345
|
-
'def': [{Device: '--keine--', Adapter: '', Battery: ''}]
|
|
346
464
|
},
|
|
347
465
|
'native': {}
|
|
348
466
|
});
|
|
349
467
|
await this.setObjectNotExistsAsync(`${adptName}.lowBatteryCount`, {
|
|
350
468
|
'type': 'state',
|
|
351
469
|
'common': {
|
|
352
|
-
'name':
|
|
470
|
+
'name': {
|
|
471
|
+
'en': 'Number of devices with low battery',
|
|
472
|
+
'de': 'Anzahl der Geräte mit niedriger Batterie',
|
|
473
|
+
'ru': 'Количество устройств c низкой батареей',
|
|
474
|
+
'pt': 'Número de dispositivos com bateria baixa',
|
|
475
|
+
'nl': 'Nummer van apparaten met lage batterij',
|
|
476
|
+
'fr': 'Nombre de dispositifs avec batterie basse',
|
|
477
|
+
'it': 'Numero di dispositivi con batteria bassa',
|
|
478
|
+
'es': 'Número de dispositivos con batería baja',
|
|
479
|
+
'pl': 'Liczba urządzeń z niską baterią',
|
|
480
|
+
'zh-cn': '低电池的装置数量'
|
|
481
|
+
},
|
|
353
482
|
'type': 'number',
|
|
354
483
|
'role': 'value',
|
|
355
484
|
'read': true,
|
|
356
485
|
'write': false,
|
|
357
|
-
'def': 0
|
|
358
486
|
},
|
|
359
487
|
'native': {}
|
|
360
488
|
});
|
|
361
489
|
await this.setObjectNotExistsAsync(`${adptName}.batteryCount`, {
|
|
362
490
|
'type': 'state',
|
|
363
491
|
'common': {
|
|
364
|
-
'name':
|
|
492
|
+
'name': {
|
|
493
|
+
'en': 'Number of devices with battery',
|
|
494
|
+
'de': 'Anzahl der Geräte mit Batterie',
|
|
495
|
+
'ru': 'Количество устройств c батареей',
|
|
496
|
+
'pt': 'Número de dispositivos com bateria',
|
|
497
|
+
'nl': 'Nummer van apparaten met batterij',
|
|
498
|
+
'fr': 'Nombre de dispositifs avec batterie',
|
|
499
|
+
'it': 'Numero di dispositivi con batteria',
|
|
500
|
+
'es': 'Número de dispositivos con batería',
|
|
501
|
+
'pl': 'Liczba urządzeń z baterią',
|
|
502
|
+
'zh-cn': '电池的装置数量'
|
|
503
|
+
},
|
|
365
504
|
'type': 'number',
|
|
366
505
|
'role': 'value',
|
|
367
506
|
'read': true,
|
|
368
507
|
'write': false,
|
|
369
|
-
'def': 0
|
|
370
508
|
},
|
|
371
509
|
'native': {}
|
|
372
510
|
});
|
|
373
511
|
}
|
|
374
512
|
|
|
513
|
+
/**
|
|
514
|
+
* @param {object} [i] - Device Object
|
|
515
|
+
**/
|
|
375
516
|
async createData(i) {
|
|
376
517
|
const devices = await this.getForeignStatesAsync(this.arrDev[i].Selektor);
|
|
377
518
|
const deviceAdapterName = await this.capitalize(this.arrDev[i].adapter);
|
|
@@ -388,31 +529,37 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
388
529
|
if (!this.blacklistArr.includes(id)) {
|
|
389
530
|
|
|
390
531
|
const currDeviceString = id.slice(0, (id.lastIndexOf('.') + 1) - 1);
|
|
391
|
-
const shortCurrDeviceString
|
|
532
|
+
const shortCurrDeviceString = currDeviceString.slice(0, (currDeviceString.lastIndexOf('.') + 1) - 1);
|
|
392
533
|
|
|
393
534
|
//Get device name
|
|
394
535
|
const deviceObject = await this.getForeignObjectAsync(currDeviceString);
|
|
395
536
|
const shortDeviceObject = await this.getForeignObjectAsync(shortCurrDeviceString);
|
|
396
537
|
let deviceName;
|
|
397
538
|
|
|
398
|
-
if (deviceObject && typeof deviceObject === 'object') {
|
|
399
|
-
deviceName = deviceObject.common.name;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
if (shortDeviceObject && typeof shortDeviceObject === 'object') {
|
|
403
|
-
if (this.arrDev[i].adapter === 'hue extended') {
|
|
404
|
-
deviceName = shortDeviceObject.common.name;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
//Get ID for Switchbot and ESPHome Devices
|
|
409
539
|
switch (this.arrDev[i].adapter) {
|
|
410
|
-
case '
|
|
540
|
+
case 'switchbotBle': //Get ID for Switchbot and ESPHome Devices
|
|
411
541
|
case 'esphome':
|
|
412
542
|
deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
|
|
413
543
|
break;
|
|
544
|
+
|
|
545
|
+
case 'hue-extended':
|
|
546
|
+
if (shortDeviceObject && typeof shortDeviceObject === 'object') {
|
|
547
|
+
deviceName = shortDeviceObject.common.name;
|
|
548
|
+
}
|
|
549
|
+
break;
|
|
550
|
+
|
|
551
|
+
default:
|
|
552
|
+
if (deviceObject && typeof deviceObject === 'object') {
|
|
553
|
+
deviceName = deviceObject.common.name;
|
|
554
|
+
}
|
|
555
|
+
break;
|
|
414
556
|
}
|
|
415
557
|
|
|
558
|
+
const deviceMainSelector = await this.getForeignStateAsync(id);
|
|
559
|
+
// 3. Get battery states
|
|
560
|
+
const deviceBatteryState = await this.getInitValue(currDeviceString + this.arrDev[i].battery);
|
|
561
|
+
const shortDeviceBatteryState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery);
|
|
562
|
+
|
|
416
563
|
// 1. Get link quality
|
|
417
564
|
let deviceQualityState;
|
|
418
565
|
let linkQuality;
|
|
@@ -436,13 +583,25 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
436
583
|
linkQuality = parseFloat((100/255 * deviceQualityState.val).toFixed(0)) + '%';
|
|
437
584
|
}
|
|
438
585
|
}
|
|
439
|
-
this.
|
|
440
|
-
{
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
586
|
+
if (this.config.listOnlyBattery) {
|
|
587
|
+
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
588
|
+
this.linkQualityDevices.push(
|
|
589
|
+
{
|
|
590
|
+
'Device': deviceName,
|
|
591
|
+
'Adapter': deviceAdapterName,
|
|
592
|
+
'Signal strength': linkQuality
|
|
593
|
+
}
|
|
594
|
+
);
|
|
444
595
|
}
|
|
445
|
-
|
|
596
|
+
} else {
|
|
597
|
+
this.linkQualityDevices.push(
|
|
598
|
+
{
|
|
599
|
+
'Device': deviceName,
|
|
600
|
+
'Adapter': deviceAdapterName,
|
|
601
|
+
'Signal strength': linkQuality
|
|
602
|
+
}
|
|
603
|
+
);
|
|
604
|
+
}
|
|
446
605
|
} else {
|
|
447
606
|
// no linkQuality available for powered devices
|
|
448
607
|
linkQuality = ' - ';
|
|
@@ -454,7 +613,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
454
613
|
// 2. When was the last contact to the device?
|
|
455
614
|
let lastContactString;
|
|
456
615
|
|
|
457
|
-
const deviceMainSelector = await this.getForeignStateAsync(id);
|
|
458
616
|
let deviceState = 'Online';
|
|
459
617
|
if (deviceMainSelector) {
|
|
460
618
|
try {
|
|
@@ -488,7 +646,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
488
646
|
|
|
489
647
|
// 2b. wenn seit X Minuten kein Kontakt mehr besteht, nimm Gerät in Liste auf
|
|
490
648
|
//Rechne auf Tage um, wenn mehr als 48 Stunden seit letztem Kontakt vergangen sind
|
|
491
|
-
//lastContactString = Math.round(lastContact) + ' Minuten';
|
|
492
649
|
switch (this.arrDev[i].adapter) {
|
|
493
650
|
case 'ping':
|
|
494
651
|
//State changed
|
|
@@ -504,401 +661,219 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
504
661
|
break;
|
|
505
662
|
}
|
|
506
663
|
|
|
664
|
+
const pushOfflineDevice = async () => {
|
|
665
|
+
if (this.config.listOnlyBattery) { //if checked, list only battery devices
|
|
666
|
+
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
667
|
+
this.offlineDevices.push(
|
|
668
|
+
{
|
|
669
|
+
'Device': deviceName,
|
|
670
|
+
'Adapter': deviceAdapterName,
|
|
671
|
+
'Last contact': lastContactString
|
|
672
|
+
}
|
|
673
|
+
);
|
|
674
|
+
}
|
|
675
|
+
} else {
|
|
676
|
+
this.offlineDevices.push( //else push all devices
|
|
677
|
+
{
|
|
678
|
+
'Device': deviceName,
|
|
679
|
+
'Adapter': deviceAdapterName,
|
|
680
|
+
'Last contact': lastContactString
|
|
681
|
+
}
|
|
682
|
+
);
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
|
|
507
686
|
switch (this.arrDev[i].adapter) {
|
|
508
687
|
case 'alexa2':
|
|
509
688
|
if (this.config.alexa2MaxMinutes === -1) {
|
|
510
689
|
if (!deviceUnreachState) {
|
|
511
690
|
deviceState = 'Offline'; //set online state to offline
|
|
512
|
-
|
|
513
|
-
{
|
|
514
|
-
Device: deviceName,
|
|
515
|
-
Adapter: deviceAdapterName,
|
|
516
|
-
Last_contact: lastContactString
|
|
517
|
-
}
|
|
518
|
-
);
|
|
691
|
+
await pushOfflineDevice();
|
|
519
692
|
}
|
|
520
693
|
} else if (lastContact > this.config.alexa2MaxMinutes) {
|
|
521
694
|
deviceState = 'Offline'; //set online state to offline
|
|
522
|
-
|
|
523
|
-
{
|
|
524
|
-
Device: deviceName,
|
|
525
|
-
Adapter: deviceAdapterName,
|
|
526
|
-
Last_contact: lastContactString
|
|
527
|
-
}
|
|
528
|
-
);
|
|
695
|
+
await pushOfflineDevice();
|
|
529
696
|
}
|
|
530
697
|
break;
|
|
531
698
|
case 'ble':
|
|
532
699
|
if (this.config.bleMaxMinutes === -1) {
|
|
533
700
|
if (!deviceUnreachState) {
|
|
534
701
|
deviceState = 'Offline'; //set online state to offline
|
|
535
|
-
|
|
536
|
-
{
|
|
537
|
-
Device: deviceName,
|
|
538
|
-
Adapter: deviceAdapterName,
|
|
539
|
-
Last_contact: lastContactString
|
|
540
|
-
}
|
|
541
|
-
);
|
|
702
|
+
await pushOfflineDevice();
|
|
542
703
|
}
|
|
543
704
|
} else if (lastContact > this.config.bleMaxMinutes) {
|
|
544
705
|
deviceState = 'Offline'; //set online state to offline
|
|
545
|
-
|
|
546
|
-
{
|
|
547
|
-
Device: deviceName,
|
|
548
|
-
Adapter: deviceAdapterName,
|
|
549
|
-
Last_contact: lastContactString
|
|
550
|
-
}
|
|
551
|
-
);
|
|
706
|
+
await pushOfflineDevice();
|
|
552
707
|
}
|
|
553
708
|
break;
|
|
554
709
|
case 'deconz':
|
|
555
710
|
if (this.config.deconzMaxMinutes === -1) {
|
|
556
711
|
if (!deviceUnreachState) {
|
|
557
712
|
deviceState = 'Offline'; //set online state to offline
|
|
558
|
-
|
|
559
|
-
{
|
|
560
|
-
Device: deviceName,
|
|
561
|
-
Adapter: deviceAdapterName,
|
|
562
|
-
Last_contact: lastContactString
|
|
563
|
-
}
|
|
564
|
-
);
|
|
713
|
+
await pushOfflineDevice();
|
|
565
714
|
}
|
|
566
715
|
} else if (lastContact > this.config.deconzMaxMinutes) {
|
|
567
716
|
deviceState = 'Offline'; //set online state to offline
|
|
568
|
-
|
|
569
|
-
{
|
|
570
|
-
Device: deviceName,
|
|
571
|
-
Adapter: deviceAdapterName,
|
|
572
|
-
Last_contact: lastContactString
|
|
573
|
-
}
|
|
574
|
-
);
|
|
717
|
+
await pushOfflineDevice();
|
|
575
718
|
}
|
|
576
719
|
break;
|
|
577
720
|
case 'esphome':
|
|
578
721
|
if (this.config.esphomeMaxMinutes === -1) {
|
|
579
722
|
if (!deviceUnreachState) {
|
|
580
723
|
deviceState = 'Offline'; //set online state to offline
|
|
581
|
-
|
|
582
|
-
{
|
|
583
|
-
Device: deviceName,
|
|
584
|
-
Adapter: deviceAdapterName,
|
|
585
|
-
Last_contact: lastContactString
|
|
586
|
-
}
|
|
587
|
-
);
|
|
724
|
+
await pushOfflineDevice();
|
|
588
725
|
}
|
|
589
726
|
} else if (lastContact > this.config.esphomeMaxMinutes) {
|
|
590
727
|
deviceState = 'Offline'; //set online state to offline
|
|
591
|
-
|
|
592
|
-
{
|
|
593
|
-
Device: deviceName,
|
|
594
|
-
Adapter: deviceAdapterName,
|
|
595
|
-
Last_contact: lastContactString
|
|
596
|
-
}
|
|
597
|
-
);
|
|
728
|
+
await pushOfflineDevice();
|
|
598
729
|
}
|
|
599
730
|
break;
|
|
600
731
|
case 'fritzDect':
|
|
601
732
|
if (this.config.fritzdectMaxMinutes === -1) {
|
|
602
733
|
if (!deviceUnreachState) {
|
|
603
734
|
deviceState = 'Offline'; //set online state to offline
|
|
604
|
-
|
|
605
|
-
{
|
|
606
|
-
Device: deviceName,
|
|
607
|
-
Adapter: deviceAdapterName,
|
|
608
|
-
Last_contact: lastContactString
|
|
609
|
-
}
|
|
610
|
-
);
|
|
735
|
+
await pushOfflineDevice();
|
|
611
736
|
}
|
|
612
737
|
} else if (lastContact > this.config.fritzdectMaxMinutes) {
|
|
613
738
|
deviceState = 'Offline'; //set online state to offline
|
|
614
|
-
|
|
615
|
-
{
|
|
616
|
-
Device: deviceName,
|
|
617
|
-
Adapter: deviceAdapterName,
|
|
618
|
-
Last_contact: lastContactString
|
|
619
|
-
}
|
|
620
|
-
);
|
|
739
|
+
await pushOfflineDevice();
|
|
621
740
|
}
|
|
622
741
|
break;
|
|
623
742
|
case 'homematic':
|
|
624
743
|
if (this.config.homematicMaxMinutes === -1) {
|
|
625
744
|
if (deviceUnreachState) {
|
|
626
745
|
deviceState = 'Offline'; //set online state to offline
|
|
627
|
-
|
|
628
|
-
{
|
|
629
|
-
Device: deviceName,
|
|
630
|
-
Adapter: deviceAdapterName,
|
|
631
|
-
Last_contact: lastContactString
|
|
632
|
-
}
|
|
633
|
-
);
|
|
746
|
+
await pushOfflineDevice();
|
|
634
747
|
}
|
|
635
748
|
} else if (lastContact > this.config.homematicMaxMinutes) {
|
|
636
749
|
deviceState = 'Offline'; //set online state to offline
|
|
637
|
-
|
|
638
|
-
{
|
|
639
|
-
Device: deviceName,
|
|
640
|
-
Adapter: deviceAdapterName,
|
|
641
|
-
Last_contact: lastContactString
|
|
642
|
-
}
|
|
643
|
-
);
|
|
750
|
+
await pushOfflineDevice();
|
|
644
751
|
}
|
|
645
752
|
break;
|
|
646
753
|
case 'hue':
|
|
647
754
|
if (this.config.hueMaxMinutes === -1) {
|
|
648
755
|
if (!deviceUnreachState) {
|
|
649
756
|
deviceState = 'Offline'; //set online state to offline
|
|
650
|
-
|
|
651
|
-
{
|
|
652
|
-
Device: deviceName,
|
|
653
|
-
Adapter: deviceAdapterName,
|
|
654
|
-
Last_contact: lastContactString
|
|
655
|
-
}
|
|
656
|
-
);
|
|
757
|
+
await pushOfflineDevice();
|
|
657
758
|
}
|
|
658
759
|
} else if (lastContact > this.config.hueMaxMinutes) {
|
|
659
760
|
deviceState = 'Offline'; //set online state to offline
|
|
660
|
-
|
|
661
|
-
{
|
|
662
|
-
Device: deviceName,
|
|
663
|
-
Adapter: deviceAdapterName,
|
|
664
|
-
Last_contact: lastContactString
|
|
665
|
-
}
|
|
666
|
-
);
|
|
761
|
+
await pushOfflineDevice();
|
|
667
762
|
}
|
|
668
763
|
break;
|
|
669
|
-
case 'hue
|
|
764
|
+
case 'hue-extended':
|
|
670
765
|
if (this.config.hueextMaxMinutes === -1) {
|
|
671
766
|
if (!deviceUnreachState) {
|
|
672
767
|
deviceState = 'Offline'; //set online state to offline
|
|
673
|
-
|
|
674
|
-
{
|
|
675
|
-
Device: deviceName,
|
|
676
|
-
Adapter: deviceAdapterName,
|
|
677
|
-
Last_contact: lastContactString
|
|
678
|
-
}
|
|
679
|
-
);
|
|
768
|
+
await pushOfflineDevice();
|
|
680
769
|
}
|
|
681
770
|
} else if (lastContact > this.config.hueextMaxMinutes) {
|
|
682
771
|
deviceState = 'Offline'; //set online state to offline
|
|
683
|
-
|
|
684
|
-
{
|
|
685
|
-
Device: deviceName,
|
|
686
|
-
Adapter: deviceAdapterName,
|
|
687
|
-
Last_contact: lastContactString
|
|
688
|
-
}
|
|
689
|
-
);
|
|
772
|
+
await pushOfflineDevice();
|
|
690
773
|
}
|
|
691
774
|
break;
|
|
692
775
|
case 'miHome':
|
|
693
776
|
if (this.config.mihomeMaxMinutes === -1) {
|
|
694
777
|
if (!deviceUnreachState) {
|
|
695
778
|
deviceState = 'Offline'; //set online state to offline
|
|
696
|
-
|
|
697
|
-
{
|
|
698
|
-
Device: deviceName,
|
|
699
|
-
Adapter: deviceAdapterName,
|
|
700
|
-
Last_contact: lastContactString
|
|
701
|
-
}
|
|
702
|
-
);
|
|
779
|
+
await pushOfflineDevice();
|
|
703
780
|
}
|
|
704
781
|
} else if (lastContact > this.config.mihomeMaxMinutes) {
|
|
705
782
|
deviceState = 'Offline'; //set online state to offline
|
|
706
|
-
|
|
707
|
-
{
|
|
708
|
-
Device: deviceName,
|
|
709
|
-
Adapter: deviceAdapterName,
|
|
710
|
-
Last_contact: lastContactString
|
|
711
|
-
}
|
|
712
|
-
);
|
|
783
|
+
await pushOfflineDevice();
|
|
713
784
|
}
|
|
714
785
|
break;
|
|
715
|
-
case '
|
|
786
|
+
case 'nuki-extended':
|
|
716
787
|
if (this.config.nukiextendMaxMinutes === -1) {
|
|
717
788
|
if (!deviceUnreachState) {
|
|
718
789
|
deviceState = 'Offline'; //set online state to offline
|
|
719
|
-
|
|
720
|
-
{
|
|
721
|
-
Device: deviceName,
|
|
722
|
-
Adapter: deviceAdapterName,
|
|
723
|
-
Last_contact: lastContactString
|
|
724
|
-
}
|
|
725
|
-
);
|
|
790
|
+
await pushOfflineDevice();
|
|
726
791
|
}
|
|
727
792
|
} else if (lastContact > this.config.nukiextendMaxMinutes) {
|
|
728
793
|
deviceState = 'Offline'; //set online state to offline
|
|
729
|
-
|
|
730
|
-
{
|
|
731
|
-
Device: deviceName,
|
|
732
|
-
Adapter: deviceAdapterName,
|
|
733
|
-
Last_contact: lastContactString
|
|
734
|
-
}
|
|
735
|
-
);
|
|
794
|
+
await pushOfflineDevice();
|
|
736
795
|
}
|
|
737
796
|
break;
|
|
738
797
|
case 'ping':
|
|
739
798
|
if (this.config.pingMaxMinutes === -1) {
|
|
740
799
|
if (!deviceUnreachState) {
|
|
741
800
|
deviceState = 'Offline'; //set online state to offline
|
|
742
|
-
|
|
743
|
-
{
|
|
744
|
-
Device: deviceName,
|
|
745
|
-
Adapter: deviceAdapterName,
|
|
746
|
-
Last_contact: lastContactString
|
|
747
|
-
}
|
|
748
|
-
);
|
|
801
|
+
await pushOfflineDevice();
|
|
749
802
|
}
|
|
750
803
|
} else if ((lastStateChange > this.config.pingMaxMinutes) && (!deviceUnreachState)) {
|
|
751
804
|
deviceState = 'Offline'; //set online state to offline
|
|
752
|
-
|
|
753
|
-
{
|
|
754
|
-
Device: deviceName,
|
|
755
|
-
Adapter: deviceAdapterName,
|
|
756
|
-
Last_contact: lastContactString
|
|
757
|
-
}
|
|
758
|
-
);
|
|
805
|
+
await pushOfflineDevice();
|
|
759
806
|
}
|
|
760
807
|
break;
|
|
761
808
|
case 'shelly':
|
|
762
809
|
if (this.config.shellyMaxMinutes === -1) {
|
|
763
810
|
if (!deviceUnreachState) {
|
|
764
811
|
deviceState = 'Offline'; //set online state to offline
|
|
765
|
-
|
|
766
|
-
{
|
|
767
|
-
Device: deviceName,
|
|
768
|
-
Adapter: deviceAdapterName,
|
|
769
|
-
Last_contact: lastContactString
|
|
770
|
-
}
|
|
771
|
-
);
|
|
812
|
+
await pushOfflineDevice();
|
|
772
813
|
}
|
|
773
814
|
} else if (lastContact > this.config.shellyMaxMinutes) {
|
|
774
815
|
deviceState = 'Offline'; //set online state to offline
|
|
775
|
-
|
|
776
|
-
{
|
|
777
|
-
Device: deviceName,
|
|
778
|
-
Adapter: deviceAdapterName,
|
|
779
|
-
Last_contact: lastContactString
|
|
780
|
-
}
|
|
781
|
-
);
|
|
816
|
+
await pushOfflineDevice();
|
|
782
817
|
}
|
|
783
818
|
break;
|
|
784
819
|
case 'sonoff':
|
|
785
820
|
if (this.config.sonoffMaxMinutes === -1) {
|
|
786
821
|
if (!deviceUnreachState) {
|
|
787
822
|
deviceState = 'Offline'; //set online state to offline
|
|
788
|
-
|
|
789
|
-
{
|
|
790
|
-
Device: deviceName,
|
|
791
|
-
Adapter: deviceAdapterName,
|
|
792
|
-
Last_contact: lastContactString
|
|
793
|
-
}
|
|
794
|
-
);
|
|
823
|
+
await pushOfflineDevice();
|
|
795
824
|
}
|
|
796
825
|
} else if (lastContact > this.config.sonoffMaxMinutes) {
|
|
797
826
|
deviceState = 'Offline'; //set online state to offline
|
|
798
|
-
|
|
799
|
-
{
|
|
800
|
-
Device: deviceName,
|
|
801
|
-
Adapter: deviceAdapterName,
|
|
802
|
-
Last_contact: lastContactString
|
|
803
|
-
}
|
|
804
|
-
);
|
|
827
|
+
await pushOfflineDevice();
|
|
805
828
|
}
|
|
806
829
|
break;
|
|
807
830
|
case 'sonos':
|
|
808
831
|
if (this.config.sonosMaxMinutes === -1) {
|
|
809
832
|
if (!deviceUnreachState) {
|
|
810
833
|
deviceState = 'Offline'; //set online state to offline
|
|
811
|
-
|
|
812
|
-
{
|
|
813
|
-
Device: deviceName,
|
|
814
|
-
Adapter: deviceAdapterName,
|
|
815
|
-
Last_contact: lastContactString
|
|
816
|
-
}
|
|
817
|
-
);
|
|
834
|
+
await pushOfflineDevice();
|
|
818
835
|
}
|
|
819
836
|
} else if (lastContact > this.config.sonosMaxMinutes) {
|
|
820
837
|
deviceState = 'Offline'; //set online state to offline
|
|
821
|
-
|
|
822
|
-
{
|
|
823
|
-
Device: deviceName,
|
|
824
|
-
Adapter: deviceAdapterName,
|
|
825
|
-
Last_contact: lastContactString
|
|
826
|
-
}
|
|
827
|
-
);
|
|
838
|
+
await pushOfflineDevice();
|
|
828
839
|
}
|
|
829
840
|
break;
|
|
830
|
-
case '
|
|
841
|
+
case 'switchbotBle':
|
|
831
842
|
if (this.config.switchbotMaxMinutes === -1) {
|
|
832
843
|
if (!deviceUnreachState) {
|
|
833
844
|
deviceState = 'Offline'; //set online state to offline
|
|
834
|
-
|
|
835
|
-
{
|
|
836
|
-
Device: deviceName,
|
|
837
|
-
Adapter: deviceAdapterName,
|
|
838
|
-
Last_contact: lastContactString
|
|
839
|
-
}
|
|
840
|
-
);
|
|
845
|
+
await pushOfflineDevice();
|
|
841
846
|
}
|
|
842
847
|
} else if (lastContact > this.config.switchbotMaxMinutes) {
|
|
843
848
|
deviceState = 'Offline'; //set online state to offline
|
|
844
|
-
|
|
845
|
-
{
|
|
846
|
-
Device: deviceName,
|
|
847
|
-
Adapter: deviceAdapterName,
|
|
848
|
-
Last_contact: lastContactString
|
|
849
|
-
}
|
|
850
|
-
);
|
|
849
|
+
await pushOfflineDevice();
|
|
851
850
|
}
|
|
852
851
|
break;
|
|
853
852
|
case 'zigbee':
|
|
854
853
|
if (this.config.zigbeeMaxMinutes === -1) {
|
|
855
854
|
if (!deviceUnreachState) {
|
|
856
855
|
deviceState = 'Offline'; //set online state to offline
|
|
857
|
-
|
|
858
|
-
{
|
|
859
|
-
Device: deviceName,
|
|
860
|
-
Adapter: deviceAdapterName,
|
|
861
|
-
Last_contact: lastContactString
|
|
862
|
-
}
|
|
863
|
-
);
|
|
856
|
+
await pushOfflineDevice();
|
|
864
857
|
}
|
|
865
858
|
} else if (lastContact > this.config.zigbeeMaxMinutes) {
|
|
866
859
|
deviceState = 'Offline'; //set online state to offline
|
|
867
|
-
|
|
868
|
-
{
|
|
869
|
-
Device: deviceName,
|
|
870
|
-
Adapter: deviceAdapterName,
|
|
871
|
-
Last_contact: lastContactString
|
|
872
|
-
}
|
|
873
|
-
);
|
|
860
|
+
await pushOfflineDevice();
|
|
874
861
|
}
|
|
875
862
|
break;
|
|
876
863
|
case 'zwave':
|
|
877
864
|
if (this.config.zwaveMaxMinutes === -1) {
|
|
878
865
|
if (!deviceUnreachState) {
|
|
879
866
|
deviceState = 'Offline'; //set online state to offline
|
|
880
|
-
|
|
881
|
-
{
|
|
882
|
-
Device: deviceName,
|
|
883
|
-
Adapter: deviceAdapterName,
|
|
884
|
-
Last_contact: lastContactString
|
|
885
|
-
}
|
|
886
|
-
);
|
|
867
|
+
await pushOfflineDevice();
|
|
887
868
|
}
|
|
888
869
|
} else if (lastContact > this.config.zwaveMaxMinutes) {
|
|
889
870
|
deviceState = 'Offline'; //set online state to offline
|
|
890
|
-
|
|
891
|
-
{
|
|
892
|
-
Device: deviceName,
|
|
893
|
-
Adapter: deviceAdapterName,
|
|
894
|
-
Last_contact: lastContactString
|
|
895
|
-
}
|
|
896
|
-
);
|
|
871
|
+
await pushOfflineDevice();
|
|
897
872
|
}
|
|
898
873
|
break;
|
|
899
874
|
}
|
|
900
|
-
} catch (
|
|
901
|
-
this.
|
|
875
|
+
} catch (error) {
|
|
876
|
+
this.errorReporting('[getLastContact]', error);
|
|
902
877
|
}
|
|
903
878
|
}
|
|
904
879
|
|
|
@@ -908,8 +883,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
908
883
|
this.offlineDevicesCount = this.offlineDevices.length;
|
|
909
884
|
|
|
910
885
|
// 3. Get battery states
|
|
911
|
-
const deviceBatteryState = await this.getInitValue(currDeviceString + this.arrDev[i].battery);
|
|
912
|
-
const shortDeviceBatteryState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery);
|
|
913
886
|
let batteryHealth;
|
|
914
887
|
|
|
915
888
|
if ((!deviceBatteryState) && (!shortDeviceBatteryState)) {
|
|
@@ -926,20 +899,20 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
926
899
|
|
|
927
900
|
this.batteryPowered.push(
|
|
928
901
|
{
|
|
929
|
-
Device: deviceName,
|
|
930
|
-
Adapter: deviceAdapterName,
|
|
931
|
-
Battery: batteryHealth
|
|
902
|
+
'Device': deviceName,
|
|
903
|
+
'Adapter': deviceAdapterName,
|
|
904
|
+
'Battery': batteryHealth
|
|
932
905
|
}
|
|
933
906
|
);
|
|
934
907
|
break;
|
|
935
|
-
case 'hue
|
|
908
|
+
case 'hue-extended':
|
|
936
909
|
if (shortDeviceBatteryState) {
|
|
937
910
|
batteryHealth = shortDeviceBatteryState + '%';
|
|
938
911
|
this.batteryPowered.push(
|
|
939
912
|
{
|
|
940
|
-
Device: deviceName,
|
|
941
|
-
Adapter: deviceAdapterName,
|
|
942
|
-
Battery: batteryHealth
|
|
913
|
+
'Device': deviceName,
|
|
914
|
+
'Adapter': deviceAdapterName,
|
|
915
|
+
'Battery': batteryHealth
|
|
943
916
|
}
|
|
944
917
|
);
|
|
945
918
|
}
|
|
@@ -948,9 +921,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
948
921
|
batteryHealth = (deviceBatteryState) + '%';
|
|
949
922
|
this.batteryPowered.push(
|
|
950
923
|
{
|
|
951
|
-
Device: deviceName,
|
|
952
|
-
Adapter: deviceAdapterName,
|
|
953
|
-
Battery: batteryHealth
|
|
924
|
+
'Device': deviceName,
|
|
925
|
+
'Adapter': deviceAdapterName,
|
|
926
|
+
'Battery': batteryHealth
|
|
954
927
|
}
|
|
955
928
|
);
|
|
956
929
|
}
|
|
@@ -964,55 +937,64 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
964
937
|
const deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat);
|
|
965
938
|
const deviceLowBatStateHM = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat2);
|
|
966
939
|
|
|
940
|
+
switch (this.arrDev[i].adapter) {
|
|
941
|
+
case 'homematic':
|
|
942
|
+
if (deviceLowBatState || deviceLowBatStateHM) {
|
|
943
|
+
this.batteryLowPowered.push(
|
|
944
|
+
{
|
|
945
|
+
'Device': deviceName,
|
|
946
|
+
'Adapter': deviceAdapterName,
|
|
947
|
+
'Battery': batteryHealth
|
|
948
|
+
}
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
break;
|
|
967
952
|
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
);
|
|
987
|
-
}
|
|
953
|
+
default:
|
|
954
|
+
if (deviceLowBatState) {
|
|
955
|
+
this.batteryLowPowered.push(
|
|
956
|
+
{
|
|
957
|
+
'Device': deviceName,
|
|
958
|
+
'Adapter': deviceAdapterName,
|
|
959
|
+
'Battery': batteryHealth
|
|
960
|
+
}
|
|
961
|
+
);
|
|
962
|
+
} else if (deviceBatteryState && (deviceBatteryState < batteryWarningMin)) {
|
|
963
|
+
this.batteryLowPowered.push(
|
|
964
|
+
{
|
|
965
|
+
'Device': deviceName,
|
|
966
|
+
'Adapter': deviceAdapterName,
|
|
967
|
+
'Battery': batteryHealth
|
|
968
|
+
}
|
|
969
|
+
);
|
|
970
|
+
}
|
|
988
971
|
}
|
|
989
972
|
|
|
990
973
|
// 3d. Count how many devices are with low battery
|
|
991
974
|
this.lowBatteryPoweredCount = this.batteryLowPowered.length;
|
|
992
975
|
|
|
993
|
-
// 4. Add
|
|
994
|
-
|
|
995
|
-
if (deviceBatteryState !== null || shortDeviceBatteryState !== null) {
|
|
976
|
+
if (this.config.listOnlyBattery) { // 4. Add only devices with battery in the list
|
|
977
|
+
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
996
978
|
this.listAllDevices.push(
|
|
997
979
|
{
|
|
998
|
-
Device: deviceName,
|
|
999
|
-
Adapter: deviceAdapterName,
|
|
1000
|
-
Battery: batteryHealth,
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
Status: deviceState
|
|
980
|
+
'Device': deviceName,
|
|
981
|
+
'Adapter': deviceAdapterName,
|
|
982
|
+
'Battery': batteryHealth,
|
|
983
|
+
'Signal strength': linkQuality,
|
|
984
|
+
'Last contact': lastContactString,
|
|
985
|
+
'Status': deviceState
|
|
1004
986
|
}
|
|
1005
987
|
);
|
|
1006
988
|
}
|
|
1007
|
-
} else if (!this.config.listOnlyBattery) {
|
|
989
|
+
} else if (!this.config.listOnlyBattery) { // 4. Add all devices
|
|
1008
990
|
this.listAllDevices.push(
|
|
1009
991
|
{
|
|
1010
|
-
Device: deviceName,
|
|
1011
|
-
Adapter: deviceAdapterName,
|
|
1012
|
-
Battery: batteryHealth,
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
Status: deviceState
|
|
992
|
+
'Device': deviceName,
|
|
993
|
+
'Adapter': deviceAdapterName,
|
|
994
|
+
'Battery': batteryHealth,
|
|
995
|
+
'Signal strength': linkQuality,
|
|
996
|
+
'Last contact': lastContactString,
|
|
997
|
+
'Status': deviceState
|
|
1016
998
|
}
|
|
1017
999
|
);
|
|
1018
1000
|
}
|
|
@@ -1021,132 +1003,182 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1021
1003
|
// 4a. Count how many devices are exists
|
|
1022
1004
|
this.deviceCounter = this.listAllDevices.length;
|
|
1023
1005
|
}
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1006
|
+
} // <-- end of loop
|
|
1007
|
+
} // <-- end of createData
|
|
1008
|
+
|
|
1026
1009
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1010
|
+
/**
|
|
1011
|
+
* @param {string} [adptName] - Adapter name
|
|
1012
|
+
*/
|
|
1013
|
+
async createDataForEachAdapter(adptName) {
|
|
1014
|
+
// create Data for each Adapter in own lists
|
|
1015
|
+
this.log.debug(`Function started: ${this.createDataForEachAdapter.name}`);
|
|
1030
1016
|
|
|
1031
|
-
|
|
1017
|
+
try {
|
|
1018
|
+
await this.resetVars(); // reset the arrays and counts
|
|
1032
1019
|
|
|
1033
|
-
|
|
1034
|
-
await this.createData(i);
|
|
1035
|
-
}
|
|
1020
|
+
for (let i = 0; i < this.arrDev.length; i++) {
|
|
1036
1021
|
|
|
1022
|
+
if (this.arrDev[i].adapter.includes(adptName)) { // list device only if selected adapter matched with device
|
|
1023
|
+
await this.createData(i);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
await this.writeDatapoints(adptName); // fill the datapoints
|
|
1027
|
+
} catch (error) {
|
|
1028
|
+
this.errorReporting('[createDataForEachAdapter]', error);
|
|
1037
1029
|
}
|
|
1038
|
-
await this.writeDatapoints(adptName);
|
|
1039
1030
|
|
|
1040
|
-
this.log.debug(`Function finished: ${this.
|
|
1041
|
-
}
|
|
1031
|
+
this.log.debug(`Function finished: ${this.createDataForEachAdapter.name}`);
|
|
1032
|
+
} // <-- end of createDataForEachAdapter
|
|
1033
|
+
|
|
1034
|
+
async createDataOfAllAdapter() {
|
|
1035
|
+
// create Data of all selected adapter in one list
|
|
1036
|
+
this.log.debug(`Function started: ${this.createDataOfAllAdapter.name}`);
|
|
1037
|
+
|
|
1038
|
+
try {
|
|
1039
|
+
await this.resetVars(); // reset the arrays and counts
|
|
1042
1040
|
|
|
1043
|
-
|
|
1044
|
-
this.log.debug(`Function started: ${this.createDataOfAll.name}`);
|
|
1045
|
-
await this.resetVars();
|
|
1041
|
+
for (let i = 0; i < this.arrDev.length; i++) {
|
|
1046
1042
|
|
|
1047
|
-
|
|
1043
|
+
await this.createData(i);
|
|
1048
1044
|
|
|
1049
|
-
|
|
1045
|
+
}
|
|
1050
1046
|
|
|
1047
|
+
if (this.config.checkSendOfflineMsg) await this.sendOfflineNotifications(); // send message if new devices are offline
|
|
1048
|
+
if (this.config.checkSendBatteryMsg) await this.sendBatteryNotifications(); // send message for low battery devices
|
|
1049
|
+
await this.writeDatapoints(); // fill the datapoints
|
|
1050
|
+
} catch (error) {
|
|
1051
|
+
this.errorReporting('[createDataOfAllAdapter]', error);
|
|
1051
1052
|
}
|
|
1052
|
-
await this.writeDatapoints();
|
|
1053
1053
|
|
|
1054
|
-
this.log.debug(`Function finished: ${this.
|
|
1055
|
-
}
|
|
1054
|
+
this.log.debug(`Function finished: ${this.createDataOfAllAdapter.name}`);
|
|
1055
|
+
} // <-- end of createDataOfAllAdapter
|
|
1056
1056
|
|
|
1057
|
-
async resetVars() {
|
|
1058
|
-
// arrays
|
|
1059
|
-
this.offlineDevices = [],
|
|
1060
|
-
this.linkQualityDevices = [];
|
|
1061
|
-
this.batteryPowered = [];
|
|
1062
|
-
this.batteryLowPowered = [];
|
|
1063
|
-
this.listAllDevices = [];
|
|
1064
1057
|
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
this.lowBatteryPoweredCount = 0;
|
|
1058
|
+
/**
|
|
1059
|
+
* Notification service
|
|
1060
|
+
* @param {string} [text] - Text which should be send
|
|
1061
|
+
**/
|
|
1062
|
+
async sendNotification(text) {
|
|
1071
1063
|
|
|
1072
|
-
|
|
1073
|
-
|
|
1064
|
+
// Pushover
|
|
1065
|
+
try {
|
|
1066
|
+
if (this.config.instancePushover) {
|
|
1067
|
+
//first check if instance is living
|
|
1068
|
+
const pushoverAliveState = await this.getInitValue('system.adapter.' + this.config.instancePushover + '.alive');
|
|
1074
1069
|
|
|
1075
|
-
|
|
1076
|
-
|
|
1070
|
+
if (!pushoverAliveState) {
|
|
1071
|
+
this.log.warn('Pushover instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1072
|
+
} else {
|
|
1073
|
+
await this.sendToAsync(this.config.instancePushover, 'send', {
|
|
1074
|
+
message: text,
|
|
1075
|
+
title: this.config.titlePushover,
|
|
1076
|
+
device: this.config.devicePushover,
|
|
1077
|
+
priority: this.config.prioPushover
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
} catch (error) {
|
|
1082
|
+
this.errorReporting('[sendNotification Pushover]', error);
|
|
1083
|
+
}
|
|
1077
1084
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
test: false, // Only for Developer
|
|
1098
|
-
test2: false, // Only for Developer
|
|
1099
|
-
test3: false // Only for Developer
|
|
1100
|
-
};
|
|
1085
|
+
// Telegram
|
|
1086
|
+
try {
|
|
1087
|
+
if (this.config.instanceTelegram) {
|
|
1088
|
+
//first check if instance is living
|
|
1089
|
+
const telegramAliveState = await this.getInitValue('system.adapter.' + this.config.instanceTelegram + '.alive');
|
|
1090
|
+
|
|
1091
|
+
if (!telegramAliveState) {
|
|
1092
|
+
this.log.warn('Telegram instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1093
|
+
} else {
|
|
1094
|
+
await this.sendToAsync(this.config.instanceTelegram, 'send', {
|
|
1095
|
+
text: text,
|
|
1096
|
+
user: this.config.deviceTelegram,
|
|
1097
|
+
chatId: this.config.chatIdTelegram
|
|
1098
|
+
});
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
} catch (error) {
|
|
1102
|
+
this.errorReporting('[sendNotification Telegram]', error);
|
|
1103
|
+
}
|
|
1101
1104
|
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
this.
|
|
1105
|
+
// Whatsapp
|
|
1106
|
+
try {
|
|
1107
|
+
if (this.config.instanceWhatsapp) {
|
|
1108
|
+
//first check if instance is living
|
|
1109
|
+
const whatsappAliveState = await this.getInitValue('system.adapter.' + this.config.instanceWhatsapp + '.alive');
|
|
1107
1110
|
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
} catch (e) {
|
|
1116
|
-
this.log.warn(`Error at creating/filling datapoints for each adapter: ${e}`);
|
|
1117
|
-
return;
|
|
1118
|
-
}
|
|
1111
|
+
if (!whatsappAliveState) {
|
|
1112
|
+
this.log.warn('Whatsapp instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1113
|
+
} else {
|
|
1114
|
+
await this.sendToAsync(this.config.instanceWhatsapp, 'send', {
|
|
1115
|
+
text: text,
|
|
1116
|
+
phone: this.config.phoneWhatsapp
|
|
1117
|
+
});
|
|
1119
1118
|
}
|
|
1120
1119
|
}
|
|
1120
|
+
} catch (error) {
|
|
1121
|
+
this.errorReporting('[sendNotification Whatsapp]', error);
|
|
1121
1122
|
}
|
|
1122
1123
|
|
|
1123
|
-
//
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1124
|
+
// Email
|
|
1125
|
+
try {
|
|
1126
|
+
if (this.config.instanceEmail) {
|
|
1127
|
+
//first check if instance is living
|
|
1128
|
+
const eMailAliveState = await this.getInitValue('system.adapter.' + this.config.instanceEmail + '.alive');
|
|
1129
|
+
|
|
1130
|
+
if (!eMailAliveState) {
|
|
1131
|
+
this.log.warn('eMail instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1132
|
+
} else {
|
|
1133
|
+
await this.sendToAsync(this.config.instanceEmail, 'send', {
|
|
1134
|
+
sendTo: this.config.sendToEmail,
|
|
1135
|
+
text: text,
|
|
1136
|
+
subject: this.config.subjectEmail
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
} catch (error) {
|
|
1141
|
+
this.errorReporting('[sendNotification eMail]', error);
|
|
1129
1142
|
}
|
|
1130
1143
|
|
|
1131
|
-
|
|
1132
|
-
= Start of main loop =
|
|
1133
|
-
=============================================*/
|
|
1144
|
+
// Jarvis Notification
|
|
1134
1145
|
try {
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1146
|
+
if (this.config.instanceJarvis) {
|
|
1147
|
+
//first check if instance is living
|
|
1148
|
+
const jarvisAliveState = await this.getInitValue('system.adapter.' + this.config.instanceJarvis + '.alive');
|
|
1149
|
+
|
|
1150
|
+
if (!jarvisAliveState) {
|
|
1151
|
+
this.log.warn('Jarvis instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1152
|
+
} else {
|
|
1153
|
+
const jsonText = JSON.stringify(text);
|
|
1154
|
+
await this.setForeignStateAsync(`${this.config.instanceJarvis}.addNotification`, '{"title":"'+ this.config.titleJarvis +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message": ' + jsonText + ',"display": "drawer"}');
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
} catch (error) {
|
|
1158
|
+
this.errorReporting('[sendNotification Jarvis]', error);
|
|
1140
1159
|
}
|
|
1141
1160
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1161
|
+
// Lovelace Notification
|
|
1162
|
+
try {
|
|
1163
|
+
if (this.config.instanceLovelace) {
|
|
1164
|
+
//first check if instance is living
|
|
1165
|
+
const lovelaceAliveState = await this.getInitValue('system.adapter.' + this.config.instanceLovelace + '.alive');
|
|
1166
|
+
|
|
1167
|
+
if (!lovelaceAliveState) {
|
|
1168
|
+
this.log.warn('Lovelace instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1169
|
+
} else {
|
|
1170
|
+
const jsonText = JSON.stringify(text);
|
|
1171
|
+
await this.setForeignStateAsync(`${this.config.instanceLovelace}.notifications.add`, '{"message":' + jsonText + ', "title":"'+ this.config.titleLovelace +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')"}');
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
} catch (error) {
|
|
1175
|
+
this.errorReporting('[sendNotification Lovelace]', error);
|
|
1176
|
+
}
|
|
1177
|
+
} // <-- End of sendNotification function
|
|
1144
1178
|
|
|
1145
1179
|
|
|
1146
1180
|
async sendOfflineNotifications() {
|
|
1147
|
-
|
|
1148
|
-
= send offline notification =
|
|
1149
|
-
=============================================*/
|
|
1181
|
+
// send message if an device is offline
|
|
1150
1182
|
|
|
1151
1183
|
this.log.debug(`Start the function: ${this.sendOfflineNotifications.name}`);
|
|
1152
1184
|
|
|
@@ -1162,184 +1194,122 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1162
1194
|
}
|
|
1163
1195
|
|
|
1164
1196
|
for (const id of this.offlineDevices) {
|
|
1165
|
-
msg = `${msg} \n ${id['Device']} (${id['
|
|
1197
|
+
msg = `${msg} \n ${id['Device']} (${id['Last contact']})`;
|
|
1166
1198
|
}
|
|
1167
1199
|
this.log.info(msg);
|
|
1168
1200
|
await this.setStateAsync('lastNotification', msg, true);
|
|
1169
|
-
|
|
1170
|
-
try {
|
|
1171
|
-
await this.sendPushover(msg);
|
|
1172
|
-
} catch (e) {
|
|
1173
|
-
this.log.warn (`Getting error at sending pushover notification ${e}`);
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
if (this.config.instanceTelegram) {
|
|
1177
|
-
try {
|
|
1178
|
-
await this.sendTelegram(msg);
|
|
1179
|
-
} catch (e) {
|
|
1180
|
-
this.log.warn (`Getting error at sending telegram notification ${e}`);
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
if (this.config.instanceWhatsapp) {
|
|
1184
|
-
try {
|
|
1185
|
-
await this.sendWhatsapp(msg);
|
|
1186
|
-
} catch (e) {
|
|
1187
|
-
this.log.warn (`Getting error at sending whatsapp notification ${e}`);
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
if (this.config.instanceEmail) {
|
|
1191
|
-
try {
|
|
1192
|
-
await this.sendEmail(msg);
|
|
1193
|
-
} catch (e) {
|
|
1194
|
-
this.log.warn (`Getting error at sending email notification ${e}`);
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
if (this.config.instanceJarvis) {
|
|
1198
|
-
try {
|
|
1199
|
-
await this.sendJarvis('{"title":"'+ this.config.titleJarvis +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message":" ' + this.offlineDevicesCount + ' Geräte sind nicht erreichbar","display": "drawer"}');
|
|
1200
|
-
} catch (e) {
|
|
1201
|
-
this.log.warn (`Getting error at sending jarvis notification ${e}`);
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
if (this.config.instanceLovelace) {
|
|
1205
|
-
try {
|
|
1206
|
-
await this.sendLovelace('{"message":" ' + this.offlineDevicesCount + ' Geräte sind nicht erreichbar", "title":"'+ this.config.titleLovelace +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')"}');
|
|
1207
|
-
} catch (e) {
|
|
1208
|
-
this.log.warn (`Getting error at sending lovelace notification ${e}`);
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1201
|
+
await this.sendNotification(msg);
|
|
1211
1202
|
}
|
|
1212
|
-
} catch (
|
|
1213
|
-
this.
|
|
1203
|
+
} catch (error) {
|
|
1204
|
+
this.errorReporting('[sendOfflineMessage]', error);
|
|
1214
1205
|
}
|
|
1215
1206
|
this.log.debug(`Finished the function: ${this.sendOfflineNotifications.name}`);
|
|
1216
1207
|
}//<--End of offline notification
|
|
1217
1208
|
|
|
1218
1209
|
|
|
1219
1210
|
async sendBatteryNotifications() {
|
|
1220
|
-
|
|
1221
|
-
= send low battery notification =
|
|
1222
|
-
=============================================*/
|
|
1211
|
+
// send message for low battery devices
|
|
1223
1212
|
|
|
1224
1213
|
this.log.debug(`Start the function: ${this.sendBatteryNotifications.name}`);
|
|
1225
|
-
const now = new Date();
|
|
1226
|
-
const today = now.getDay();
|
|
1227
|
-
const checkDays = [];
|
|
1228
|
-
let checkToday;
|
|
1229
|
-
|
|
1230
|
-
const choosedDays = {
|
|
1231
|
-
monday: this.config.checkMonday,
|
|
1232
|
-
tuesday: this.config.checkTuesday,
|
|
1233
|
-
wednesday: this.config.checkWednesday,
|
|
1234
|
-
thursday: this.config.checkThursday,
|
|
1235
|
-
friday: this.config.checkFriday,
|
|
1236
|
-
saturday: this.config.checkSaturday,
|
|
1237
|
-
sunday: this.config.checkSunday,
|
|
1238
|
-
};
|
|
1239
1214
|
|
|
1240
|
-
|
|
1241
|
-
if (choosedDays.tuesday) checkDays.push(2);
|
|
1242
|
-
if (choosedDays.wednesday) checkDays.push(3);
|
|
1243
|
-
if (choosedDays.thursday) checkDays.push(4);
|
|
1244
|
-
if (choosedDays.friday) checkDays.push(5);
|
|
1245
|
-
if (choosedDays.saturday) checkDays.push(6);
|
|
1246
|
-
if (choosedDays.sunday) checkDays.push(0);
|
|
1247
|
-
|
|
1248
|
-
//Check if the message should be send today
|
|
1249
|
-
checkDays.forEach(object => {
|
|
1250
|
-
if((object >= 0) && today == object){
|
|
1251
|
-
checkToday = true;
|
|
1252
|
-
}
|
|
1253
|
-
});
|
|
1215
|
+
try {
|
|
1254
1216
|
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1217
|
+
const now = new Date(); // get date
|
|
1218
|
+
const today = now.getDay();
|
|
1219
|
+
const checkDays = []; // list of selected days
|
|
1220
|
+
let checkToday; // indicator if selected day is today
|
|
1221
|
+
|
|
1222
|
+
// push the selected days in list
|
|
1223
|
+
if (this.config.checkMonday) checkDays.push(1);
|
|
1224
|
+
if (this.config.checkTuesday) checkDays.push(2);
|
|
1225
|
+
if (this.config.checkWednesday) checkDays.push(3);
|
|
1226
|
+
if (this.config.checkThursday) checkDays.push(4);
|
|
1227
|
+
if (this.config.checkFriday) checkDays.push(5);
|
|
1228
|
+
if (this.config.checkSaturday) checkDays.push(6);
|
|
1229
|
+
if (this.config.checkSunday) checkDays.push(0);
|
|
1230
|
+
|
|
1231
|
+
//Check if the message should be send today
|
|
1232
|
+
checkDays.forEach(object => {
|
|
1233
|
+
if((object >= 0) && today == object){
|
|
1234
|
+
checkToday = true;
|
|
1235
|
+
}
|
|
1236
|
+
});
|
|
1262
1237
|
|
|
1263
|
-
|
|
1238
|
+
if (checkDays.length >= 1) { // check if an day is selected
|
|
1239
|
+
this.log.debug(`Number of selected days: ${checkDays.length}. Send Message on: ${(checkDays).join(', ')} ...`);
|
|
1240
|
+
} else {
|
|
1241
|
+
this.log.warn(`No days selected. Please check the instance configuration!`);
|
|
1242
|
+
return; // break off function if no day is selected
|
|
1243
|
+
}
|
|
1264
1244
|
|
|
1265
|
-
//Check if the message for low battery was already sent today
|
|
1245
|
+
// Check if the message for low battery was already sent today
|
|
1266
1246
|
const lastBatteryNotifyIndicator = await this.getOwnInitValue('info.lastBatteryNotification');
|
|
1267
1247
|
|
|
1268
|
-
|
|
1248
|
+
// set indicator for send message first to 'false', after sending to 'true'
|
|
1249
|
+
if (now.getHours() < 11) {await this.setStateAsync('info.lastBatteryNotification', false, true);}
|
|
1250
|
+
|
|
1251
|
+
// if time is > 11 (12:00 pm create message for low battery devices)
|
|
1269
1252
|
if ((now.getHours() > 11) && (!lastBatteryNotifyIndicator) && (checkToday != undefined)){
|
|
1270
|
-
let
|
|
1253
|
+
let msg = '';
|
|
1271
1254
|
|
|
1272
1255
|
for (const id of this.batteryLowPowered) {
|
|
1273
|
-
|
|
1256
|
+
msg = '\n' + id['Device'] + ' (' + id['Battery'] + ')'.split(', ');
|
|
1274
1257
|
}
|
|
1275
1258
|
|
|
1276
1259
|
if (this.lowBatteryPoweredCount > 0) {
|
|
1277
|
-
this.log.info(`Niedrige Batteriezustände: ${
|
|
1278
|
-
await this.setStateAsync('lastNotification',
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
try {
|
|
1282
|
-
await this.sendPushover(`Niedrige Batteriezustände: ${infotext}`);
|
|
1283
|
-
} catch (e) {
|
|
1284
|
-
this.log.warn (`Getting error at sending pushover notification ${e}`);
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
if (this.config.instanceTelegram) {
|
|
1288
|
-
try {
|
|
1289
|
-
await this.sendTelegram(`Niedrige Batteriezustände: ${infotext}`);
|
|
1290
|
-
} catch (e) {
|
|
1291
|
-
this.log.warn (`Getting error at sending telegram notification ${e}`);
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
if (this.config.instanceWhatsapp) {
|
|
1295
|
-
try {
|
|
1296
|
-
await this.sendWhatsapp(`Niedrige Batteriezustände: ${infotext}`);
|
|
1297
|
-
} catch (e) {
|
|
1298
|
-
this.log.warn (`Getting error at sending whatsapp notification ${e}`);
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1301
|
-
if (this.config.instanceEmail) {
|
|
1302
|
-
try {
|
|
1303
|
-
await this.sendEmail(`Niedrige Batteriezustände: ${infotext}`);
|
|
1304
|
-
} catch (e) {
|
|
1305
|
-
this.log.warn (`Getting error at sending email notification ${e}`);
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
if (this.config.instanceJarvis) {
|
|
1309
|
-
try {
|
|
1310
|
-
await this.sendJarvis('{"title":"'+ this.config.titleJarvis +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message":" ' + this.lowBatteryPoweredCount + ' Geräte mit schwacher Batterie","display": "drawer"}');
|
|
1311
|
-
} catch (e) {
|
|
1312
|
-
this.log.warn (`Getting error at sending jarvis notification ${e}`);
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
if (this.config.instanceLovelace) {
|
|
1316
|
-
try {
|
|
1317
|
-
await this.sendLovelace('{"message":" ' + this.lowBatteryPoweredCount + ' Geräte mit schwacher Batterie", "title":"'+ this.config.titleLovelace +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')"}');
|
|
1318
|
-
} catch (e) {
|
|
1319
|
-
this.log.warn (`Getting error at sending lovelace notification ${e}`);
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1260
|
+
this.log.info(`Niedrige Batteriezustände: ${msg}`);
|
|
1261
|
+
await this.setStateAsync('lastNotification', `Niedrige Batteriezustände: ${msg}`, true);
|
|
1262
|
+
|
|
1263
|
+
await this.sendNotification(msg);
|
|
1322
1264
|
|
|
1323
1265
|
await this.setStateAsync('info.lastBatteryNotification', true, true);
|
|
1324
1266
|
}
|
|
1325
1267
|
}
|
|
1326
|
-
} catch (
|
|
1327
|
-
this.
|
|
1268
|
+
} catch (error) {
|
|
1269
|
+
this.errorReporting('[sendOfflineMessage]', error);
|
|
1328
1270
|
}
|
|
1271
|
+
|
|
1329
1272
|
this.log.debug(`Finished the function: ${this.sendBatteryNotifications.name}`);
|
|
1330
1273
|
}//<--End of battery notification
|
|
1331
1274
|
|
|
1275
|
+
|
|
1276
|
+
async resetVars() {
|
|
1277
|
+
//Reset all arrays and counts
|
|
1278
|
+
this.log.debug(`Function started: ${this.resetVars.name}`);
|
|
1279
|
+
|
|
1280
|
+
// arrays
|
|
1281
|
+
this.offlineDevices = [],
|
|
1282
|
+
this.linkQualityDevices = [];
|
|
1283
|
+
this.batteryPowered = [];
|
|
1284
|
+
this.batteryLowPowered = [];
|
|
1285
|
+
this.listAllDevices = [];
|
|
1286
|
+
|
|
1287
|
+
// counts
|
|
1288
|
+
this.offlineDevicesCount = 0;
|
|
1289
|
+
this.deviceCounter = 0;
|
|
1290
|
+
this.linkQualityCount = 0;
|
|
1291
|
+
this.batteryPoweredCount = 0;
|
|
1292
|
+
this.lowBatteryPoweredCount = 0;
|
|
1293
|
+
|
|
1294
|
+
this.deviceReachable = '';
|
|
1295
|
+
|
|
1296
|
+
this.log.debug(`Function finished: ${this.resetVars.name}`);
|
|
1297
|
+
} // <-- end of resetVars
|
|
1298
|
+
|
|
1299
|
+
|
|
1300
|
+
/**
|
|
1301
|
+
* @param {string} [adptName] - Adaptername
|
|
1302
|
+
*/
|
|
1332
1303
|
async writeDatapoints(adptName) {
|
|
1333
|
-
|
|
1334
|
-
= Write Datapoints =
|
|
1335
|
-
=============================================*/
|
|
1304
|
+
// fill the datapoints
|
|
1336
1305
|
|
|
1337
1306
|
this.log.debug(`Start the function: ${this.writeDatapoints.name}`);
|
|
1338
1307
|
|
|
1339
1308
|
try {
|
|
1340
1309
|
|
|
1341
1310
|
let dpSubFolder;
|
|
1342
|
-
|
|
1311
|
+
//write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
|
|
1312
|
+
if (adptName) {
|
|
1343
1313
|
dpSubFolder = adptName + '.';
|
|
1344
1314
|
} else {
|
|
1345
1315
|
dpSubFolder = '';}
|
|
@@ -1350,7 +1320,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1350
1320
|
await this.setStateAsync(`${dpSubFolder}lowBatteryCount`, {val: this.lowBatteryPoweredCount, ack: true});
|
|
1351
1321
|
|
|
1352
1322
|
if (this.deviceCounter == 0) {
|
|
1353
|
-
|
|
1323
|
+
// if no device is count, write the JSON List with default value
|
|
1324
|
+
this.listAllDevices = [{'Device': '--none--', 'Adapter': '', 'Battery': '', 'Last contact': '', 'Signal strength': ''}];
|
|
1354
1325
|
|
|
1355
1326
|
await this.setStateAsync(`${dpSubFolder}listAll`, {val: JSON.stringify(this.listAllDevices), ack: true});
|
|
1356
1327
|
} else {
|
|
@@ -1358,7 +1329,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1358
1329
|
}
|
|
1359
1330
|
|
|
1360
1331
|
if (this.linkQualityCount == 0) {
|
|
1361
|
-
|
|
1332
|
+
// if no device is count, write the JSON List with default value
|
|
1333
|
+
this.linkQualityDevices = [{'Device': '--none--', 'Adapter': '', 'Signal strength': ''}];
|
|
1362
1334
|
|
|
1363
1335
|
await this.setStateAsync(`${dpSubFolder}linkQualityList`, {val: JSON.stringify(this.linkQualityDevices), ack: true});
|
|
1364
1336
|
} else {
|
|
@@ -1367,7 +1339,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1367
1339
|
|
|
1368
1340
|
|
|
1369
1341
|
if (this.offlineDevicesCount == 0) {
|
|
1370
|
-
|
|
1342
|
+
// if no device is count, write the JSON List with default value
|
|
1343
|
+
this.offlineDevices = [{'Device': '--none--', 'Adapter': '', 'Last contact': ''}];
|
|
1371
1344
|
|
|
1372
1345
|
await this.setStateAsync(`${dpSubFolder}offlineList`, {val: JSON.stringify(this.offlineDevices), ack: true});
|
|
1373
1346
|
} else {
|
|
@@ -1375,7 +1348,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1375
1348
|
}
|
|
1376
1349
|
|
|
1377
1350
|
if (this.batteryPoweredCount == 0) {
|
|
1378
|
-
|
|
1351
|
+
// if no device is count, write the JSON List with default value
|
|
1352
|
+
this.batteryPowered = [{'Device': '--none--', 'Adapter': '', 'Battery': ''}];
|
|
1379
1353
|
|
|
1380
1354
|
await this.setStateAsync(`${dpSubFolder}batteryList`, {val: JSON.stringify(this.batteryPowered), ack: true});
|
|
1381
1355
|
} else {
|
|
@@ -1383,23 +1357,42 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1383
1357
|
}
|
|
1384
1358
|
|
|
1385
1359
|
if (this.lowBatteryPoweredCount == 0) {
|
|
1386
|
-
|
|
1360
|
+
// if no device is count, write the JSON List with default value
|
|
1361
|
+
this.batteryLowPowered = [{'Device': '--none--', 'Adapter': '', 'Battery': ''}];
|
|
1387
1362
|
|
|
1388
1363
|
await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {val: JSON.stringify(this.batteryLowPowered), ack: true});
|
|
1389
1364
|
} else {
|
|
1390
1365
|
await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {val: JSON.stringify(this.batteryLowPowered), ack: true});
|
|
1391
1366
|
}
|
|
1392
1367
|
|
|
1393
|
-
//
|
|
1368
|
+
// create timestamp of last run
|
|
1394
1369
|
const lastCheck = this.formatDate(new Date(), 'DD.MM.YYYY') + ' - ' + this.formatDate(new Date(), 'hh:mm:ss');
|
|
1395
1370
|
await this.setStateAsync('lastCheck', lastCheck, true);
|
|
1396
1371
|
}
|
|
1397
|
-
catch (
|
|
1398
|
-
this.
|
|
1372
|
+
catch (error) {
|
|
1373
|
+
this.errorReporting('[writeDatapoints]', error);
|
|
1399
1374
|
}
|
|
1400
1375
|
this.log.debug(`Function finished: ${this.writeDatapoints.name}`);
|
|
1401
1376
|
}//<--End of writing Datapoints
|
|
1402
1377
|
|
|
1378
|
+
/**
|
|
1379
|
+
* @param {string} [codePart] - Message Prefix
|
|
1380
|
+
* @param {object} [error] - Sentry message
|
|
1381
|
+
*/
|
|
1382
|
+
errorReporting(codePart, error) {
|
|
1383
|
+
const msg = `[${codePart}] error: ${error.message}`;
|
|
1384
|
+
if (enableSendSentry) {
|
|
1385
|
+
if (this.supportsFeature && this.supportsFeature('PLUGINS')) {
|
|
1386
|
+
const sentryInstance = this.getPluginInstance('sentry');
|
|
1387
|
+
if (sentryInstance) {
|
|
1388
|
+
this.log.warn(`Error catched and sent to Sentry, error: ${msg}`);
|
|
1389
|
+
sentryInstance.getSentryObject().captureException(msg);
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
} else {
|
|
1393
|
+
this.log.error(`Sentry disabled, error catched : ${msg}`);
|
|
1394
|
+
}
|
|
1395
|
+
} // <-- end of errorReporting
|
|
1403
1396
|
|
|
1404
1397
|
|
|
1405
1398
|
onUnload(callback) {
|