iobroker.device-watcher 0.2.2 → 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/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,7 +42,7 @@ 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 = {
@@ -70,7 +73,7 @@ class DeviceWatcher extends utils.Adapter {
70
73
  'adapter':'zigbee',
71
74
  'battery':'.battery',
72
75
  'reach':'.available',
73
- 'isLowBat':'none'
76
+ 'isLowBat':'.battery_low'
74
77
  },
75
78
  sonoff: {
76
79
  'Selektor':'sonoff.*.Uptime',
@@ -182,80 +185,121 @@ class DeviceWatcher extends utils.Adapter {
182
185
 
183
186
  try {
184
187
  await this.main();
185
- if (this.config.checkSendOfflineMsg) await this.sendOfflineNotifications();
186
- if (this.config.checkSendBatteryMsg) await this.sendBatteryNotifications();
187
188
  await this.writeDatapoints();
188
189
  this.log.debug('all done, exiting');
189
190
  this.terminate ? this.terminate('Everything done. Going to terminate till next schedule', 11) : process.exit(0);
190
- } catch (e) {
191
- this.log.error(`Error while running Device-Watcher. Error Message: ${e}`);
191
+ } catch (error) {
192
+ this.errorReporting('[onReady]', error);
192
193
  this.terminate ? this.terminate(15) : process.exit(15);
193
194
  }
194
195
  }
195
196
 
196
- //Helpfunctions
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
+ **/
197
275
  async capitalize(sentence)
198
276
  {
199
277
  //make the first letter uppercase
200
278
  return sentence && sentence[0].toUpperCase() + sentence.slice(1);
201
279
  }
202
280
 
281
+ /**
282
+ * @param {object} [obj] - State of datapoint
283
+ **/
203
284
  async getInitValue(obj) {
204
285
  //state can be null or undefinded
205
286
  const foreignState = await this.getForeignStateAsync(obj);
206
287
  if (foreignState) return foreignState.val;
207
288
  }
208
289
 
290
+ /**
291
+ * @param {object} [obj] - State of own datapoint
292
+ **/
209
293
  async getOwnInitValue(obj) {
210
294
  //state can be null or undefinded for own states
211
295
  const stateVal = await this.getStateAsync(obj);
212
296
  if (stateVal) return stateVal.val;
213
297
  }
214
298
 
215
- //Notification services
216
- async sendPushover(text) {
217
- await this.sendToAsync(this.config.instancePushover, 'send', {
218
- message: text,
219
- title: this.config.titlePushover,
220
- device: this.config.devicePushover,
221
- priority: this.config.prioPushover
222
- });
223
- }
224
-
225
- async sendTelegram(text) {
226
- await this.sendToAsync(this.config.instanceTelegram, 'send', {
227
- text: text,
228
- user: this.config.deviceTelegram,
229
- chatId: this.config.chatIdTelegram
230
- });
231
- }
232
-
233
- async sendWhatsapp(text) {
234
- await this.sendToAsync(this.config.instanceWhatsapp, 'send', {
235
- text: text,
236
- phone: this.config.phoneWhatsapp
237
- });
238
- }
239
-
240
- async sendEmail(text) {
241
- await this.sendToAsync(this.config.instanceEmail, 'send', {
242
- sendTo: this.config.sendToEmail,
243
- text: text,
244
- subject: this.config.subjectEmail
245
- });
246
- }
247
-
248
- async sendJarvis(text) {
249
- await this.setForeignStateAsync(`${this.config.instanceJarvis}.addNotification`, text);
250
-
251
- }
252
-
253
- async sendLovelace(text) {
254
- await this.setForeignStateAsync(`${this.config.instanceLovelace}.notifications.add`, text);
255
-
256
- }
257
-
258
299
  //create datapoints for each adapter
300
+ /**
301
+ * @param {object} [adptName] - Adaptername of devices
302
+ **/
259
303
  async createDPsForEachAdapter(adptName) {
260
304
 
261
305
  await this.setObjectNotExistsAsync(`${adptName}`, {
@@ -466,6 +510,9 @@ class DeviceWatcher extends utils.Adapter {
466
510
  });
467
511
  }
468
512
 
513
+ /**
514
+ * @param {object} [i] - Device Object
515
+ **/
469
516
  async createData(i) {
470
517
  const devices = await this.getForeignStatesAsync(this.arrDev[i].Selektor);
471
518
  const deviceAdapterName = await this.capitalize(this.arrDev[i].adapter);
@@ -482,7 +529,7 @@ class DeviceWatcher extends utils.Adapter {
482
529
  if (!this.blacklistArr.includes(id)) {
483
530
 
484
531
  const currDeviceString = id.slice(0, (id.lastIndexOf('.') + 1) - 1);
485
- const shortCurrDeviceString = currDeviceString.slice(0, (currDeviceString.lastIndexOf('.') + 1) - 1);
532
+ const shortCurrDeviceString = currDeviceString.slice(0, (currDeviceString.lastIndexOf('.') + 1) - 1);
486
533
 
487
534
  //Get device name
488
535
  const deviceObject = await this.getForeignObjectAsync(currDeviceString);
@@ -508,6 +555,11 @@ class DeviceWatcher extends utils.Adapter {
508
555
  break;
509
556
  }
510
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
+
511
563
  // 1. Get link quality
512
564
  let deviceQualityState;
513
565
  let linkQuality;
@@ -531,13 +583,25 @@ class DeviceWatcher extends utils.Adapter {
531
583
  linkQuality = parseFloat((100/255 * deviceQualityState.val).toFixed(0)) + '%';
532
584
  }
533
585
  }
534
- this.linkQualityDevices.push(
535
- {
536
- 'Device': deviceName,
537
- 'Adapter': deviceAdapterName,
538
- 'Signal strength': linkQuality
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
+ );
539
595
  }
540
- );
596
+ } else {
597
+ this.linkQualityDevices.push(
598
+ {
599
+ 'Device': deviceName,
600
+ 'Adapter': deviceAdapterName,
601
+ 'Signal strength': linkQuality
602
+ }
603
+ );
604
+ }
541
605
  } else {
542
606
  // no linkQuality available for powered devices
543
607
  linkQuality = ' - ';
@@ -549,7 +613,6 @@ class DeviceWatcher extends utils.Adapter {
549
613
  // 2. When was the last contact to the device?
550
614
  let lastContactString;
551
615
 
552
- const deviceMainSelector = await this.getForeignStateAsync(id);
553
616
  let deviceState = 'Online';
554
617
  if (deviceMainSelector) {
555
618
  try {
@@ -583,7 +646,6 @@ class DeviceWatcher extends utils.Adapter {
583
646
 
584
647
  // 2b. wenn seit X Minuten kein Kontakt mehr besteht, nimm Gerät in Liste auf
585
648
  //Rechne auf Tage um, wenn mehr als 48 Stunden seit letztem Kontakt vergangen sind
586
- //lastContactString = Math.round(lastContact) + ' Minuten';
587
649
  switch (this.arrDev[i].adapter) {
588
650
  case 'ping':
589
651
  //State changed
@@ -599,401 +661,219 @@ class DeviceWatcher extends utils.Adapter {
599
661
  break;
600
662
  }
601
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
+
602
686
  switch (this.arrDev[i].adapter) {
603
687
  case 'alexa2':
604
688
  if (this.config.alexa2MaxMinutes === -1) {
605
689
  if (!deviceUnreachState) {
606
690
  deviceState = 'Offline'; //set online state to offline
607
- this.offlineDevices.push(
608
- {
609
- 'Device': deviceName,
610
- 'Adapter': deviceAdapterName,
611
- 'Last contact': lastContactString
612
- }
613
- );
691
+ await pushOfflineDevice();
614
692
  }
615
693
  } else if (lastContact > this.config.alexa2MaxMinutes) {
616
694
  deviceState = 'Offline'; //set online state to offline
617
- this.offlineDevices.push(
618
- {
619
- 'Device': deviceName,
620
- 'Adapter': deviceAdapterName,
621
- 'Last contact': lastContactString
622
- }
623
- );
695
+ await pushOfflineDevice();
624
696
  }
625
697
  break;
626
698
  case 'ble':
627
699
  if (this.config.bleMaxMinutes === -1) {
628
700
  if (!deviceUnreachState) {
629
701
  deviceState = 'Offline'; //set online state to offline
630
- this.offlineDevices.push(
631
- {
632
- 'Device': deviceName,
633
- 'Adapter': deviceAdapterName,
634
- 'Last contact': lastContactString
635
- }
636
- );
702
+ await pushOfflineDevice();
637
703
  }
638
704
  } else if (lastContact > this.config.bleMaxMinutes) {
639
705
  deviceState = 'Offline'; //set online state to offline
640
- this.offlineDevices.push(
641
- {
642
- 'Device': deviceName,
643
- 'Adapter': deviceAdapterName,
644
- 'Last contact': lastContactString
645
- }
646
- );
706
+ await pushOfflineDevice();
647
707
  }
648
708
  break;
649
709
  case 'deconz':
650
710
  if (this.config.deconzMaxMinutes === -1) {
651
711
  if (!deviceUnreachState) {
652
712
  deviceState = 'Offline'; //set online state to offline
653
- this.offlineDevices.push(
654
- {
655
- 'Device': deviceName,
656
- 'Adapter': deviceAdapterName,
657
- 'Last contact': lastContactString
658
- }
659
- );
713
+ await pushOfflineDevice();
660
714
  }
661
715
  } else if (lastContact > this.config.deconzMaxMinutes) {
662
716
  deviceState = 'Offline'; //set online state to offline
663
- this.offlineDevices.push(
664
- {
665
- 'Device': deviceName,
666
- 'Adapter': deviceAdapterName,
667
- 'Last contact': lastContactString
668
- }
669
- );
717
+ await pushOfflineDevice();
670
718
  }
671
719
  break;
672
720
  case 'esphome':
673
721
  if (this.config.esphomeMaxMinutes === -1) {
674
722
  if (!deviceUnreachState) {
675
723
  deviceState = 'Offline'; //set online state to offline
676
- this.offlineDevices.push(
677
- {
678
- 'Device': deviceName,
679
- 'Adapter': deviceAdapterName,
680
- 'Last contact': lastContactString
681
- }
682
- );
724
+ await pushOfflineDevice();
683
725
  }
684
726
  } else if (lastContact > this.config.esphomeMaxMinutes) {
685
727
  deviceState = 'Offline'; //set online state to offline
686
- this.offlineDevices.push(
687
- {
688
- 'Device': deviceName,
689
- 'Adapter': deviceAdapterName,
690
- 'Last contact': lastContactString
691
- }
692
- );
728
+ await pushOfflineDevice();
693
729
  }
694
730
  break;
695
731
  case 'fritzDect':
696
732
  if (this.config.fritzdectMaxMinutes === -1) {
697
733
  if (!deviceUnreachState) {
698
734
  deviceState = 'Offline'; //set online state to offline
699
- this.offlineDevices.push(
700
- {
701
- 'Device': deviceName,
702
- 'Adapter': deviceAdapterName,
703
- 'Last contact': lastContactString
704
- }
705
- );
735
+ await pushOfflineDevice();
706
736
  }
707
737
  } else if (lastContact > this.config.fritzdectMaxMinutes) {
708
738
  deviceState = 'Offline'; //set online state to offline
709
- this.offlineDevices.push(
710
- {
711
- 'Device': deviceName,
712
- 'Adapter': deviceAdapterName,
713
- 'Last contact': lastContactString
714
- }
715
- );
739
+ await pushOfflineDevice();
716
740
  }
717
741
  break;
718
742
  case 'homematic':
719
743
  if (this.config.homematicMaxMinutes === -1) {
720
744
  if (deviceUnreachState) {
721
745
  deviceState = 'Offline'; //set online state to offline
722
- this.offlineDevices.push(
723
- {
724
- 'Device': deviceName,
725
- 'Adapter': deviceAdapterName,
726
- 'Last contact': lastContactString
727
- }
728
- );
746
+ await pushOfflineDevice();
729
747
  }
730
748
  } else if (lastContact > this.config.homematicMaxMinutes) {
731
749
  deviceState = 'Offline'; //set online state to offline
732
- this.offlineDevices.push(
733
- {
734
- 'Device': deviceName,
735
- 'Adapter': deviceAdapterName,
736
- 'Last contact': lastContactString
737
- }
738
- );
750
+ await pushOfflineDevice();
739
751
  }
740
752
  break;
741
753
  case 'hue':
742
754
  if (this.config.hueMaxMinutes === -1) {
743
755
  if (!deviceUnreachState) {
744
756
  deviceState = 'Offline'; //set online state to offline
745
- this.offlineDevices.push(
746
- {
747
- 'Device': deviceName,
748
- 'Adapter': deviceAdapterName,
749
- 'Last contact': lastContactString
750
- }
751
- );
757
+ await pushOfflineDevice();
752
758
  }
753
759
  } else if (lastContact > this.config.hueMaxMinutes) {
754
760
  deviceState = 'Offline'; //set online state to offline
755
- this.offlineDevices.push(
756
- {
757
- 'Device': deviceName,
758
- 'Adapter': deviceAdapterName,
759
- 'Last contact': lastContactString
760
- }
761
- );
761
+ await pushOfflineDevice();
762
762
  }
763
763
  break;
764
764
  case 'hue-extended':
765
765
  if (this.config.hueextMaxMinutes === -1) {
766
766
  if (!deviceUnreachState) {
767
767
  deviceState = 'Offline'; //set online state to offline
768
- this.offlineDevices.push(
769
- {
770
- 'Device': deviceName,
771
- 'Adapter': deviceAdapterName,
772
- 'Last contact': lastContactString
773
- }
774
- );
768
+ await pushOfflineDevice();
775
769
  }
776
770
  } else if (lastContact > this.config.hueextMaxMinutes) {
777
771
  deviceState = 'Offline'; //set online state to offline
778
- this.offlineDevices.push(
779
- {
780
- 'Device': deviceName,
781
- 'Adapter': deviceAdapterName,
782
- 'Last contact': lastContactString
783
- }
784
- );
772
+ await pushOfflineDevice();
785
773
  }
786
774
  break;
787
775
  case 'miHome':
788
776
  if (this.config.mihomeMaxMinutes === -1) {
789
777
  if (!deviceUnreachState) {
790
778
  deviceState = 'Offline'; //set online state to offline
791
- this.offlineDevices.push(
792
- {
793
- 'Device': deviceName,
794
- 'Adapter': deviceAdapterName,
795
- 'Last contact': lastContactString
796
- }
797
- );
779
+ await pushOfflineDevice();
798
780
  }
799
781
  } else if (lastContact > this.config.mihomeMaxMinutes) {
800
782
  deviceState = 'Offline'; //set online state to offline
801
- this.offlineDevices.push(
802
- {
803
- 'Device': deviceName,
804
- 'Adapter': deviceAdapterName,
805
- 'Last contact': lastContactString
806
- }
807
- );
783
+ await pushOfflineDevice();
808
784
  }
809
785
  break;
810
786
  case 'nuki-extended':
811
787
  if (this.config.nukiextendMaxMinutes === -1) {
812
788
  if (!deviceUnreachState) {
813
789
  deviceState = 'Offline'; //set online state to offline
814
- this.offlineDevices.push(
815
- {
816
- 'Device': deviceName,
817
- 'Adapter': deviceAdapterName,
818
- 'Last contact': lastContactString
819
- }
820
- );
790
+ await pushOfflineDevice();
821
791
  }
822
792
  } else if (lastContact > this.config.nukiextendMaxMinutes) {
823
793
  deviceState = 'Offline'; //set online state to offline
824
- this.offlineDevices.push(
825
- {
826
- 'Device': deviceName,
827
- 'Adapter': deviceAdapterName,
828
- 'Last contact': lastContactString
829
- }
830
- );
794
+ await pushOfflineDevice();
831
795
  }
832
796
  break;
833
797
  case 'ping':
834
798
  if (this.config.pingMaxMinutes === -1) {
835
799
  if (!deviceUnreachState) {
836
800
  deviceState = 'Offline'; //set online state to offline
837
- this.offlineDevices.push(
838
- {
839
- 'Device': deviceName,
840
- 'Adapter': deviceAdapterName,
841
- 'Last contact': lastContactString
842
- }
843
- );
801
+ await pushOfflineDevice();
844
802
  }
845
803
  } else if ((lastStateChange > this.config.pingMaxMinutes) && (!deviceUnreachState)) {
846
804
  deviceState = 'Offline'; //set online state to offline
847
- this.offlineDevices.push(
848
- {
849
- 'Device': deviceName,
850
- 'Adapter': deviceAdapterName,
851
- 'Last contact': lastContactString
852
- }
853
- );
805
+ await pushOfflineDevice();
854
806
  }
855
807
  break;
856
808
  case 'shelly':
857
809
  if (this.config.shellyMaxMinutes === -1) {
858
810
  if (!deviceUnreachState) {
859
811
  deviceState = 'Offline'; //set online state to offline
860
- this.offlineDevices.push(
861
- {
862
- 'Device': deviceName,
863
- 'Adapter': deviceAdapterName,
864
- 'Last contact': lastContactString
865
- }
866
- );
812
+ await pushOfflineDevice();
867
813
  }
868
814
  } else if (lastContact > this.config.shellyMaxMinutes) {
869
815
  deviceState = 'Offline'; //set online state to offline
870
- this.offlineDevices.push(
871
- {
872
- 'Device': deviceName,
873
- 'Adapter': deviceAdapterName,
874
- 'Last contact': lastContactString
875
- }
876
- );
816
+ await pushOfflineDevice();
877
817
  }
878
818
  break;
879
819
  case 'sonoff':
880
820
  if (this.config.sonoffMaxMinutes === -1) {
881
821
  if (!deviceUnreachState) {
882
822
  deviceState = 'Offline'; //set online state to offline
883
- this.offlineDevices.push(
884
- {
885
- 'Device': deviceName,
886
- 'Adapter': deviceAdapterName,
887
- 'Last contact': lastContactString
888
- }
889
- );
823
+ await pushOfflineDevice();
890
824
  }
891
825
  } else if (lastContact > this.config.sonoffMaxMinutes) {
892
826
  deviceState = 'Offline'; //set online state to offline
893
- this.offlineDevices.push(
894
- {
895
- 'Device': deviceName,
896
- 'Adapter': deviceAdapterName,
897
- 'Last contact': lastContactString
898
- }
899
- );
827
+ await pushOfflineDevice();
900
828
  }
901
829
  break;
902
830
  case 'sonos':
903
831
  if (this.config.sonosMaxMinutes === -1) {
904
832
  if (!deviceUnreachState) {
905
833
  deviceState = 'Offline'; //set online state to offline
906
- this.offlineDevices.push(
907
- {
908
- 'Device': deviceName,
909
- 'Adapter': deviceAdapterName,
910
- 'Last contact': lastContactString
911
- }
912
- );
834
+ await pushOfflineDevice();
913
835
  }
914
836
  } else if (lastContact > this.config.sonosMaxMinutes) {
915
837
  deviceState = 'Offline'; //set online state to offline
916
- this.offlineDevices.push(
917
- {
918
- 'Device': deviceName,
919
- 'Adapter': deviceAdapterName,
920
- 'Last contact': lastContactString
921
- }
922
- );
838
+ await pushOfflineDevice();
923
839
  }
924
840
  break;
925
841
  case 'switchbotBle':
926
842
  if (this.config.switchbotMaxMinutes === -1) {
927
843
  if (!deviceUnreachState) {
928
844
  deviceState = 'Offline'; //set online state to offline
929
- this.offlineDevices.push(
930
- {
931
- 'Device': deviceName,
932
- 'Adapter': deviceAdapterName,
933
- 'Last contact': lastContactString
934
- }
935
- );
845
+ await pushOfflineDevice();
936
846
  }
937
847
  } else if (lastContact > this.config.switchbotMaxMinutes) {
938
848
  deviceState = 'Offline'; //set online state to offline
939
- this.offlineDevices.push(
940
- {
941
- 'Device': deviceName,
942
- 'Adapter': deviceAdapterName,
943
- 'Last contact': lastContactString
944
- }
945
- );
849
+ await pushOfflineDevice();
946
850
  }
947
851
  break;
948
852
  case 'zigbee':
949
853
  if (this.config.zigbeeMaxMinutes === -1) {
950
854
  if (!deviceUnreachState) {
951
855
  deviceState = 'Offline'; //set online state to offline
952
- this.offlineDevices.push(
953
- {
954
- 'Device': deviceName,
955
- 'Adapter': deviceAdapterName,
956
- 'Last contact': lastContactString
957
- }
958
- );
856
+ await pushOfflineDevice();
959
857
  }
960
858
  } else if (lastContact > this.config.zigbeeMaxMinutes) {
961
859
  deviceState = 'Offline'; //set online state to offline
962
- this.offlineDevices.push(
963
- {
964
- 'Device': deviceName,
965
- 'Adapter': deviceAdapterName,
966
- 'Last contact': lastContactString
967
- }
968
- );
860
+ await pushOfflineDevice();
969
861
  }
970
862
  break;
971
863
  case 'zwave':
972
864
  if (this.config.zwaveMaxMinutes === -1) {
973
865
  if (!deviceUnreachState) {
974
866
  deviceState = 'Offline'; //set online state to offline
975
- this.offlineDevices.push(
976
- {
977
- 'Device': deviceName,
978
- 'Adapter': deviceAdapterName,
979
- 'Last contact': lastContactString
980
- }
981
- );
867
+ await pushOfflineDevice();
982
868
  }
983
869
  } else if (lastContact > this.config.zwaveMaxMinutes) {
984
870
  deviceState = 'Offline'; //set online state to offline
985
- this.offlineDevices.push(
986
- {
987
- 'Device': deviceName,
988
- 'Adapter': deviceAdapterName,
989
- 'Last contact': lastContactString
990
- }
991
- );
871
+ await pushOfflineDevice();
992
872
  }
993
873
  break;
994
874
  }
995
- } catch (e) {
996
- this.log.error(`(03) Error while getting timestate ${e}`);
875
+ } catch (error) {
876
+ this.errorReporting('[getLastContact]', error);
997
877
  }
998
878
  }
999
879
 
@@ -1003,8 +883,6 @@ class DeviceWatcher extends utils.Adapter {
1003
883
  this.offlineDevicesCount = this.offlineDevices.length;
1004
884
 
1005
885
  // 3. Get battery states
1006
- const deviceBatteryState = await this.getInitValue(currDeviceString + this.arrDev[i].battery);
1007
- const shortDeviceBatteryState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery);
1008
886
  let batteryHealth;
1009
887
 
1010
888
  if ((!deviceBatteryState) && (!shortDeviceBatteryState)) {
@@ -1059,35 +937,44 @@ class DeviceWatcher extends utils.Adapter {
1059
937
  const deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat);
1060
938
  const deviceLowBatStateHM = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat2);
1061
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;
1062
952
 
1063
- if (this.arrDev[i].isLowBat === 'none') {
1064
- if (deviceBatteryState && (deviceBatteryState < batteryWarningMin)) {
1065
- this.batteryLowPowered.push(
1066
- {
1067
- 'Device': deviceName,
1068
- 'Adapter': deviceAdapterName,
1069
- 'Battery': batteryHealth
1070
- }
1071
- );
1072
- }
1073
- } else {
1074
- if (deviceLowBatState || deviceLowBatStateHM) {
1075
- this.batteryLowPowered.push(
1076
- {
1077
- 'Device': deviceName,
1078
- 'Adapter': deviceAdapterName,
1079
- 'Battery': batteryHealth
1080
- }
1081
- );
1082
- }
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
+ }
1083
971
  }
1084
972
 
1085
973
  // 3d. Count how many devices are with low battery
1086
974
  this.lowBatteryPoweredCount = this.batteryLowPowered.length;
1087
975
 
1088
- // 4. Add all devices in the list
1089
- if (this.config.listOnlyBattery) {
1090
- if (deviceBatteryState !== null || shortDeviceBatteryState !== null) {
976
+ if (this.config.listOnlyBattery) { // 4. Add only devices with battery in the list
977
+ if (deviceBatteryState || shortDeviceBatteryState) {
1091
978
  this.listAllDevices.push(
1092
979
  {
1093
980
  'Device': deviceName,
@@ -1099,7 +986,7 @@ class DeviceWatcher extends utils.Adapter {
1099
986
  }
1100
987
  );
1101
988
  }
1102
- } else if (!this.config.listOnlyBattery) {
989
+ } else if (!this.config.listOnlyBattery) { // 4. Add all devices
1103
990
  this.listAllDevices.push(
1104
991
  {
1105
992
  'Device': deviceName,
@@ -1116,129 +1003,182 @@ class DeviceWatcher extends utils.Adapter {
1116
1003
  // 4a. Count how many devices are exists
1117
1004
  this.deviceCounter = this.listAllDevices.length;
1118
1005
  }
1119
- } //<--End of second loop
1120
- }
1006
+ } // <-- end of loop
1007
+ } // <-- end of createData
1121
1008
 
1122
- async createDataForEachAdpt(adptName) {
1123
- this.log.debug(`Function started: ${this.createDataForEachAdpt.name}`);
1124
- await this.resetVars();
1125
1009
 
1126
- for (let i = 0; i < this.arrDev.length; i++) {
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}`);
1127
1016
 
1128
- if (this.arrDev[i].adapter.includes(adptName)) {
1129
- await this.createData(i);
1130
- }
1017
+ try {
1018
+ await this.resetVars(); // reset the arrays and counts
1131
1019
 
1020
+ for (let i = 0; i < this.arrDev.length; i++) {
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);
1132
1029
  }
1133
- await this.writeDatapoints(adptName);
1134
1030
 
1135
- this.log.debug(`Function finished: ${this.createDataForEachAdpt.name}`);
1136
- }
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
1137
1040
 
1138
- async createDataOfAll() {
1139
- this.log.debug(`Function started: ${this.createDataOfAll.name}`);
1140
- await this.resetVars();
1041
+ for (let i = 0; i < this.arrDev.length; i++) {
1141
1042
 
1142
- for (let i = 0; i < this.arrDev.length; i++) {
1043
+ await this.createData(i);
1143
1044
 
1144
- await this.createData(i);
1045
+ }
1145
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);
1146
1052
  }
1147
- await this.writeDatapoints();
1148
1053
 
1149
- this.log.debug(`Function finished: ${this.createDataOfAll.name}`);
1150
- }
1054
+ this.log.debug(`Function finished: ${this.createDataOfAllAdapter.name}`);
1055
+ } // <-- end of createDataOfAllAdapter
1151
1056
 
1152
- async resetVars() {
1153
- // arrays
1154
- this.offlineDevices = [],
1155
- this.linkQualityDevices = [];
1156
- this.batteryPowered = [];
1157
- this.batteryLowPowered = [];
1158
- this.listAllDevices = [];
1159
1057
 
1160
- // counts
1161
- this.offlineDevicesCount = 0;
1162
- this.deviceCounter = 0;
1163
- this.linkQualityCount = 0;
1164
- this.batteryPoweredCount = 0;
1165
- this.lowBatteryPoweredCount = 0;
1058
+ /**
1059
+ * Notification service
1060
+ * @param {string} [text] - Text which should be send
1061
+ **/
1062
+ async sendNotification(text) {
1166
1063
 
1167
- this.deviceReachable = '';
1168
- }
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');
1169
1069
 
1170
- async main() {
1171
- this.log.debug(`Function started: ${this.main.name}`);
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
+ }
1172
1084
 
1173
- this.supAdapter = {
1174
- alexa2: this.config.alexa2Devices,
1175
- esphome: this.config.esphomeDevices,
1176
- zigbee: this.config.zigbeeDevices,
1177
- ble: this.config.bleDevices,
1178
- sonoff: this.config.sonoffDevices,
1179
- shelly: this.config.shellyDevices,
1180
- homematic: this.config.homematicDevices,
1181
- deconz: this.config.deconzDevices,
1182
- zwave: this.config.zwaveDevices,
1183
- dect: this.config.dectDevices,
1184
- hue: this.config.hueDevices,
1185
- hueExt: this.config.hueExtDevices,
1186
- nukiExt: this.config.nukiExtDevices,
1187
- ping: this.config.pingDevices,
1188
- switchbotBle: this.config.switchbotBleDevices,
1189
- sonos: this.config.sonosDevices,
1190
- mihome: this.config.mihomeDevices,
1191
- mihomeGW: this.config.mihomeDevices,
1192
- };
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');
1193
1090
 
1194
- for(const [id] of Object.entries(this.arrApart)) {
1195
- if (this.supAdapter[id]) {
1196
- this.arrDev.push(this.arrApart[id]);
1197
- this.adapterSelected.push(await this.capitalize(id));
1198
- this.log.debug(JSON.stringify(this.arrDev));
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
+ }
1199
1104
 
1200
- //create and fill datapoints for each adapter if selected
1201
- if (this.config.createOwnFolder) {
1202
- try {
1203
- await this.createDPsForEachAdapter(id);
1204
- this.log.debug(`Created datapoints for ${await this.capitalize(id)}`);
1205
- await this.createDataForEachAdpt(id);
1206
- this.log.debug(`Created and filled data for each adapter`);
1207
- } catch (e) {
1208
- this.log.warn(`Error at creating/filling datapoints for each adapter: ${e}`);
1209
- return;
1210
- }
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');
1110
+
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
+ });
1211
1118
  }
1212
1119
  }
1120
+ } catch (error) {
1121
+ this.errorReporting('[sendNotification Whatsapp]', error);
1213
1122
  }
1214
1123
 
1215
- //Check if an Adapter is selected.
1216
- if (this.adapterSelected.length >= 1) {
1217
- this.log.info(`Number of selected adapters: ${this.adapterSelected.length}. Loading data from: ${(this.adapterSelected).join(', ')} ...`);
1218
- } else {
1219
- this.log.warn(`No adapter selected. Please check the instance configuration!`);
1220
- return;
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);
1221
1142
  }
1222
1143
 
1223
- /*=============================================
1224
- = Start of main loop =
1225
- =============================================*/
1144
+ // Jarvis Notification
1226
1145
  try {
1227
- await this.createDataOfAll();
1228
- this.log.debug(`Created and filled data for all adapters`);
1229
- } catch (e) {
1230
- this.log.warn(`Error at creating/filling datapoints for all adapters: ${e}`);
1231
- return;
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);
1232
1159
  }
1233
1160
 
1234
- this.log.debug(`Function finished: ${this.main.name}`);
1235
- } //<--End of main function
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
1236
1178
 
1237
1179
 
1238
1180
  async sendOfflineNotifications() {
1239
- /*=============================================
1240
- = send offline notification =
1241
- =============================================*/
1181
+ // send message if an device is offline
1242
1182
 
1243
1183
  this.log.debug(`Start the function: ${this.sendOfflineNotifications.name}`);
1244
1184
 
@@ -1258,179 +1198,118 @@ class DeviceWatcher extends utils.Adapter {
1258
1198
  }
1259
1199
  this.log.info(msg);
1260
1200
  await this.setStateAsync('lastNotification', msg, true);
1261
- if (this.config.instancePushover) {
1262
- try {
1263
- await this.sendPushover(msg);
1264
- } catch (e) {
1265
- this.log.warn (`Getting error at sending pushover notification ${e}`);
1266
- }
1267
- }
1268
- if (this.config.instanceTelegram) {
1269
- try {
1270
- await this.sendTelegram(msg);
1271
- } catch (e) {
1272
- this.log.warn (`Getting error at sending telegram notification ${e}`);
1273
- }
1274
- }
1275
- if (this.config.instanceWhatsapp) {
1276
- try {
1277
- await this.sendWhatsapp(msg);
1278
- } catch (e) {
1279
- this.log.warn (`Getting error at sending whatsapp notification ${e}`);
1280
- }
1281
- }
1282
- if (this.config.instanceEmail) {
1283
- try {
1284
- await this.sendEmail(msg);
1285
- } catch (e) {
1286
- this.log.warn (`Getting error at sending email notification ${e}`);
1287
- }
1288
- }
1289
- if (this.config.instanceJarvis) {
1290
- try {
1291
- 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"}');
1292
- } catch (e) {
1293
- this.log.warn (`Getting error at sending jarvis notification ${e}`);
1294
- }
1295
- }
1296
- if (this.config.instanceLovelace) {
1297
- try {
1298
- 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') + ')"}');
1299
- } catch (e) {
1300
- this.log.warn (`Getting error at sending lovelace notification ${e}`);
1301
- }
1302
- }
1201
+ await this.sendNotification(msg);
1303
1202
  }
1304
- } catch (e) {
1305
- this.log.debug(`Getting error at sending offline notification ${e}`);
1203
+ } catch (error) {
1204
+ this.errorReporting('[sendOfflineMessage]', error);
1306
1205
  }
1307
1206
  this.log.debug(`Finished the function: ${this.sendOfflineNotifications.name}`);
1308
1207
  }//<--End of offline notification
1309
1208
 
1310
1209
 
1311
1210
  async sendBatteryNotifications() {
1312
- /*=============================================
1313
- = send low battery notification =
1314
- =============================================*/
1211
+ // send message for low battery devices
1315
1212
 
1316
1213
  this.log.debug(`Start the function: ${this.sendBatteryNotifications.name}`);
1317
- const now = new Date();
1318
- const today = now.getDay();
1319
- const checkDays = [];
1320
- let checkToday;
1321
-
1322
- const choosedDays = {
1323
- monday: this.config.checkMonday,
1324
- tuesday: this.config.checkTuesday,
1325
- wednesday: this.config.checkWednesday,
1326
- thursday: this.config.checkThursday,
1327
- friday: this.config.checkFriday,
1328
- saturday: this.config.checkSaturday,
1329
- sunday: this.config.checkSunday,
1330
- };
1331
1214
 
1332
- if (choosedDays.monday) checkDays.push(1);
1333
- if (choosedDays.tuesday) checkDays.push(2);
1334
- if (choosedDays.wednesday) checkDays.push(3);
1335
- if (choosedDays.thursday) checkDays.push(4);
1336
- if (choosedDays.friday) checkDays.push(5);
1337
- if (choosedDays.saturday) checkDays.push(6);
1338
- if (choosedDays.sunday) checkDays.push(0);
1339
-
1340
- //Check if the message should be send today
1341
- checkDays.forEach(object => {
1342
- if((object >= 0) && today == object){
1343
- checkToday = true;
1344
- }
1345
- });
1215
+ try {
1346
1216
 
1347
- //Check first if a day is selected
1348
- if (checkDays.length >= 1) {
1349
- this.log.debug(`Number of selected days: ${checkDays.length}. Send Message on: ${(checkDays).join(', ')} ...`);
1350
- } else {
1351
- this.log.warn(`No days selected. Please check the instance configuration!`);
1352
- return;
1353
- }
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
+ });
1354
1237
 
1355
- try {
1356
- //Check if the message for low battery was already sent today
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
+ }
1244
+
1245
+ // Check if the message for low battery was already sent today
1357
1246
  const lastBatteryNotifyIndicator = await this.getOwnInitValue('info.lastBatteryNotification');
1358
1247
 
1359
- if (now.getHours() < 11) {await this.setStateAsync('info.lastBatteryNotification', false, true);} //set indicator for send message first to 'false' later after sending to 'true'
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)
1360
1252
  if ((now.getHours() > 11) && (!lastBatteryNotifyIndicator) && (checkToday != undefined)){
1361
- let infotext = '';
1253
+ let msg = '';
1362
1254
 
1363
1255
  for (const id of this.batteryLowPowered) {
1364
- infotext = '\n' + id['Device'] + ' (' + id['Battery'] + ')'.split(', ');
1256
+ msg = '\n' + id['Device'] + ' (' + id['Battery'] + ')'.split(', ');
1365
1257
  }
1366
1258
 
1367
1259
  if (this.lowBatteryPoweredCount > 0) {
1368
- this.log.info(`Niedrige Batteriezustände: ${infotext}`);
1369
- await this.setStateAsync('lastNotification', `Niedrige Batteriezustände: ${infotext}`, true);
1370
-
1371
- if (this.config.instancePushover) {
1372
- try {
1373
- await this.sendPushover(`Niedrige Batteriezustände: ${infotext}`);
1374
- } catch (e) {
1375
- this.log.warn (`Getting error at sending pushover notification ${e}`);
1376
- }
1377
- }
1378
- if (this.config.instanceTelegram) {
1379
- try {
1380
- await this.sendTelegram(`Niedrige Batteriezustände: ${infotext}`);
1381
- } catch (e) {
1382
- this.log.warn (`Getting error at sending telegram notification ${e}`);
1383
- }
1384
- }
1385
- if (this.config.instanceWhatsapp) {
1386
- try {
1387
- await this.sendWhatsapp(`Niedrige Batteriezustände: ${infotext}`);
1388
- } catch (e) {
1389
- this.log.warn (`Getting error at sending whatsapp notification ${e}`);
1390
- }
1391
- }
1392
- if (this.config.instanceEmail) {
1393
- try {
1394
- await this.sendEmail(`Niedrige Batteriezustände: ${infotext}`);
1395
- } catch (e) {
1396
- this.log.warn (`Getting error at sending email notification ${e}`);
1397
- }
1398
- }
1399
- if (this.config.instanceJarvis) {
1400
- try {
1401
- 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"}');
1402
- } catch (e) {
1403
- this.log.warn (`Getting error at sending jarvis notification ${e}`);
1404
- }
1405
- }
1406
- if (this.config.instanceLovelace) {
1407
- try {
1408
- 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') + ')"}');
1409
- } catch (e) {
1410
- this.log.warn (`Getting error at sending lovelace notification ${e}`);
1411
- }
1412
- }
1260
+ this.log.info(`Niedrige Batteriezustände: ${msg}`);
1261
+ await this.setStateAsync('lastNotification', `Niedrige Batteriezustände: ${msg}`, true);
1262
+
1263
+ await this.sendNotification(msg);
1413
1264
 
1414
1265
  await this.setStateAsync('info.lastBatteryNotification', true, true);
1415
1266
  }
1416
1267
  }
1417
- } catch (e) {
1418
- this.log.debug(`Getting error at sending battery notification ${e}`);
1268
+ } catch (error) {
1269
+ this.errorReporting('[sendOfflineMessage]', error);
1419
1270
  }
1271
+
1420
1272
  this.log.debug(`Finished the function: ${this.sendBatteryNotifications.name}`);
1421
1273
  }//<--End of battery notification
1422
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
+ */
1423
1303
  async writeDatapoints(adptName) {
1424
- /*=============================================
1425
- = Write Datapoints =
1426
- =============================================*/
1304
+ // fill the datapoints
1427
1305
 
1428
1306
  this.log.debug(`Start the function: ${this.writeDatapoints.name}`);
1429
1307
 
1430
1308
  try {
1431
1309
 
1432
1310
  let dpSubFolder;
1433
- if (adptName) { //write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
1311
+ //write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
1312
+ if (adptName) {
1434
1313
  dpSubFolder = adptName + '.';
1435
1314
  } else {
1436
1315
  dpSubFolder = '';}
@@ -1441,7 +1320,8 @@ class DeviceWatcher extends utils.Adapter {
1441
1320
  await this.setStateAsync(`${dpSubFolder}lowBatteryCount`, {val: this.lowBatteryPoweredCount, ack: true});
1442
1321
 
1443
1322
  if (this.deviceCounter == 0) {
1444
- this.listAllDevices = [{'Device': '--none--', 'Adapter': '', 'Battery': '', 'Last contact': '', 'Signal strength': ''}]; //JSON-Info Gesamtliste mit Info je Gerät
1323
+ // if no device is count, write the JSON List with default value
1324
+ this.listAllDevices = [{'Device': '--none--', 'Adapter': '', 'Battery': '', 'Last contact': '', 'Signal strength': ''}];
1445
1325
 
1446
1326
  await this.setStateAsync(`${dpSubFolder}listAll`, {val: JSON.stringify(this.listAllDevices), ack: true});
1447
1327
  } else {
@@ -1449,7 +1329,8 @@ class DeviceWatcher extends utils.Adapter {
1449
1329
  }
1450
1330
 
1451
1331
  if (this.linkQualityCount == 0) {
1452
- this.linkQualityDevices = [{'Device': '--none--', 'Adapter': '', 'Signal strength': ''}]; //JSON-Info alle mit LinkQuality
1332
+ // if no device is count, write the JSON List with default value
1333
+ this.linkQualityDevices = [{'Device': '--none--', 'Adapter': '', 'Signal strength': ''}];
1453
1334
 
1454
1335
  await this.setStateAsync(`${dpSubFolder}linkQualityList`, {val: JSON.stringify(this.linkQualityDevices), ack: true});
1455
1336
  } else {
@@ -1458,7 +1339,8 @@ class DeviceWatcher extends utils.Adapter {
1458
1339
 
1459
1340
 
1460
1341
  if (this.offlineDevicesCount == 0) {
1461
- this.offlineDevices = [{'Device': '--none--', 'Adapter': '', 'Last contact': ''}]; //JSON-Info alle offline-Geräte = 0
1342
+ // if no device is count, write the JSON List with default value
1343
+ this.offlineDevices = [{'Device': '--none--', 'Adapter': '', 'Last contact': ''}];
1462
1344
 
1463
1345
  await this.setStateAsync(`${dpSubFolder}offlineList`, {val: JSON.stringify(this.offlineDevices), ack: true});
1464
1346
  } else {
@@ -1466,7 +1348,8 @@ class DeviceWatcher extends utils.Adapter {
1466
1348
  }
1467
1349
 
1468
1350
  if (this.batteryPoweredCount == 0) {
1469
- this.batteryPowered = [{'Device': '--none--', 'Adapter': '', 'Battery': ''}]; //JSON-Info alle batteriebetriebenen Geräte
1351
+ // if no device is count, write the JSON List with default value
1352
+ this.batteryPowered = [{'Device': '--none--', 'Adapter': '', 'Battery': ''}];
1470
1353
 
1471
1354
  await this.setStateAsync(`${dpSubFolder}batteryList`, {val: JSON.stringify(this.batteryPowered), ack: true});
1472
1355
  } else {
@@ -1474,23 +1357,42 @@ class DeviceWatcher extends utils.Adapter {
1474
1357
  }
1475
1358
 
1476
1359
  if (this.lowBatteryPoweredCount == 0) {
1477
- this.batteryLowPowered = [{'Device': '--none--', 'Adapter': '', 'Battery': ''}]; //JSON-Info alle batteriebetriebenen Geräte
1360
+ // if no device is count, write the JSON List with default value
1361
+ this.batteryLowPowered = [{'Device': '--none--', 'Adapter': '', 'Battery': ''}];
1478
1362
 
1479
1363
  await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {val: JSON.stringify(this.batteryLowPowered), ack: true});
1480
1364
  } else {
1481
1365
  await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {val: JSON.stringify(this.batteryLowPowered), ack: true});
1482
1366
  }
1483
1367
 
1484
- //Zeitstempel wann die Datenpunkte zuletzt gecheckt wurden
1368
+ // create timestamp of last run
1485
1369
  const lastCheck = this.formatDate(new Date(), 'DD.MM.YYYY') + ' - ' + this.formatDate(new Date(), 'hh:mm:ss');
1486
1370
  await this.setStateAsync('lastCheck', lastCheck, true);
1487
1371
  }
1488
- catch (e) {
1489
- this.log.error(`(05) Error while writing the states ${e}`);
1372
+ catch (error) {
1373
+ this.errorReporting('[writeDatapoints]', error);
1490
1374
  }
1491
1375
  this.log.debug(`Function finished: ${this.writeDatapoints.name}`);
1492
1376
  }//<--End of writing Datapoints
1493
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
1494
1396
 
1495
1397
 
1496
1398
  onUnload(callback) {