iobroker.device-watcher 2.3.0 → 2.4.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/main.js CHANGED
@@ -10,7 +10,7 @@ const schedule = require('node-schedule');
10
10
  const arrApart = require('./lib/arrApart.js'); // list of supported adapters
11
11
 
12
12
  // Sentry error reporting, disable when testing code!
13
- const enableSendSentry = false;
13
+ const enableSendSentry = true;
14
14
 
15
15
  // indicator if the adapter is running or not (for intervall/shedule)
16
16
  let isUnloaded = false;
@@ -32,7 +32,7 @@ class DeviceWatcher extends utils.Adapter {
32
32
  this.blacklistLists = [];
33
33
  this.blacklistAdapterLists = [];
34
34
  this.blacklistNotify = [];
35
- this.arrDev = [];
35
+ this.selAdapter = [];
36
36
  this.adapterSelected = [];
37
37
  this.upgradableList = [];
38
38
 
@@ -40,6 +40,7 @@ class DeviceWatcher extends utils.Adapter {
40
40
  this.listAllDevicesRaw = [];
41
41
  this.batteryLowPoweredRaw = [];
42
42
  this.offlineDevicesRaw = [];
43
+ this.upgradableDevicesRaw = [];
43
44
 
44
45
  // counts
45
46
  this.offlineDevicesCount = 0;
@@ -65,14 +66,12 @@ class DeviceWatcher extends utils.Adapter {
65
66
  async onReady() {
66
67
  this.log.debug(`Adapter ${adapterName} was started`);
67
68
 
68
- isUnloaded = false;
69
-
70
69
  try {
71
70
  this.listOnlyBattery = this.config.listOnlyBattery;
72
71
  this.createOwnFolder = this.config.createOwnFolder;
73
72
  this.createHtmlList = this.config.createHtmlList;
74
73
 
75
- this.supAdapter = {
74
+ this.configSetAdapter = {
76
75
  alexa2: this.config.alexa2Devices,
77
76
  apcups: this.config.apcupsDevices,
78
77
  ble: this.config.bleDevices,
@@ -86,6 +85,7 @@ class DeviceWatcher extends utils.Adapter {
86
85
  harmony: this.config.harmonyDevices,
87
86
  hmiP: this.config.hmiPDevices,
88
87
  hmrpc: this.config.hmrpcDevices,
88
+ homeconnect: this.config.homeconnectDevices,
89
89
  hs100: this.config.hs100Devices,
90
90
  hue: this.config.hueDevices,
91
91
  hueExt: this.config.hueExtDevices,
@@ -106,6 +106,7 @@ class DeviceWatcher extends utils.Adapter {
106
106
  ping: this.config.pingDevices,
107
107
  roomba: this.config.roombaDevices,
108
108
  shelly: this.config.shellyDevices,
109
+ smartgarden: this.config.smartgardenDevices,
109
110
  sonoff: this.config.sonoffDevices,
110
111
  sonos: this.config.sonosDevices,
111
112
  sureflap: this.config.sureflapDevices,
@@ -121,7 +122,7 @@ class DeviceWatcher extends utils.Adapter {
121
122
  zwave: this.config.zwaveDevices,
122
123
  };
123
124
 
124
- this.maxMinutes = {
125
+ this.configMaxMinutes = {
125
126
  alexa2: this.config.alexa2MaxMinutes,
126
127
  apcups: this.config.apcupsMaxMinutes,
127
128
  ble: this.config.bleMaxMinutes,
@@ -135,6 +136,7 @@ class DeviceWatcher extends utils.Adapter {
135
136
  harmony: this.config.harmonyMaxMinutes,
136
137
  hmiP: this.config.hmiPMaxMinutes,
137
138
  hmrpc: this.config.hmrpcMaxMinutes,
139
+ homeconnect: this.config.homeconnectMaxMinutes,
138
140
  hs100: this.config.hs100MaxMinutes,
139
141
  hue: this.config.hueMaxMinutes,
140
142
  hueExt: this.config.hueextMaxMinutes,
@@ -155,6 +157,7 @@ class DeviceWatcher extends utils.Adapter {
155
157
  ping: this.config.pingMaxMinutes,
156
158
  roomba: this.config.roombaMaxMinutes,
157
159
  shelly: this.config.shellyMaxMinutes,
160
+ smartgarden: this.config.smartgardenMaxMinutes,
158
161
  sonoff: this.config.sonoffMaxMinutes,
159
162
  sonos: this.config.sonosMaxMinutes,
160
163
  sureflap: this.config.sureflapMaxMinutes,
@@ -171,20 +174,16 @@ class DeviceWatcher extends utils.Adapter {
171
174
  };
172
175
 
173
176
  for (const [id] of Object.entries(arrApart)) {
174
- if (!isUnloaded) {
175
- if (this.supAdapter[id]) {
176
- this.arrDev.push(arrApart[id]);
177
- this.adapterSelected.push(await this.capitalize(id));
178
- }
179
- } else {
180
- return; // cancel run if unloaded was called.
177
+ if (this.configSetAdapter[id]) {
178
+ this.selAdapter.push(arrApart[id]);
179
+ this.adapterSelected.push(await this.capitalize(id));
181
180
  }
182
181
  }
183
182
 
184
183
  //Check if an Adapter is selected.
185
184
  if (this.adapterSelected.length >= 1) {
186
185
  // show list in debug log
187
- this.log.debug(JSON.stringify(this.arrDev));
186
+ this.log.debug(JSON.stringify(this.selAdapter));
188
187
 
189
188
  this.log.info(`Number of selected adapters: ${this.adapterSelected.length}. Loading data from: ${this.adapterSelected.join(', ')} ...`);
190
189
  } else {
@@ -203,7 +202,7 @@ class DeviceWatcher extends utils.Adapter {
203
202
  if (this.createOwnFolder) {
204
203
  try {
205
204
  for (const [id] of Object.entries(arrApart)) {
206
- if (this.supAdapter !== undefined && this.supAdapter[id]) {
205
+ if (this.configSetAdapter !== undefined && this.configSetAdapter[id]) {
207
206
  await this.createDPsForEachAdapter(id);
208
207
  if (this.createHtmlList) await this.createHtmlListDatapoints(id);
209
208
  this.log.debug(`Created datapoints for ${this.capitalize(id)}`);
@@ -214,7 +213,7 @@ class DeviceWatcher extends utils.Adapter {
214
213
  }
215
214
  }
216
215
 
217
- // create HTML list
216
+ // create HTML list datapoints
218
217
  if (this.createHtmlList) await this.createHtmlListDatapoints();
219
218
 
220
219
  //read data first at start
@@ -250,79 +249,115 @@ class DeviceWatcher extends utils.Adapter {
250
249
  let oldLowBatState;
251
250
  let contactData;
252
251
  let oldStatus;
252
+ let isLowBatValue;
253
253
 
254
254
  for (const device of this.listAllDevicesRaw) {
255
255
  // On statechange update available datapoint
256
256
  switch (id) {
257
+ case device.instanceAliveDP:
258
+ device.instanceAlive = state.val;
259
+ break;
260
+
257
261
  case device.UpdateDP:
258
- if (state.val) {
262
+ if (device.instanceAlive) {
259
263
  device.Upgradable = state.val;
260
- if (!this.blacklistNotify.includes(device.Path)) {
261
- await this.sendDeviceUpdatesNotification(device.Device, device.Adapter);
264
+ if (state.val) {
265
+ if (!this.blacklistNotify.includes(device.Path)) {
266
+ await this.sendDeviceUpdatesNotification(device.Device, device.Adapter);
267
+ }
262
268
  }
263
269
  }
264
270
  break;
265
271
 
266
272
  case device.SignalStrengthDP:
267
- device.SignalStrength = await this.calculateSignalStrength(state, device.adapterID);
273
+ if (device.instanceAlive) {
274
+ device.SignalStrength = await this.calculateSignalStrength(state, device.adapterID);
275
+ }
268
276
  break;
269
277
 
270
278
  case device.batteryDP:
271
- if (device.isBatteryDevice) {
272
- oldLowBatState = device.LowBat;
273
- batteryData = await this.getBatteryData(state.val, oldLowBatState, device.adapterID);
274
-
275
- device.Battery = batteryData[0];
276
- device.BatteryRaw = batteryData[2];
277
- device.LowBat = await this.setLowbatIndicator(state.val, undefined, device.LowBatDP);
279
+ if (device.instanceAlive) {
280
+ if (device.isBatteryDevice) {
281
+ oldLowBatState = device.LowBat;
282
+ batteryData = await this.getBatteryData(state.val, oldLowBatState, device.adapterID);
283
+
284
+ device.Battery = batteryData[0];
285
+ device.BatteryRaw = batteryData[2];
286
+ if (device.LowBatDP !== 'none') {
287
+ isLowBatValue = await this.getInitValue(device.LowBatDP);
288
+ } else {
289
+ isLowBatValue = undefined;
290
+ }
291
+ device.LowBat = await this.setLowbatIndicator(state.val, isLowBatValue, device.faultReport, device.adapterID);
278
292
 
279
- if (device.LowBat && oldLowBatState !== device.LowBat) {
280
- if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(device.Path)) {
281
- await this.sendLowBatNoticiation(device.Device, device.Adapter, device.Battery);
293
+ if (device.LowBat && oldLowBatState !== device.LowBat) {
294
+ if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(device.Path)) {
295
+ await this.sendLowBatNoticiation(device.Device, device.Adapter, device.Battery);
296
+ }
282
297
  }
283
298
  }
284
299
  }
285
300
  break;
286
301
 
287
302
  case device.LowBatDP:
288
- if (device.isBatteryDevice) {
289
- oldLowBatState = device.LowBat;
290
- batteryData = await this.getBatteryData(device.BatteryRaw, state.val, device.adapterID);
291
- device.Battery = batteryData[0];
292
- device.BatteryRaw = batteryData[2];
293
- device.LowBat = await this.setLowbatIndicator(device.BatteryRaw, state.val, device.LowBatDP);
294
-
295
- if (device.LowBat && oldLowBatState !== device.LowBat) {
296
- if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(device.Path)) {
297
- await this.sendLowBatNoticiation(device.Device, device.Adapter, device.Battery);
303
+ if (device.instanceAlive) {
304
+ if (device.isBatteryDevice) {
305
+ oldLowBatState = device.LowBat;
306
+ batteryData = await this.getBatteryData(device.BatteryRaw, state.val, device.adapterID);
307
+ device.Battery = batteryData[0];
308
+ device.BatteryRaw = batteryData[2];
309
+ device.LowBat = await this.setLowbatIndicator(device.BatteryRaw, state.val, device.faultReport, device.adapterID);
310
+
311
+ if (device.LowBat && oldLowBatState !== device.LowBat) {
312
+ if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(device.Path)) {
313
+ await this.sendLowBatNoticiation(device.Device, device.Adapter, device.Battery);
314
+ }
298
315
  }
299
316
  }
300
317
  }
318
+ break;
319
+
320
+ case device.faultReportDP:
321
+ if (device.instanceAlive) {
322
+ if (device.isBatteryDevice) {
323
+ oldLowBatState = device.LowBat;
324
+ batteryData = await this.getBatteryData(device.BatteryRaw, oldLowBatState, device.adapterID);
301
325
 
326
+ device.Battery = batteryData[0];
327
+ device.BatteryRaw = batteryData[2];
328
+ device.LowBat = await this.setLowbatIndicator(device.BatteryRaw, undefined, state.val, device.adapterID);
329
+
330
+ if (device.LowBat && oldLowBatState !== device.LowBat) {
331
+ if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(device.Path)) {
332
+ await this.sendLowBatNoticiation(device.Device, device.Adapter, device.Battery);
333
+ }
334
+ }
335
+ }
336
+ }
302
337
  break;
338
+
303
339
  case device.UnreachDP:
304
- case device.DeviceStateSelectorDP:
305
- case device.rssiPeerSelectorDP:
306
- case device.Path:
307
- oldStatus = device.Status;
308
- device.UnreachState = await this.getInitValue(device.UnreachDP);
309
- contactData = await this.getOnlineState(
310
- device.Path,
311
- device.adapterID,
312
- device.UnreachDP,
313
- device.SignalStrength,
314
- device.UnreachState,
315
- device.DeviceStateSelectorDP,
316
- device.rssiPeerSelectorDP,
317
- );
318
- if (contactData !== undefined) {
319
- device.LastContact = contactData[0];
320
- device.Status = contactData[1];
321
- device.SignalStrength = contactData[2];
322
- }
340
+ if (device.instanceAlive) {
341
+ oldStatus = device.Status;
342
+ device.UnreachState = await this.getInitValue(device.UnreachDP);
343
+ contactData = await this.getOnlineState(
344
+ device.timeSelector,
345
+ device.adapterID,
346
+ device.UnreachDP,
347
+ device.SignalStrength,
348
+ device.UnreachState,
349
+ device.DeviceStateSelectorDP,
350
+ device.rssiPeerSelectorDP,
351
+ );
352
+ if (contactData !== undefined) {
353
+ device.LastContact = contactData[0];
354
+ device.Status = contactData[1];
355
+ device.SignalStrength = contactData[2];
356
+ }
323
357
 
324
- if (this.config.checkSendOfflineMsg && oldStatus !== device.Status && !this.blacklistNotify.includes(device.Path)) {
325
- await this.sendOfflineNotifications(device.Device, device.Adapter, device.Status, device.LastContact);
358
+ if (this.config.checkSendOfflineMsg && oldStatus !== device.Status && !this.blacklistNotify.includes(device.Path)) {
359
+ await this.sendOfflineNotifications(device.Device, device.Adapter, device.Status, device.LastContact);
360
+ }
326
361
  }
327
362
  break;
328
363
  }
@@ -370,6 +405,37 @@ class DeviceWatcher extends utils.Adapter {
370
405
  }
371
406
  }
372
407
 
408
+ /**
409
+ * main function
410
+ */
411
+ async main() {
412
+ this.log.debug(`Function started: ${this.main.name}`);
413
+
414
+ // fill counts and lists of all selected adapter
415
+ try {
416
+ await this.createDataOfAllAdapter();
417
+ this.log.debug(`Created and filled data for all adapters`);
418
+ } catch (error) {
419
+ this.errorReporting('[main - create data of all adapter]', error);
420
+ }
421
+
422
+ // fill datapoints for each adapter if selected
423
+ if (this.createOwnFolder) {
424
+ try {
425
+ for (const [id] of Object.entries(arrApart)) {
426
+ if (this.configSetAdapter !== undefined && this.configSetAdapter[id]) {
427
+ await this.createDataForEachAdapter(id);
428
+ this.log.debug(`Created and filled data for ${this.capitalize(id)}`);
429
+ }
430
+ }
431
+ } catch (error) {
432
+ this.errorReporting('[main - create and fill datapoints for each adapter]', error);
433
+ }
434
+ }
435
+
436
+ this.log.debug(`Function finished: ${this.main.name}`);
437
+ } //<--End of main function
438
+
373
439
  /**
374
440
  * refresh data with interval
375
441
  * is neccessary to refresh lastContact data, especially of devices without state changes
@@ -383,7 +449,7 @@ class DeviceWatcher extends utils.Adapter {
383
449
 
384
450
  if (this.createOwnFolder) {
385
451
  for (const [id] of Object.entries(arrApart)) {
386
- if (this.supAdapter !== undefined && this.supAdapter[id]) {
452
+ if (this.configSetAdapter !== undefined && this.configSetAdapter[id]) {
387
453
  await this.createLists(id);
388
454
  await this.writeDatapoints(id);
389
455
  this.log.debug(`Created and filled data for ${this.capitalize(id)}`);
@@ -409,117 +475,284 @@ class DeviceWatcher extends utils.Adapter {
409
475
  } // <-- refreshData end
410
476
 
411
477
  /**
412
- * main function
478
+ * create blacklist
413
479
  */
414
- async main() {
415
- this.log.debug(`Function started: ${this.main.name}`);
480
+ async createBlacklist() {
481
+ this.log.debug(`Function started: ${this.createBlacklist.name}`);
416
482
 
417
- // fill counts and lists of all selected adapter
418
- try {
419
- await this.createDataOfAllAdapter();
420
- this.log.debug(`Created and filled data for all adapters`);
421
- } catch (error) {
422
- this.errorReporting('[main - create data of all adapter]', error);
423
- }
483
+ const myBlacklist = this.config.tableBlacklist;
424
484
 
425
- // fill datapoints for each adapter if selected
426
- if (this.createOwnFolder) {
485
+ for (const i in myBlacklist) {
427
486
  try {
428
- for (const [id] of Object.entries(arrApart)) {
429
- if (this.supAdapter !== undefined && this.supAdapter[id]) {
430
- await this.createDataForEachAdapter(id);
431
- this.log.debug(`Created and filled data for ${this.capitalize(id)}`);
432
- }
487
+ const blacklistParse = await this.parseData(myBlacklist[i].devices);
488
+ // push devices in list to ignor device in lists
489
+ if (myBlacklist[i].checkIgnorLists) {
490
+ this.blacklistLists.push(blacklistParse.path);
491
+ }
492
+ if (myBlacklist[i].checkIgnorAdapterLists) {
493
+ this.blacklistAdapterLists.push(blacklistParse.path);
494
+ }
495
+ // push devices in list to ignor device in notifications
496
+ if (myBlacklist[i].checkIgnorNotify) {
497
+ this.blacklistNotify.push(blacklistParse.path);
433
498
  }
434
499
  } catch (error) {
435
- this.errorReporting('[main - create and fill datapoints for each adapter]', error);
500
+ this.errorReporting('[createBlacklist]', error);
436
501
  }
437
502
  }
438
503
 
439
- this.log.debug(`Function finished: ${this.main.name}`);
440
- } //<--End of main function
504
+ if (this.blacklistLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistLists}`);
505
+ if (this.blacklistAdapterLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistAdapterLists}`);
506
+ if (this.blacklistNotify.length >= 1) this.log.info(`Found items on blacklist for notificatioons: ${this.blacklistNotify}`);
441
507
 
442
- /**
443
- * @param {string} id - id which should be capitalize
444
- */
445
- capitalize(id) {
446
- //make the first letter uppercase
447
- return id && id[0].toUpperCase() + id.slice(1);
508
+ this.log.debug(`Function finished: ${this.createBlacklist.name}`);
448
509
  }
449
510
 
450
511
  /**
451
- * @param {number} dpValue - get Time of this datapoint
512
+ * @param {object} i - Device Object
452
513
  */
453
- async getTimestamp(dpValue) {
454
- const time = new Date();
455
- return (dpValue = Math.round((time.getTime() - dpValue) / 1000 / 60));
456
- }
514
+ async createData(i) {
515
+ const devices = await this.getForeignStatesAsync(this.selAdapter[i].Selektor);
516
+ const adapterID = this.selAdapter[i].adapterID;
457
517
 
458
- /**
459
- * @param {object} obj - State of datapoint
460
- */
461
- async getInitValue(obj) {
462
- //state can be null or undefinded
463
- const foreignState = await this.getForeignStateAsync(obj);
464
- if (foreignState) return foreignState.val;
465
- }
518
+ /*---------- Start of loop ----------*/
519
+ for (const [id] of Object.entries(devices)) {
520
+ /*=============================================
521
+ = get Instanz =
522
+ =============================================*/
523
+ const instance = id.slice(0, id.indexOf('.') + 2);
524
+ const instanceAliveDP = `system.adapter.${instance}.alive`;
525
+ const instanceAlive = await this.getInitValue(instanceAliveDP);
526
+ this.subscribeForeignStates(instanceAliveDP);
466
527
 
467
- /**
468
- * @param {object} obj - State of own datapoint
469
- */
470
- async getOwnInitValue(obj) {
471
- //state can be null or undefinded for own states
472
- const stateVal = await this.getStateAsync(obj);
473
- if (stateVal) return stateVal.val;
474
- }
528
+ /*=============================================
529
+ = Get device name =
530
+ =============================================*/
531
+ const deviceName = await this.getDeviceName(id, i);
475
532
 
476
- /**
477
- * @param {object} data - object
478
- */
479
- async parseData(data) {
480
- if (!data) return {};
481
- if (typeof data === 'object') return data;
482
- if (typeof data === 'string') return JSON.parse(data);
483
- return {};
484
- }
533
+ /*=============================================
534
+ = Get adapter name =
535
+ =============================================*/
536
+ const adapter = this.selAdapter[i].adapter;
485
537
 
486
- /**
487
- * create blacklist
488
- */
489
- async createBlacklist() {
490
- this.log.debug(`Function started: ${this.createBlacklist.name}`);
538
+ /*=============================================
539
+ = Get path to datapoints =
540
+ =============================================*/
541
+ const currDeviceString = id.slice(0, id.lastIndexOf('.') + 1 - 1);
542
+ const shortCurrDeviceString = currDeviceString.slice(0, currDeviceString.lastIndexOf('.') + 1 - 1);
491
543
 
492
- if (!isUnloaded) {
493
- const myBlacklist = this.config.tableBlacklist;
544
+ /*=============================================
545
+ = Get signal strength =
546
+ =============================================*/
547
+ let deviceQualityDP = currDeviceString + this.selAdapter[i].rssiState;
548
+ let deviceQualityState;
494
549
 
495
- for (const i in myBlacklist) {
496
- try {
497
- const blacklistParse = await this.parseData(myBlacklist[i].devices);
498
- // push devices in list to ignor device in lists
499
- if (myBlacklist[i].checkIgnorLists) {
500
- this.blacklistLists.push(blacklistParse.path);
501
- }
502
- if (myBlacklist[i].checkIgnorAdapterLists) {
503
- this.blacklistAdapterLists.push(blacklistParse.path);
504
- }
505
- // push devices in list to ignor device in notifications
506
- if (myBlacklist[i].checkIgnorNotify) {
507
- this.blacklistNotify.push(blacklistParse.path);
550
+ switch (adapterID) {
551
+ case 'mihomeVacuum':
552
+ deviceQualityDP = shortCurrDeviceString + this.selAdapter[i].rssiState;
553
+ deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
554
+ break;
555
+
556
+ case 'netatmo':
557
+ deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
558
+ if (!deviceQualityState) {
559
+ deviceQualityDP = currDeviceString + this.selAdapter[i].rfState;
560
+ deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
508
561
  }
509
- } catch (error) {
510
- this.errorReporting('[createBlacklist]', error);
562
+ break;
563
+
564
+ default:
565
+ deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
566
+ break;
567
+ }
568
+ //subscribe to states
569
+ this.subscribeForeignStates(deviceQualityDP);
570
+
571
+ let linkQuality = await this.calculateSignalStrength(deviceQualityState, adapterID);
572
+
573
+ /*=============================================
574
+ = Get battery data =
575
+ =============================================*/
576
+ let deviceBatteryStateDP;
577
+ let deviceBatteryState;
578
+ let batteryHealth;
579
+ let batteryHealthRaw;
580
+ let lowBatIndicator;
581
+ let isBatteryDevice;
582
+ let isLowBatDP;
583
+ let faultReportingDP;
584
+ let faultReportingState;
585
+
586
+ const deviceChargerStateDP = currDeviceString + this.selAdapter[i].charger;
587
+ const deviceChargerState = await this.getInitValue(deviceChargerStateDP);
588
+
589
+ if (deviceChargerState === undefined || deviceChargerState === false) {
590
+ // Get battery states
591
+ switch (adapterID) {
592
+ case 'hueExt':
593
+ case 'mihomeVacuum':
594
+ case 'mqttNuki':
595
+ deviceBatteryStateDP = shortCurrDeviceString + this.selAdapter[i].battery;
596
+ deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
597
+ if (deviceBatteryState === undefined) {
598
+ deviceBatteryStateDP = shortCurrDeviceString + this.selAdapter[i].battery2;
599
+ deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
600
+ }
601
+ break;
602
+ default:
603
+ deviceBatteryStateDP = currDeviceString + this.selAdapter[i].battery;
604
+ deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
605
+ if (deviceBatteryState === undefined) {
606
+ deviceBatteryStateDP = currDeviceString + this.selAdapter[i].battery2;
607
+ deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
608
+ }
609
+ break;
610
+ }
611
+
612
+ // Get low bat states
613
+ isLowBatDP = currDeviceString + this.selAdapter[i].isLowBat;
614
+ let deviceLowBatState = await this.getInitValue(isLowBatDP);
615
+ if (deviceLowBatState === undefined) {
616
+ isLowBatDP = currDeviceString + this.selAdapter[i].isLowBat2;
617
+ deviceLowBatState = await this.getInitValue(isLowBatDP);
618
+ }
619
+ if (deviceLowBatState === undefined) isLowBatDP = 'none';
620
+
621
+ faultReportingDP = shortCurrDeviceString + this.selAdapter[i].faultReporting;
622
+ faultReportingState = await this.getInitValue(faultReportingDP);
623
+
624
+ //subscribe to states
625
+ this.subscribeForeignStates(deviceBatteryStateDP);
626
+ this.subscribeForeignStates(isLowBatDP);
627
+ this.subscribeForeignStates(faultReportingDP);
628
+
629
+ const batteryData = await this.getBatteryData(deviceBatteryState, deviceLowBatState, adapterID);
630
+ batteryHealth = batteryData[0];
631
+ batteryHealthRaw = batteryData[2];
632
+ isBatteryDevice = batteryData[1];
633
+
634
+ if (isBatteryDevice) {
635
+ lowBatIndicator = await this.setLowbatIndicator(deviceBatteryState, deviceLowBatState, faultReportingState, adapterID);
511
636
  }
512
637
  }
513
638
 
514
- if (this.blacklistLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistLists}`);
515
- if (this.blacklistAdapterLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistAdapterLists}`);
516
- if (this.blacklistNotify.length >= 1) this.log.info(`Found items on blacklist for notificatioons: ${this.blacklistNotify}`);
517
- } else {
518
- return; // cancel run if unloaded was called.
519
- }
639
+ /*=============================================
640
+ = Get last contact of device =
641
+ =============================================*/
642
+ let unreachDP = currDeviceString + this.selAdapter[i].reach;
643
+ const deviceStateSelectorDP = shortCurrDeviceString + this.selAdapter[i].stateValue;
644
+ const rssiPeerSelectorDP = currDeviceString + this.selAdapter[i].rssiPeerState;
645
+ const timeSelector = currDeviceString + this.selAdapter[i].timeSelector;
646
+
647
+ let deviceUnreachState = await this.getInitValue(unreachDP);
648
+ if (deviceUnreachState === undefined) {
649
+ unreachDP = shortCurrDeviceString + this.selAdapter[i].reach;
650
+ deviceUnreachState = await this.getInitValue(shortCurrDeviceString + this.selAdapter[i].reach);
651
+ }
520
652
 
521
- this.log.debug(`Function finished: ${this.createBlacklist.name}`);
522
- }
653
+ // subscribe to states
654
+ this.subscribeForeignStates(timeSelector);
655
+ this.subscribeForeignStates(unreachDP);
656
+ this.subscribeForeignStates(deviceStateSelectorDP);
657
+ this.subscribeForeignStates(rssiPeerSelectorDP);
658
+
659
+ const onlineState = await this.getOnlineState(timeSelector, adapterID, unreachDP, linkQuality, deviceUnreachState, deviceStateSelectorDP, rssiPeerSelectorDP);
660
+ let deviceState;
661
+ let lastContactString;
662
+
663
+ if (onlineState) {
664
+ lastContactString = onlineState[0];
665
+ deviceState = onlineState[1];
666
+ linkQuality = onlineState[2];
667
+ }
668
+
669
+ /*=============================================
670
+ = Get update data =
671
+ =============================================*/
672
+ const deviceUpdateDP = currDeviceString + this.selAdapter[i].upgrade;
673
+ let isUpgradable;
674
+
675
+ if (this.config.checkSendDeviceUpgrade) {
676
+ const deviceUpdateSelector = await this.getInitValue(deviceUpdateDP);
677
+
678
+ if (deviceUpdateSelector) {
679
+ isUpgradable = true;
680
+ } else if (!deviceUpdateSelector) {
681
+ isUpgradable = false;
682
+ }
683
+ // subscribe to states
684
+ this.subscribeForeignStates(deviceUpdateDP);
685
+ }
686
+
687
+ /*=============================================
688
+ = Fill Raw Lists =
689
+ =============================================*/
690
+
691
+ /* Add only devices with battery in the rawlist */
692
+ if (this.listOnlyBattery && isBatteryDevice) {
693
+ this.listAllDevicesRaw.push({
694
+ Path: id,
695
+ instanceAliveDP: instanceAliveDP,
696
+ instanceAlive: instanceAlive,
697
+ Device: deviceName,
698
+ adapterID: adapterID,
699
+ Adapter: adapter,
700
+ timeSelector: timeSelector,
701
+ isBatteryDevice: isBatteryDevice,
702
+ Battery: batteryHealth,
703
+ BatteryRaw: batteryHealthRaw,
704
+ batteryDP: deviceBatteryStateDP,
705
+ LowBat: lowBatIndicator,
706
+ LowBatDP: isLowBatDP,
707
+ faultReport: faultReportingState,
708
+ faultReportDP: faultReportingDP,
709
+ SignalStrengthDP: deviceQualityDP,
710
+ SignalStrength: linkQuality,
711
+ UnreachState: deviceUnreachState,
712
+ UnreachDP: unreachDP,
713
+ DeviceStateSelectorDP: deviceStateSelectorDP,
714
+ rssiPeerSelectorDP: rssiPeerSelectorDP,
715
+ LastContact: lastContactString,
716
+ Status: deviceState,
717
+ UpdateDP: deviceUpdateDP,
718
+ Upgradable: isUpgradable,
719
+ });
720
+ } else {
721
+ /* Add all devices */
722
+ this.listAllDevicesRaw.push({
723
+ Path: id,
724
+ instanceAliveDP: instanceAliveDP,
725
+ instanceAlive: instanceAlive,
726
+ Device: deviceName,
727
+ adapterID: adapterID,
728
+ Adapter: adapter,
729
+ timeSelector: timeSelector,
730
+ isBatteryDevice: isBatteryDevice,
731
+ Battery: batteryHealth,
732
+ BatteryRaw: batteryHealthRaw,
733
+ batteryDP: deviceBatteryStateDP,
734
+ LowBat: lowBatIndicator,
735
+ LowBatDP: isLowBatDP,
736
+ faultReport: faultReportingState,
737
+ faultReportDP: faultReportingDP,
738
+ SignalStrengthDP: deviceQualityDP,
739
+ SignalStrength: linkQuality,
740
+ UnreachState: deviceUnreachState,
741
+ UnreachDP: unreachDP,
742
+ DeviceStateSelectorDP: deviceStateSelectorDP,
743
+ rssiPeerSelectorDP: rssiPeerSelectorDP,
744
+ LastContact: lastContactString,
745
+ Status: deviceState,
746
+ UpdateDP: deviceUpdateDP,
747
+ Upgradable: isUpgradable,
748
+ });
749
+ }
750
+ } // <-- end of loop
751
+ } // <-- end of createData
752
+
753
+ /*=============================================
754
+ = functions to get data =
755
+ =============================================*/
523
756
 
524
757
  /**
525
758
  * @param {object} id - deviceID
@@ -539,25 +772,9 @@ class DeviceWatcher extends utils.Adapter {
539
772
  let folderName;
540
773
  let deviceID;
541
774
 
542
- switch (this.arrDev[i].adapterID) {
543
- // Get ID with currDeviceString from datapoint
544
- case 'switchbotBle':
545
- case 'esphome':
546
- case 'apcups':
547
- deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
548
- break;
549
-
550
- case 'eusec':
551
- deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
552
- if (deviceName === null || deviceName === undefined) {
553
- if (deviceObject && typeof deviceObject === 'object') {
554
- deviceName = deviceObject.common.name;
555
- }
556
- }
557
- break;
558
-
775
+ switch (this.selAdapter[i].adapterID) {
559
776
  case 'fullybrowser':
560
- deviceName = (await this.getInitValue(currDeviceString + this.arrDev[i].id)) + ' ' + (await this.getInitValue(currDeviceString + this.arrDev[i].id2));
777
+ deviceName = (await this.getInitValue(currDeviceString + this.selAdapter[i].id)) + ' ' + (await this.getInitValue(currDeviceString + this.selAdapter[i].id2));
561
778
  break;
562
779
 
563
780
  // Get ID with short currDeviceString from objectjson
@@ -565,6 +782,7 @@ class DeviceWatcher extends utils.Adapter {
565
782
  case 'hmrpc':
566
783
  case 'nukiExt':
567
784
  case 'wled':
785
+ case 'mqttNuki':
568
786
  if (shortDeviceObject && typeof shortDeviceObject === 'object') {
569
787
  deviceName = shortDeviceObject.common.name;
570
788
  }
@@ -581,7 +799,7 @@ class DeviceWatcher extends utils.Adapter {
581
799
  case 'mihomeVacuum':
582
800
  case 'roomba':
583
801
  folderName = shortCurrDeviceString.slice(shortCurrDeviceString.lastIndexOf('.') + 1);
584
- deviceID = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].id);
802
+ deviceID = await this.getInitValue(shortCurrDeviceString + this.selAdapter[i].id);
585
803
  deviceName = `I${folderName} ${deviceID}`;
586
804
  break;
587
805
 
@@ -610,8 +828,11 @@ class DeviceWatcher extends utils.Adapter {
610
828
 
611
829
  // Get ID with main selektor from objectjson
612
830
  default:
613
- if (deviceObject && typeof deviceObject === 'object') {
614
- deviceName = deviceObject.common.name;
831
+ if (this.selAdapter[i].id !== 'none' || this.selAdapter[i].id !== undefined) deviceName = await this.getInitValue(currDeviceString + this.selAdapter[i].id);
832
+ if (deviceName === null || deviceName === undefined) {
833
+ if (deviceObject && typeof deviceObject === 'object') {
834
+ deviceName = deviceObject.common.name;
835
+ }
615
836
  }
616
837
  break;
617
838
  }
@@ -639,6 +860,7 @@ class DeviceWatcher extends utils.Adapter {
639
860
  switch (adapterID) {
640
861
  case 'roomba':
641
862
  case 'sonoff':
863
+ case 'smartgarden':
642
864
  linkQuality = deviceQualityState.val + '%'; // If quality state is already an percent value
643
865
  break;
644
866
  case 'lupusec':
@@ -698,42 +920,49 @@ class DeviceWatcher extends utils.Adapter {
698
920
  let batteryHealth;
699
921
  let isBatteryDevice;
700
922
 
701
- if (deviceBatteryState === undefined) {
702
- if (deviceLowBatState !== undefined) {
703
- switch (deviceLowBatState) {
704
- case 'none':
705
- break;
706
- default:
707
- if (deviceLowBatState !== true || deviceLowBatState === 'NORMAL' || deviceLowBatState === 1) {
923
+ switch (adapterID) {
924
+ case 'hmrpc':
925
+ if (deviceBatteryState === undefined) {
926
+ if (deviceLowBatState !== undefined) {
927
+ if (deviceLowBatState !== 1) {
708
928
  batteryHealth = 'ok';
709
- isBatteryDevice = true;
710
929
  } else {
711
930
  batteryHealth = 'low';
712
- isBatteryDevice = true;
713
931
  }
714
- break;
715
- }
716
- } else {
717
- batteryHealth = ' - ';
718
- }
719
- } else {
720
- switch (adapterID) {
721
- case 'hmrpc':
722
- if (deviceBatteryState === 0 || (deviceBatteryState && deviceBatteryState >= 6)) {
932
+ isBatteryDevice = true;
933
+ } else {
934
+ batteryHealth = ' - ';
935
+ }
936
+ } else {
937
+ if (deviceBatteryState === 0 || deviceBatteryState >= 6) {
723
938
  batteryHealth = ' - ';
724
939
  } else {
725
940
  batteryHealth = deviceBatteryState + 'V';
726
941
  batteryHealthRaw = deviceBatteryState;
727
942
  isBatteryDevice = true;
728
943
  }
729
- break;
730
- default:
944
+ }
945
+ break;
946
+ default:
947
+ if (deviceBatteryState === undefined) {
948
+ if (deviceLowBatState !== undefined) {
949
+ if (deviceLowBatState !== true || deviceLowBatState === 'NORMAL' || deviceLowBatState === 1) {
950
+ batteryHealth = 'ok';
951
+ } else {
952
+ batteryHealth = 'low';
953
+ }
954
+ isBatteryDevice = true;
955
+ } else {
956
+ batteryHealth = ' - ';
957
+ }
958
+ } else {
731
959
  batteryHealth = deviceBatteryState + '%';
732
960
  batteryHealthRaw = deviceBatteryState;
733
961
  isBatteryDevice = true;
734
- break;
735
- }
962
+ }
963
+ break;
736
964
  }
965
+
737
966
  return [batteryHealth, isBatteryDevice, batteryHealthRaw];
738
967
  }
739
968
 
@@ -741,34 +970,43 @@ class DeviceWatcher extends utils.Adapter {
741
970
  * set low bat indicator
742
971
  * @param {object} deviceBatteryState
743
972
  * @param {object} deviceLowBatState
744
- * @param {object} isLowBatDP
973
+ * @param {object} faultReportState
974
+ * @param {object} adapterID
745
975
  */
746
976
 
747
- async setLowbatIndicator(deviceBatteryState, deviceLowBatState, isLowBatDP) {
977
+ async setLowbatIndicator(deviceBatteryState, deviceLowBatState, faultReportState, adapterID) {
748
978
  let lowBatIndicator = false;
749
979
  /*=============================================
750
- = Set Lowbat indicator =
751
- =============================================*/
752
- if (deviceLowBatState !== null && isLowBatDP !== 'none') {
753
- switch (typeof deviceLowBatState) {
754
- case 'number':
755
- if (deviceLowBatState === 0) {
980
+ = Set Lowbat indicator =
981
+ =============================================*/
982
+ if (deviceLowBatState !== undefined || faultReportState !== undefined) {
983
+ switch (adapterID) {
984
+ case 'hmrpc':
985
+ if (deviceLowBatState === 1 || faultReportState === 6) {
756
986
  lowBatIndicator = true;
757
987
  }
758
988
  break;
989
+ default:
990
+ switch (typeof deviceLowBatState) {
991
+ case 'number':
992
+ if (deviceLowBatState === 0) {
993
+ lowBatIndicator = true;
994
+ }
995
+ break;
759
996
 
760
- case 'string':
761
- if (deviceLowBatState !== 'NORMAL') {
762
- // Tado devices
763
- lowBatIndicator = true;
764
- }
765
- break;
997
+ case 'string':
998
+ if (deviceLowBatState !== 'NORMAL') {
999
+ // Tado devices
1000
+ lowBatIndicator = true;
1001
+ }
1002
+ break;
766
1003
 
767
- case 'boolean':
768
- if (deviceLowBatState) {
769
- lowBatIndicator = true;
1004
+ case 'boolean':
1005
+ if (deviceLowBatState) {
1006
+ lowBatIndicator = true;
1007
+ }
1008
+ break;
770
1009
  }
771
- break;
772
1010
  }
773
1011
  } else {
774
1012
  if (deviceBatteryState < this.config.minWarnBatterie) {
@@ -798,7 +1036,7 @@ class DeviceWatcher extends utils.Adapter {
798
1036
 
799
1037
  /**
800
1038
  * get online state and time
801
- * @param {object} id - ID
1039
+ * @param {object} timeSelector - device Timeselector
802
1040
  * @param {string} adapterID - ID of Adapter
803
1041
  * @param {string} unreachDP - Datapoint of Unreach
804
1042
  * @param {object} linkQuality - Linkquality Value
@@ -806,33 +1044,33 @@ class DeviceWatcher extends utils.Adapter {
806
1044
  * @param {string} deviceStateSelectorDP - Selector of device state (like .state)
807
1045
  * @param {string} rssiPeerSelectorDP - HM RSSI Peer Datapoint
808
1046
  */
809
- async getOnlineState(id, adapterID, unreachDP, linkQuality, deviceUnreachState, deviceStateSelectorDP, rssiPeerSelectorDP) {
1047
+ async getOnlineState(timeSelector, adapterID, unreachDP, linkQuality, deviceUnreachState, deviceStateSelectorDP, rssiPeerSelectorDP) {
810
1048
  let lastContactString;
811
1049
  let deviceState = 'Online';
812
1050
 
813
1051
  try {
814
- const deviceMainSelector = await this.getForeignStateAsync(id);
815
- if (deviceMainSelector) {
1052
+ const deviceTimeSelector = await this.getForeignStateAsync(timeSelector);
1053
+ if (deviceTimeSelector) {
816
1054
  const deviceUnreachSelector = await this.getForeignStateAsync(unreachDP);
817
1055
  const deviceStateSelector = await this.getForeignStateAsync(deviceStateSelectorDP); // for hmrpc devices
818
1056
  const rssiPeerSelector = await this.getForeignStateAsync(rssiPeerSelectorDP);
819
- const lastContact = await this.getTimestamp(deviceMainSelector.ts);
820
- const lastDeviceUnreachStateChange = deviceUnreachSelector != undefined ? await this.getTimestamp(deviceUnreachSelector.lc) : await this.getTimestamp(deviceMainSelector.ts);
1057
+ const lastContact = await this.getTimestamp(deviceTimeSelector.ts);
1058
+ const lastDeviceUnreachStateChange = deviceUnreachSelector != undefined ? await this.getTimestamp(deviceUnreachSelector.lc) : await this.getTimestamp(timeSelector.ts);
821
1059
  // If there is no contact since user sets minutes add device in offline list
822
1060
  // calculate to days after 48 hours
823
1061
  switch (unreachDP) {
824
1062
  case 'none':
825
- lastContactString = await this.getLastContact(deviceMainSelector.ts);
1063
+ lastContactString = await this.getLastContact(deviceTimeSelector.ts);
826
1064
  break;
827
1065
 
828
1066
  default:
829
1067
  //State changed
830
1068
  if (adapterID === 'hmrpc') {
831
1069
  if (linkQuality !== ' - ') {
832
- if (deviceUnreachState) {
833
- lastContactString = await this.getLastContact(deviceMainSelector.lc);
1070
+ if (deviceUnreachState === 1) {
1071
+ lastContactString = await this.getLastContact(deviceTimeSelector.lc);
834
1072
  } else {
835
- lastContactString = await this.getLastContact(deviceMainSelector.ts);
1073
+ lastContactString = await this.getLastContact(deviceTimeSelector.ts);
836
1074
  }
837
1075
  } else {
838
1076
  if (deviceStateSelector) {
@@ -844,29 +1082,39 @@ class DeviceWatcher extends utils.Adapter {
844
1082
  }
845
1083
  }
846
1084
  } else {
847
- if (!deviceUnreachState) {
848
- lastContactString = await this.getLastContact(deviceMainSelector.lc);
1085
+ if (deviceUnreachState === 0) {
1086
+ lastContactString = await this.getLastContact(deviceTimeSelector.lc);
849
1087
  } else {
850
- lastContactString = await this.getLastContact(deviceMainSelector.ts);
1088
+ lastContactString = await this.getLastContact(deviceTimeSelector.ts);
851
1089
  }
852
1090
  break;
853
1091
  }
854
1092
  }
855
1093
 
856
1094
  /*=============================================
857
- = Set Online Status =
858
- =============================================*/
859
- if (this.maxMinutes !== undefined) {
1095
+ = Set Online Status =
1096
+ =============================================*/
1097
+ if (this.configMaxMinutes !== undefined) {
860
1098
  switch (adapterID) {
861
1099
  case 'hmrpc':
1100
+ if (this.configMaxMinutes[adapterID] <= 0) {
1101
+ if (deviceUnreachState === 1) {
1102
+ deviceState = 'Offline'; //set online state to offline
1103
+ linkQuality = '0%'; // set linkQuality to nothing
1104
+ }
1105
+ } else if (lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID] && deviceUnreachState === 1) {
1106
+ deviceState = 'Offline'; //set online state to offline
1107
+ linkQuality = '0%'; // set linkQuality to nothing
1108
+ }
1109
+ break;
862
1110
  case 'hmiP':
863
1111
  case 'maxcube':
864
- if (this.maxMinutes[adapterID] <= 0) {
1112
+ if (this.configMaxMinutes[adapterID] <= 0) {
865
1113
  if (deviceUnreachState) {
866
1114
  deviceState = 'Offline'; //set online state to offline
867
1115
  linkQuality = '0%'; // set linkQuality to nothing
868
1116
  }
869
- } else if (lastDeviceUnreachStateChange > this.maxMinutes[adapterID] && deviceUnreachState) {
1117
+ } else if (lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID] && deviceUnreachState) {
870
1118
  deviceState = 'Offline'; //set online state to offline
871
1119
  linkQuality = '0%'; // set linkQuality to nothing
872
1120
  }
@@ -881,57 +1129,68 @@ class DeviceWatcher extends utils.Adapter {
881
1129
  case 'unifi':
882
1130
  case 'zigbee':
883
1131
  case 'zigbee2MQTT':
884
- if (this.maxMinutes[adapterID] <= 0) {
1132
+ if (this.configMaxMinutes[adapterID] <= 0) {
885
1133
  if (!deviceUnreachState) {
886
1134
  deviceState = 'Offline'; //set online state to offline
887
1135
  linkQuality = '0%'; // set linkQuality to nothing
888
1136
  }
889
- } else if (!deviceUnreachState && lastDeviceUnreachStateChange > this.maxMinutes[adapterID]) {
1137
+ } else if (!deviceUnreachState && lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID]) {
890
1138
  deviceState = 'Offline'; //set online state to offline
891
1139
  linkQuality = '0%'; // set linkQuality to nothing
892
1140
  }
893
1141
  break;
894
1142
  case 'mqttClientZigbee2Mqtt':
895
- if (this.maxMinutes[adapterID] <= 0) {
1143
+ if (this.configMaxMinutes[adapterID] <= 0) {
896
1144
  if (deviceUnreachState !== 'online') {
897
1145
  deviceState = 'Offline'; //set online state to offline
898
1146
  linkQuality = '0%'; // set linkQuality to nothing
899
1147
  }
900
- } else if (deviceUnreachState !== 'online' && lastDeviceUnreachStateChange > this.maxMinutes[adapterID]) {
1148
+ } else if (deviceUnreachState !== 'online' && lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID]) {
901
1149
  deviceState = 'Offline'; //set online state to offline
902
1150
  linkQuality = '0%'; // set linkQuality to nothing
903
1151
  }
904
1152
  break;
905
1153
  case 'mihome':
906
1154
  if (deviceUnreachState !== undefined) {
907
- if (this.maxMinutes[adapterID] <= 0) {
1155
+ if (this.configMaxMinutes[adapterID] <= 0) {
908
1156
  if (!deviceUnreachState) {
909
1157
  deviceState = 'Offline'; //set online state to offline
910
1158
  linkQuality = '0%'; // set linkQuality to nothing
911
1159
  }
912
- } else if (lastContact > this.maxMinutes[adapterID]) {
1160
+ } else if (lastContact > this.configMaxMinutes[adapterID]) {
913
1161
  deviceState = 'Offline'; //set online state to offline
914
1162
  linkQuality = '0%'; // set linkQuality to nothing
915
1163
  }
916
1164
  } else {
917
1165
  if (this.config.mihomeMaxMinutes <= 0) {
918
- if (this.maxMinutes[adapterID] <= 0) {
1166
+ if (this.configMaxMinutes[adapterID] <= 0) {
919
1167
  deviceState = 'Offline'; //set online state to offline
920
1168
  linkQuality = '0%'; // set linkQuality to nothing
921
1169
  }
922
- } else if (lastContact > this.maxMinutes[adapterID]) {
1170
+ } else if (lastContact > this.configMaxMinutes[adapterID]) {
923
1171
  deviceState = 'Offline'; //set online state to offline
924
1172
  linkQuality = '0%'; // set linkQuality to nothing
925
1173
  }
926
1174
  }
927
1175
  break;
1176
+ case 'smartgarden':
1177
+ if (this.configMaxMinutes[adapterID] <= 0) {
1178
+ if (deviceUnreachState === 'OFFLINE') {
1179
+ deviceState = 'Offline'; //set online state to offline
1180
+ linkQuality = '0%'; // set linkQuality to nothing
1181
+ }
1182
+ } else if (deviceUnreachState === 'OFFLINE' && lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID]) {
1183
+ deviceState = 'Offline'; //set online state to offline
1184
+ linkQuality = '0%'; // set linkQuality to nothing
1185
+ }
1186
+ break;
928
1187
  default:
929
- if (this.maxMinutes[adapterID] <= 0) {
1188
+ if (this.configMaxMinutes[adapterID] <= 0) {
930
1189
  if (!deviceUnreachState) {
931
1190
  deviceState = 'Offline'; //set online state to offline
932
1191
  linkQuality = '0%'; // set linkQuality to nothing
933
1192
  }
934
- } else if (lastContact > this.maxMinutes[adapterID]) {
1193
+ } else if (lastContact > this.configMaxMinutes[adapterID]) {
935
1194
  deviceState = 'Offline'; //set online state to offline
936
1195
  linkQuality = '0%'; // set linkQuality to nothing
937
1196
  }
@@ -953,7 +1212,7 @@ class DeviceWatcher extends utils.Adapter {
953
1212
  const oldContactState = device.Status;
954
1213
  device.UnreachState = await this.getInitValue(device.UnreachDP);
955
1214
  const contactData = await this.getOnlineState(
956
- device.Path,
1215
+ device.timeSelector,
957
1216
  device.adapterID,
958
1217
  device.UnreachDP,
959
1218
  device.SignalStrength,
@@ -972,218 +1231,6 @@ class DeviceWatcher extends utils.Adapter {
972
1231
  }
973
1232
  }
974
1233
 
975
- /**
976
- * @param {object} i - Device Object
977
- */
978
- async createData(i) {
979
- const devices = await this.getForeignStatesAsync(this.arrDev[i].Selektor);
980
- const adapterID = this.arrDev[i].adapterID;
981
-
982
- /*---------- Start of loop ----------*/
983
- for (const [id] of Object.entries(devices)) {
984
- if (!isUnloaded) {
985
- /*=============================================
986
- = Get device name =
987
- =============================================*/
988
- const deviceName = await this.getDeviceName(id, i);
989
-
990
- /*=============================================
991
- = Get adapter name =
992
- =============================================*/
993
- const adapter = this.arrDev[i].adapter;
994
-
995
- /*=============================================
996
- = Get path to datapoints =
997
- =============================================*/
998
- const currDeviceString = id.slice(0, id.lastIndexOf('.') + 1 - 1);
999
- const shortCurrDeviceString = currDeviceString.slice(0, currDeviceString.lastIndexOf('.') + 1 - 1);
1000
-
1001
- /*=============================================
1002
- = Get signal strength =
1003
- =============================================*/
1004
- let deviceQualityDP = currDeviceString + this.arrDev[i].rssiState;
1005
- let deviceQualityState;
1006
-
1007
- switch (adapterID) {
1008
- case 'mihomeVacuum':
1009
- deviceQualityDP = shortCurrDeviceString + this.arrDev[i].rssiState;
1010
- deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
1011
- break;
1012
-
1013
- case 'netatmo':
1014
- deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
1015
- if (!deviceQualityState) {
1016
- deviceQualityDP = currDeviceString + this.arrDev[i].rfState;
1017
- deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
1018
- }
1019
- break;
1020
-
1021
- default:
1022
- deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
1023
- break;
1024
- }
1025
- //subscribe to states
1026
- this.subscribeForeignStatesAsync(deviceQualityDP);
1027
-
1028
- let linkQuality = await this.calculateSignalStrength(deviceQualityState, adapterID);
1029
-
1030
- /*=============================================
1031
- = Get battery data =
1032
- =============================================*/
1033
- let deviceBatteryStateDP;
1034
- let deviceBatteryState;
1035
- // Get battery states
1036
- switch (adapterID) {
1037
- case 'hueExt':
1038
- case 'mihomeVacuum':
1039
- case 'mqttNuki':
1040
- deviceBatteryStateDP = shortCurrDeviceString + this.arrDev[i].battery;
1041
- deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
1042
- if (deviceBatteryState === undefined) {
1043
- deviceBatteryStateDP = shortCurrDeviceString + this.arrDev[i].battery2;
1044
- deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
1045
- }
1046
- break;
1047
- default:
1048
- deviceBatteryStateDP = currDeviceString + this.arrDev[i].battery;
1049
- deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
1050
- if (deviceBatteryState === undefined) {
1051
- deviceBatteryStateDP = currDeviceString + this.arrDev[i].battery2;
1052
- deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
1053
- }
1054
- break;
1055
- }
1056
-
1057
- // Get low bat states
1058
- let isLowBatDP = currDeviceString + this.arrDev[i].isLowBat;
1059
- let deviceLowBatState = await this.getInitValue(isLowBatDP);
1060
- if (deviceLowBatState === undefined) {
1061
- isLowBatDP = currDeviceString + this.arrDev[i].isLowBat2;
1062
- deviceLowBatState = await this.getInitValue(isLowBatDP);
1063
- }
1064
- if (deviceLowBatState === undefined) isLowBatDP = 'none';
1065
-
1066
- //subscribe to states
1067
- this.subscribeForeignStatesAsync(deviceBatteryStateDP);
1068
- this.subscribeForeignStatesAsync(isLowBatDP);
1069
-
1070
- const batteryData = await this.getBatteryData(deviceBatteryState, deviceLowBatState, adapterID);
1071
- const batteryHealth = batteryData[0];
1072
- const batteryHealthRaw = batteryData[2];
1073
- const isBatteryDevice = batteryData[1];
1074
- let lowBatIndicator;
1075
-
1076
- if (isBatteryDevice) {
1077
- lowBatIndicator = await this.setLowbatIndicator(deviceBatteryState, deviceLowBatState, isLowBatDP);
1078
- }
1079
-
1080
- /*=============================================
1081
- = Get last contact of device =
1082
- =============================================*/
1083
- let unreachDP = currDeviceString + this.arrDev[i].reach;
1084
- const deviceStateSelectorDP = shortCurrDeviceString + this.arrDev[i].stateValue;
1085
- const rssiPeerSelectorDP = currDeviceString + this.arrDev[i].rssiPeerState;
1086
-
1087
- let deviceUnreachState = await this.getInitValue(unreachDP);
1088
- if (deviceUnreachState === undefined) {
1089
- unreachDP = shortCurrDeviceString + this.arrDev[i].reach;
1090
- deviceUnreachState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].reach);
1091
- }
1092
-
1093
- // subscribe to states
1094
- this.subscribeForeignStatesAsync(id);
1095
- this.subscribeForeignStatesAsync(unreachDP);
1096
- this.subscribeForeignStatesAsync(deviceStateSelectorDP);
1097
- this.subscribeForeignStatesAsync(rssiPeerSelectorDP);
1098
-
1099
- const onlineState = await this.getOnlineState(id, adapterID, unreachDP, linkQuality, deviceUnreachState, deviceStateSelectorDP, rssiPeerSelectorDP);
1100
- let deviceState;
1101
- let lastContactString;
1102
-
1103
- if (onlineState) {
1104
- lastContactString = onlineState[0];
1105
- deviceState = onlineState[1];
1106
- linkQuality = onlineState[2];
1107
- }
1108
-
1109
- /*=============================================
1110
- = Get update data =
1111
- =============================================*/
1112
- const deviceUpdateDP = currDeviceString + this.arrDev[i].upgrade;
1113
- let isUpgradable;
1114
-
1115
- if (this.config.checkSendDeviceUpgrade) {
1116
- const deviceUpdateSelector = await this.getInitValue(deviceUpdateDP);
1117
-
1118
- if (deviceUpdateSelector) {
1119
- isUpgradable = true;
1120
- } else if (!deviceUpdateSelector) {
1121
- isUpgradable = false;
1122
- }
1123
- // subscribe to states
1124
- this.subscribeForeignStatesAsync(deviceUpdateDP);
1125
- }
1126
-
1127
- /*=============================================
1128
- = Fill Raw Lists =
1129
- =============================================*/
1130
-
1131
- /* Add only devices with battery in the rawlist */
1132
- if (this.listOnlyBattery && isBatteryDevice) {
1133
- this.listAllDevicesRaw.push({
1134
- Path: id,
1135
- Device: deviceName,
1136
- adapterID: adapterID,
1137
- Adapter: adapter,
1138
- isBatteryDevice: isBatteryDevice,
1139
- Battery: batteryHealth,
1140
- BatteryRaw: batteryHealthRaw,
1141
- batteryDP: deviceBatteryStateDP,
1142
- LowBat: lowBatIndicator,
1143
- LowBatDP: isLowBatDP,
1144
- SignalStrengthDP: deviceQualityDP,
1145
- SignalStrength: linkQuality,
1146
- UnreachState: deviceUnreachState,
1147
- UnreachDP: unreachDP,
1148
- DeviceStateSelectorDP: deviceStateSelectorDP,
1149
- rssiPeerSelectorDP: rssiPeerSelectorDP,
1150
- LastContact: lastContactString,
1151
- Status: deviceState,
1152
- UpdateDP: deviceUpdateDP,
1153
- Upgradable: isUpgradable,
1154
- });
1155
- } else {
1156
- /* Add all devices */
1157
- this.listAllDevicesRaw.push({
1158
- Path: id,
1159
- Device: deviceName,
1160
- adapterID: adapterID,
1161
- Adapter: adapter,
1162
- isBatteryDevice: isBatteryDevice,
1163
- Battery: batteryHealth,
1164
- BatteryRaw: batteryHealthRaw,
1165
- batteryDP: deviceBatteryStateDP,
1166
- LowBat: lowBatIndicator,
1167
- LowBatDP: isLowBatDP,
1168
- SignalStrengthDP: deviceQualityDP,
1169
- SignalStrength: linkQuality,
1170
- UnreachState: deviceUnreachState,
1171
- UnreachDP: unreachDP,
1172
- DeviceStateSelectorDP: deviceStateSelectorDP,
1173
- rssiPeerSelectorDP: rssiPeerSelectorDP,
1174
- LastContact: lastContactString,
1175
- Status: deviceState,
1176
- UpdateDP: deviceUpdateDP,
1177
- Upgradable: isUpgradable,
1178
- });
1179
- }
1180
- } else {
1181
- /* cancel run if unloaded was called. */
1182
- return;
1183
- }
1184
- } // <-- end of loop
1185
- } // <-- end of createData
1186
-
1187
1234
  /**
1188
1235
  * Create Lists
1189
1236
  */
@@ -1195,6 +1242,7 @@ class DeviceWatcher extends utils.Adapter {
1195
1242
  this.offlineDevices = [];
1196
1243
  this.batteryLowPoweredRaw = [];
1197
1244
  this.offlineDevicesRaw = [];
1245
+ this.upgradableDevicesRaw = [];
1198
1246
  this.upgradableList = [];
1199
1247
 
1200
1248
  if (adptName === undefined) {
@@ -1222,6 +1270,15 @@ class DeviceWatcher extends utils.Adapter {
1222
1270
  });
1223
1271
  }
1224
1272
 
1273
+ // upgradable raw list
1274
+ if (device.Upgradable) {
1275
+ this.upgradableDevicesRaw.push({
1276
+ Path: device.Path,
1277
+ Device: device.Device,
1278
+ Adapter: device.Adapter,
1279
+ });
1280
+ }
1281
+
1225
1282
  if (adptName === '' && !this.blacklistLists.includes(device.Path)) {
1226
1283
  await this.theLists(device);
1227
1284
  }
@@ -1263,7 +1320,7 @@ class DeviceWatcher extends utils.Adapter {
1263
1320
  }
1264
1321
 
1265
1322
  // Battery lists
1266
- if (device['isBatteryDevice']) {
1323
+ if (device.isBatteryDevice) {
1267
1324
  this.batteryPowered.push({
1268
1325
  Device: device.Device,
1269
1326
  Adapter: device.Adapter,
@@ -1336,32 +1393,188 @@ class DeviceWatcher extends utils.Adapter {
1336
1393
  await this.createLists(adptName);
1337
1394
  }
1338
1395
  }
1339
- await this.writeDatapoints(adptName); // fill the datapoints
1340
- } catch (error) {
1341
- this.errorReporting('[createDataForEachAdapter]', error);
1342
- }
1343
-
1344
- this.log.debug(`Function finished: ${this.createDataForEachAdapter.name}`);
1345
- } // <-- end of createDataForEachAdapter
1396
+ await this.writeDatapoints(adptName); // fill the datapoints
1397
+ } catch (error) {
1398
+ this.errorReporting('[createDataForEachAdapter]', error);
1399
+ }
1400
+
1401
+ this.log.debug(`Function finished: ${this.createDataForEachAdapter.name}`);
1402
+ } // <-- end of createDataForEachAdapter
1403
+
1404
+ /**
1405
+ * create Data of all selected adapter in one list
1406
+ */
1407
+ async createDataOfAllAdapter() {
1408
+ this.log.debug(`Function started: ${this.createDataOfAllAdapter.name}`);
1409
+
1410
+ try {
1411
+ for (let i = 0; i < this.selAdapter.length; i++) {
1412
+ await this.createData(i);
1413
+ await this.createLists();
1414
+ }
1415
+ await this.writeDatapoints(); // fill the datapoints
1416
+ } catch (error) {
1417
+ this.errorReporting('[createDataOfAllAdapter]', error);
1418
+ }
1419
+
1420
+ this.log.debug(`Function finished: ${this.createDataOfAllAdapter.name}`);
1421
+ } // <-- end of createDataOfAllAdapter
1422
+
1423
+ /**
1424
+ * @param {string} [adptName] - Adaptername
1425
+ */
1426
+ async writeDatapoints(adptName) {
1427
+ // fill the datapoints
1428
+
1429
+ this.log.debug(`Start the function: ${this.writeDatapoints.name}`);
1430
+
1431
+ try {
1432
+ let dpSubFolder;
1433
+ //write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
1434
+ if (adptName) {
1435
+ dpSubFolder = adptName + '.';
1436
+ } else {
1437
+ dpSubFolder = '';
1438
+ }
1439
+
1440
+ // Write Datapoints for counts
1441
+ await this.setStateAsync(`${dpSubFolder}offlineCount`, { val: this.offlineDevicesCount, ack: true });
1442
+ await this.setStateAsync(`${dpSubFolder}countAll`, { val: this.deviceCounter, ack: true });
1443
+ await this.setStateAsync(`${dpSubFolder}batteryCount`, { val: this.batteryPoweredCount, ack: true });
1444
+ await this.setStateAsync(`${dpSubFolder}lowBatteryCount`, { val: this.lowBatteryPoweredCount, ack: true });
1445
+ await this.setStateAsync(`${dpSubFolder}upgradableCount`, { val: this.upgradableDevicesCount, ack: true });
1446
+
1447
+ // List all devices
1448
+ if (this.deviceCounter === 0) {
1449
+ // if no device is count, write the JSON List with default value
1450
+ this.listAllDevices = [{ Device: '--none--', Adapter: '', Battery: '', 'Last contact': '', 'Signal strength': '' }];
1451
+ }
1452
+ await this.setStateAsync(`${dpSubFolder}listAll`, { val: JSON.stringify(this.listAllDevices), ack: true });
1453
+
1454
+ // List link quality
1455
+ if (this.linkQualityCount === 0) {
1456
+ // if no device is count, write the JSON List with default value
1457
+ this.linkQualityDevices = [{ Device: '--none--', Adapter: '', 'Signal strength': '' }];
1458
+ }
1459
+ //write JSON list
1460
+ await this.setStateAsync(`${dpSubFolder}linkQualityList`, {
1461
+ val: JSON.stringify(this.linkQualityDevices),
1462
+ ack: true,
1463
+ });
1464
+
1465
+ // List offline devices
1466
+ if (this.offlineDevicesCount === 0) {
1467
+ // if no device is count, write the JSON List with default value
1468
+ this.offlineDevices = [{ Device: '--none--', Adapter: '', 'Last contact': '' }];
1469
+ }
1470
+ //write JSON list
1471
+ await this.setStateAsync(`${dpSubFolder}offlineList`, {
1472
+ val: JSON.stringify(this.offlineDevices),
1473
+ ack: true,
1474
+ });
1475
+
1476
+ // List updatable
1477
+ if (this.upgradableDevicesCount === 0) {
1478
+ // if no device is count, write the JSON List with default value
1479
+ this.upgradableList = [{ Device: '--none--', Adapter: '', 'Last contact': '' }];
1480
+ }
1481
+ //write JSON list
1482
+ await this.setStateAsync(`${dpSubFolder}upgradableList`, {
1483
+ val: JSON.stringify(this.upgradableList),
1484
+ ack: true,
1485
+ });
1486
+
1487
+ // List battery powered
1488
+ if (this.batteryPoweredCount === 0) {
1489
+ // if no device is count, write the JSON List with default value
1490
+ this.batteryPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
1491
+ }
1492
+ //write JSON list
1493
+ await this.setStateAsync(`${dpSubFolder}batteryList`, {
1494
+ val: JSON.stringify(this.batteryPowered),
1495
+ ack: true,
1496
+ });
1497
+
1498
+ // list battery low powered
1499
+ if (this.lowBatteryPoweredCount === 0) {
1500
+ // if no device is count, write the JSON List with default value
1501
+ this.batteryLowPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
1502
+ }
1503
+ //write JSON list
1504
+ await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {
1505
+ val: JSON.stringify(this.batteryLowPowered),
1506
+ ack: true,
1507
+ });
1508
+
1509
+ // set booleans datapoints
1510
+ if (this.offlineDevicesCount === 0) {
1511
+ await this.setStateAsync(`${dpSubFolder}oneDeviceOffline`, {
1512
+ val: false,
1513
+ ack: true,
1514
+ });
1515
+ } else {
1516
+ await this.setStateAsync(`${dpSubFolder}oneDeviceOffline`, {
1517
+ val: true,
1518
+ ack: true,
1519
+ });
1520
+ }
1521
+
1522
+ if (this.lowBatteryPoweredCount === 0) {
1523
+ await this.setStateAsync(`${dpSubFolder}oneDeviceLowBat`, {
1524
+ val: false,
1525
+ ack: true,
1526
+ });
1527
+ } else {
1528
+ await this.setStateAsync(`${dpSubFolder}oneDeviceLowBat`, {
1529
+ val: true,
1530
+ ack: true,
1531
+ });
1532
+ }
1346
1533
 
1347
- /**
1348
- * create Data of all selected adapter in one list
1349
- */
1350
- async createDataOfAllAdapter() {
1351
- this.log.debug(`Function started: ${this.createDataOfAllAdapter.name}`);
1534
+ if (this.upgradableDevicesCount === 0) {
1535
+ await this.setStateAsync(`${dpSubFolder}oneDeviceUpdatable`, {
1536
+ val: false,
1537
+ ack: true,
1538
+ });
1539
+ } else {
1540
+ await this.setStateAsync(`${dpSubFolder}oneDeviceUpdatable`, {
1541
+ val: true,
1542
+ ack: true,
1543
+ });
1544
+ }
1352
1545
 
1353
- try {
1354
- for (let i = 0; i < this.arrDev.length; i++) {
1355
- await this.createData(i);
1356
- await this.createLists();
1546
+ //write HTML list
1547
+ if (this.createHtmlList) {
1548
+ await this.setStateAsync(`${dpSubFolder}linkQualityListHTML`, {
1549
+ val: await this.creatLinkQualityListHTML(this.linkQualityDevices, this.linkQualityCount),
1550
+ ack: true,
1551
+ });
1552
+ await this.setStateAsync(`${dpSubFolder}offlineListHTML`, {
1553
+ val: await this.createOfflineListHTML(this.offlineDevices, this.offlineDevicesCount),
1554
+ ack: true,
1555
+ });
1556
+ await this.setStateAsync(`${dpSubFolder}batteryListHTML`, {
1557
+ val: await this.createBatteryListHTML(this.batteryPowered, this.batteryPoweredCount, false),
1558
+ ack: true,
1559
+ });
1560
+ await this.setStateAsync(`${dpSubFolder}lowBatteryListHTML`, {
1561
+ val: await this.createBatteryListHTML(this.batteryLowPowered, this.lowBatteryPoweredCount, true),
1562
+ ack: true,
1563
+ });
1357
1564
  }
1358
- await this.writeDatapoints(); // fill the datapoints
1565
+
1566
+ // create timestamp of last run
1567
+ const lastCheck = this.formatDate(new Date(), 'DD.MM.YYYY') + ' - ' + this.formatDate(new Date(), 'hh:mm:ss');
1568
+ await this.setStateAsync('lastCheck', lastCheck, true);
1359
1569
  } catch (error) {
1360
- this.errorReporting('[createDataOfAllAdapter]', error);
1570
+ this.errorReporting('[writeDatapoints]', error);
1361
1571
  }
1572
+ this.log.debug(`Function finished: ${this.writeDatapoints.name}`);
1573
+ } //<--End of writing Datapoints
1362
1574
 
1363
- this.log.debug(`Function finished: ${this.createDataOfAllAdapter.name}`);
1364
- } // <-- end of createDataOfAllAdapter
1575
+ /*=============================================
1576
+ = functions to send notifications =
1577
+ =============================================*/
1365
1578
 
1366
1579
  /**
1367
1580
  * Notification service
@@ -1743,7 +1956,7 @@ class DeviceWatcher extends utils.Adapter {
1743
1956
  try {
1744
1957
  let deviceList = '';
1745
1958
 
1746
- for (const id of this.upgradableList) {
1959
+ for (const id of this.upgradableDevicesRaw) {
1747
1960
  if (!this.blacklistNotify.includes(id.Path)) {
1748
1961
  if (!this.config.showAdapterNameinMsg) {
1749
1962
  deviceList = `${deviceList}\n${id.Device}`;
@@ -1752,7 +1965,6 @@ class DeviceWatcher extends utils.Adapter {
1752
1965
  }
1753
1966
  }
1754
1967
  }
1755
-
1756
1968
  if (deviceList.length > 0) {
1757
1969
  this.log.info(`Geräte Upgrade: ${deviceList}`);
1758
1970
  this.setStateAsync('lastNotification', `Geräte Upgrade: ${deviceList}`, true);
@@ -1766,157 +1978,9 @@ class DeviceWatcher extends utils.Adapter {
1766
1978
  }
1767
1979
  } //<--End of daily offline notification
1768
1980
 
1769
- /**
1770
- * @param {string} [adptName] - Adaptername
1771
- */
1772
- async writeDatapoints(adptName) {
1773
- // fill the datapoints
1774
-
1775
- this.log.debug(`Start the function: ${this.writeDatapoints.name}`);
1776
-
1777
- try {
1778
- let dpSubFolder;
1779
- //write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
1780
- if (adptName) {
1781
- dpSubFolder = adptName + '.';
1782
- } else {
1783
- dpSubFolder = '';
1784
- }
1785
-
1786
- // Write Datapoints for counts
1787
- await this.setStateAsync(`${dpSubFolder}offlineCount`, { val: this.offlineDevicesCount, ack: true });
1788
- await this.setStateAsync(`${dpSubFolder}countAll`, { val: this.deviceCounter, ack: true });
1789
- await this.setStateAsync(`${dpSubFolder}batteryCount`, { val: this.batteryPoweredCount, ack: true });
1790
- await this.setStateAsync(`${dpSubFolder}lowBatteryCount`, { val: this.lowBatteryPoweredCount, ack: true });
1791
- await this.setStateAsync(`${dpSubFolder}upgradableCount`, { val: this.upgradableDevicesCount, ack: true });
1792
-
1793
- // List all devices
1794
- if (this.deviceCounter === 0) {
1795
- // if no device is count, write the JSON List with default value
1796
- this.listAllDevices = [{ Device: '--none--', Adapter: '', Battery: '', 'Last contact': '', 'Signal strength': '' }];
1797
- }
1798
- await this.setStateAsync(`${dpSubFolder}listAll`, { val: JSON.stringify(this.listAllDevices), ack: true });
1799
-
1800
- // List link quality
1801
- if (this.linkQualityCount === 0) {
1802
- // if no device is count, write the JSON List with default value
1803
- this.linkQualityDevices = [{ Device: '--none--', Adapter: '', 'Signal strength': '' }];
1804
- }
1805
- //write JSON list
1806
- await this.setStateAsync(`${dpSubFolder}linkQualityList`, {
1807
- val: JSON.stringify(this.linkQualityDevices),
1808
- ack: true,
1809
- });
1810
-
1811
- // List offline devices
1812
- if (this.offlineDevicesCount === 0) {
1813
- // if no device is count, write the JSON List with default value
1814
- this.offlineDevices = [{ Device: '--none--', Adapter: '', 'Last contact': '' }];
1815
- }
1816
- //write JSON list
1817
- await this.setStateAsync(`${dpSubFolder}offlineList`, {
1818
- val: JSON.stringify(this.offlineDevices),
1819
- ack: true,
1820
- });
1821
-
1822
- // List updatable
1823
- if (this.upgradableDevicesCount === 0) {
1824
- // if no device is count, write the JSON List with default value
1825
- this.upgradableList = [{ Device: '--none--', Adapter: '', 'Last contact': '' }];
1826
- }
1827
- //write JSON list
1828
- await this.setStateAsync(`${dpSubFolder}upgradableList`, {
1829
- val: JSON.stringify(this.upgradableList),
1830
- ack: true,
1831
- });
1832
-
1833
- // List battery powered
1834
- if (this.batteryPoweredCount === 0) {
1835
- // if no device is count, write the JSON List with default value
1836
- this.batteryPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
1837
- }
1838
- //write JSON list
1839
- await this.setStateAsync(`${dpSubFolder}batteryList`, {
1840
- val: JSON.stringify(this.batteryPowered),
1841
- ack: true,
1842
- });
1843
-
1844
- // list battery low powered
1845
- if (this.lowBatteryPoweredCount === 0) {
1846
- // if no device is count, write the JSON List with default value
1847
- this.batteryLowPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
1848
- }
1849
- //write JSON list
1850
- await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {
1851
- val: JSON.stringify(this.batteryLowPowered),
1852
- ack: true,
1853
- });
1854
-
1855
- // set booleans datapoints
1856
- if (this.offlineDevicesCount === 0) {
1857
- await this.setStateAsync(`${dpSubFolder}oneDeviceOffline`, {
1858
- val: false,
1859
- ack: true,
1860
- });
1861
- } else {
1862
- await this.setStateAsync(`${dpSubFolder}oneDeviceOffline`, {
1863
- val: true,
1864
- ack: true,
1865
- });
1866
- }
1867
-
1868
- if (this.lowBatteryPoweredCount === 0) {
1869
- await this.setStateAsync(`${dpSubFolder}oneDeviceLowBat`, {
1870
- val: false,
1871
- ack: true,
1872
- });
1873
- } else {
1874
- await this.setStateAsync(`${dpSubFolder}oneDeviceLowBat`, {
1875
- val: true,
1876
- ack: true,
1877
- });
1878
- }
1879
-
1880
- if (this.upgradableDevicesCount === 0) {
1881
- await this.setStateAsync(`${dpSubFolder}oneDeviceUpdatable`, {
1882
- val: false,
1883
- ack: true,
1884
- });
1885
- } else {
1886
- await this.setStateAsync(`${dpSubFolder}oneDeviceUpdatable`, {
1887
- val: true,
1888
- ack: true,
1889
- });
1890
- }
1891
-
1892
- //write HTML list
1893
- if (this.createHtmlList) {
1894
- await this.setStateAsync(`${dpSubFolder}linkQualityListHTML`, {
1895
- val: await this.creatLinkQualityListHTML(this.linkQualityDevices, this.linkQualityCount),
1896
- ack: true,
1897
- });
1898
- await this.setStateAsync(`${dpSubFolder}offlineListHTML`, {
1899
- val: await this.createOfflineListHTML(this.offlineDevices, this.offlineDevicesCount),
1900
- ack: true,
1901
- });
1902
- await this.setStateAsync(`${dpSubFolder}batteryListHTML`, {
1903
- val: await this.createBatteryListHTML(this.batteryPowered, this.batteryPoweredCount, false),
1904
- ack: true,
1905
- });
1906
- await this.setStateAsync(`${dpSubFolder}lowBatteryListHTML`, {
1907
- val: await this.createBatteryListHTML(this.batteryLowPowered, this.lowBatteryPoweredCount, true),
1908
- ack: true,
1909
- });
1910
- }
1911
-
1912
- // create timestamp of last run
1913
- const lastCheck = this.formatDate(new Date(), 'DD.MM.YYYY') + ' - ' + this.formatDate(new Date(), 'hh:mm:ss');
1914
- await this.setStateAsync('lastCheck', lastCheck, true);
1915
- } catch (error) {
1916
- this.errorReporting('[writeDatapoints]', error);
1917
- }
1918
- this.log.debug(`Function finished: ${this.writeDatapoints.name}`);
1919
- } //<--End of writing Datapoints
1981
+ /*=============================================
1982
+ = functions to create html lists =
1983
+ =============================================*/
1920
1984
 
1921
1985
  /**
1922
1986
  * @param {object} devices - Device
@@ -2031,7 +2095,10 @@ class DeviceWatcher extends utils.Adapter {
2031
2095
  return html;
2032
2096
  }
2033
2097
 
2034
- // create datapoints for each adapter
2098
+ /*=============================================
2099
+ = create datapoints for each adapter =
2100
+ =============================================*/
2101
+
2035
2102
  /**
2036
2103
  * @param {object} adptName - Adaptername of devices
2037
2104
  */
@@ -2480,6 +2547,54 @@ class DeviceWatcher extends utils.Adapter {
2480
2547
  });
2481
2548
  }
2482
2549
 
2550
+ /*=============================================
2551
+ = help functions =
2552
+ =============================================*/
2553
+
2554
+ /**
2555
+ * @param {string} id - id which should be capitalize
2556
+ */
2557
+ capitalize(id) {
2558
+ //make the first letter uppercase
2559
+ return id && id[0].toUpperCase() + id.slice(1);
2560
+ }
2561
+
2562
+ /**
2563
+ * @param {number} dpValue - get Time of this datapoint
2564
+ */
2565
+ async getTimestamp(dpValue) {
2566
+ const time = new Date();
2567
+ return (dpValue = Math.round((time.getTime() - dpValue) / 1000 / 60));
2568
+ }
2569
+
2570
+ /**
2571
+ * @param {object} obj - State of datapoint
2572
+ */
2573
+ async getInitValue(obj) {
2574
+ //state can be null or undefinded
2575
+ const foreignState = await this.getForeignStateAsync(obj);
2576
+ if (foreignState) return foreignState.val;
2577
+ }
2578
+
2579
+ /**
2580
+ * @param {object} obj - State of own datapoint
2581
+ */
2582
+ async getOwnInitValue(obj) {
2583
+ //state can be null or undefinded for own states
2584
+ const stateVal = await this.getStateAsync(obj);
2585
+ if (stateVal) return stateVal.val;
2586
+ }
2587
+
2588
+ /**
2589
+ * @param {object} data - object
2590
+ */
2591
+ async parseData(data) {
2592
+ if (!data) return {};
2593
+ if (typeof data === 'object') return data;
2594
+ if (typeof data === 'string') return JSON.parse(data);
2595
+ return {};
2596
+ }
2597
+
2483
2598
  /**
2484
2599
  * @param {string} codePart - Message Prefix
2485
2600
  * @param {object} error - Sentry message