iobroker.device-watcher 0.0.6

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 ADDED
@@ -0,0 +1,582 @@
1
+ /* jshint -W097 */
2
+ /* jshint strict: false */
3
+ /* jslint node: true */
4
+
5
+ 'use strict';
6
+
7
+ const utils = require('@iobroker/adapter-core');
8
+ const adapterName = require('./package.json').name.split('.').pop();
9
+
10
+ class DeviceWatcher extends utils.Adapter {
11
+
12
+ constructor(options) {
13
+ super({
14
+ ...options,
15
+ name: adapterName,
16
+ useFormatDate: true,
17
+ });
18
+
19
+ this.refreshEverythingTimeout = null;
20
+
21
+ this.on('ready', this.onReady.bind(this));
22
+ //this.on('stateChange', this.onStateChange.bind(this));
23
+ // this.on('objectChange', this.onObjectChange.bind(this));
24
+ // this.on('message', this.onMessage.bind(this));
25
+ this.on('unload', this.onUnload.bind(this));
26
+ }
27
+
28
+ async onReady() {
29
+ this.log.debug('Adapter Device-Watcher was started');
30
+
31
+ try {
32
+ await this.main();
33
+ this.log.debug('all done, exiting');
34
+ this.terminate ? this.terminate('Everything done. Going to terminate till next schedule', 11) : process.exit(0);
35
+ } catch (e) {
36
+ this.log.error('Error while running Device-Watcher. Error Message:' + e);
37
+ this.terminate ? this.terminate(15) : process.exit(15);
38
+ }
39
+
40
+
41
+
42
+ }
43
+
44
+ async main() {
45
+
46
+ //Helperfunctions
47
+ //capitalize the first letter
48
+ /*
49
+ async function capitalize(sentence)
50
+ {
51
+ return sentence && sentence[0].toUpperCase() + sentence.slice(1);
52
+ }*/
53
+
54
+ const pushover = {
55
+ instance: this.config.instancePushover,
56
+ title: this.config.titlePushover,
57
+ device: this.config.devicePushover
58
+
59
+ };
60
+ const telegram = {
61
+ instance: this.config.instanceTelegram,
62
+ user: this.config.deviceTelegram
63
+ };
64
+ const email = {
65
+ instance: this.config.instanceEmail,
66
+ subject: this.config.subjectEmail,
67
+ sendTo: this.config.sendToEmail
68
+
69
+ };
70
+ const jarvis = {
71
+ instance: this.config.instanceJarvis,
72
+ title: this.config.titleJarvis
73
+
74
+ };
75
+ const choosedDays = {
76
+ monday: this.config.checkMonday,
77
+ tuesday: this.config.checkTuesday,
78
+ wednesday: this.config.checkWednesday,
79
+ thursday: this.config.checkThursday,
80
+ friday: this.config.checkFriday,
81
+ saturday: this.config.checkSaturday,
82
+ sunday: this.config.checkSunday,
83
+ };
84
+
85
+ const sendPushover = async (text) => {
86
+ await this.sendToAsync(pushover.instance, 'send', {
87
+ message: text,
88
+ title: pushover.title,
89
+ device: pushover.device
90
+ });
91
+ };
92
+
93
+ const sendTelegram = async (text) => {
94
+ await this.sendToAsync(telegram.instance, 'send', {
95
+ text: text,
96
+ user: telegram.user
97
+ });
98
+ };
99
+
100
+ const sendEmail = async (text) => {
101
+ await this.sendToAsync(email.instance, 'send', {
102
+ sendTo: email.sendTo,
103
+ text: text,
104
+ subject: email.subject
105
+ });
106
+ };
107
+
108
+ const sendJarvis = async (text) => {
109
+ await this.setForeignStateAsync('jarvis.0.addNotification', text);
110
+ };
111
+
112
+ this.log.debug('Function started: ' + this.main.name);
113
+
114
+ let arrOfflineDevices = []; //JSON-Info of all offline-devices
115
+ let jsonLinkQualityDevices = []; //JSON-Info of all devices with linkquality
116
+ let arrBatteryPowered = []; //JSON-Info of all devices with battery
117
+ let arrBatteryLowPowered = [];
118
+ let arrListAllDevices = []; //JSON-Info total list with info of all devices
119
+ let offlineDevicesCount = 0;
120
+ let deviceCounter = 0;
121
+ let batteryPoweredCount = 0;
122
+ let lowBatteryPoweredCount = 0;
123
+ let lastContactString;
124
+ const testMe = true;
125
+
126
+ if (!this.config.zigbeeDevices && !this.config.bleDevices && !this.config.sonoffDevices && !this.config.shellyDevices && !this.config.homematicDevices && !this.config.deconzDevices && !this.config.zwaveDevices) {
127
+ this.log.warn('No devices selected. Pleased check the instance configuration');
128
+ }
129
+
130
+ const myArrDev = []; //JSON mit Gesamtliste aller Geräte
131
+
132
+ if (testMe) { //Only for Developer to test the functions!!
133
+ myArrDev.push({'Selektor':'0_userdata.*.UNREACH', 'adapter':'Homematic', 'battery':'.OPERATING_VOLTAGE', 'reach':'.UNREACH'});
134
+ myArrDev.push({'Selektor':'0_userdata.*.link_quality', 'adapter':'Zigbee', 'battery':'.battery', 'reach':'.available'});
135
+ myArrDev.push({'Selektor':'0_userdata.*.reachable', 'adapter':'Test', 'battery':'.battery'});
136
+ myArrDev.push({'Selektor':'0_userdata.*.rssi', 'adapter':'Test', 'battery':'.sensor.battery'});
137
+ this.log.warn('Teststates wurden ausgewählt. Lade Daten...');
138
+ }
139
+
140
+ if (this.config.bleDevices) {
141
+ myArrDev.push({'Selektor':'ble.*.rssi', 'adapter':'Ble', 'battery':'.battery', 'reach':'none', 'isLowBat':'none'});
142
+ this.log.info('Ble Devices wurden ausgewählt (Xiaomi Plant Sensor). Lade Daten...');
143
+ }
144
+ if (this.config.zigbeeDevices) {
145
+ myArrDev.push({'Selektor':'zigbee.*.link_quality', 'adapter':'Zigbee', 'battery':'.battery', 'reach':'.available', 'isLowBat':'none'});
146
+ this.log.info('Zigbee Devices wurden ausgewählt. Lade Daten...');
147
+ }
148
+ if (this.config.sonoffDevices) {
149
+ myArrDev.push({'Selektor':'sonoff.*.Wifi_RSSI', 'adapter':'Sonoff', 'battery':'.battery', 'reach':'none', 'isLowBat':'none'});
150
+ myArrDev.push({'Selektor':'sonoff.*.Wifi_Signal', 'adapter':'Sonoff', 'battery':'.battery', 'reach':'none', 'isLowBat':'none'});
151
+ myArrDev.push({'Selektor':'sonoff.*.RSSI', 'adapter':'Sonoff', 'battery':'.battery', 'reach':'none', 'isLowBat':'none'});
152
+ this.log.info('Sonoff Devices wurden ausgewählt. Lade Daten...');
153
+ }
154
+ if (this.config.shellyDevices) {
155
+ myArrDev.push({'Selektor':'shelly.*.rssi', 'adapter':'Shelly', 'battery':'.sensor.battery', 'reach':'none', 'isLowBat':'none'});
156
+ this.log.info('Shelly Devices wurden ausgewählt. Lade Daten...');
157
+ }
158
+ if (this.config.homematicDevices) {
159
+ myArrDev.push({'Selektor':'hm-rpc.*.RSSI_DEVICE', 'adapter':'Homematic', 'battery':'.OPERATING_VOLTAGE', 'reach':'.UNREACH', 'isLowBat':'none'});
160
+ this.log.info('Homematic Devices wurden ausgewählt. Lade Daten...');
161
+ }
162
+ if (this.config.deconzDevices) {
163
+ myArrDev.push({'Selektor':'deconz.*.reachable', 'adapter':'Deconz', 'battery':'.battery', 'reach':'.reachable', 'isLowBat':'none'});
164
+ this.log.info('Deconz Devices wurden ausgewählt. Lade Daten...');
165
+ }
166
+ if (this.config.zwaveDevices) {
167
+ myArrDev.push({'Selektor':'zwave.*.ready', 'adapter':'Zwave', 'battery':'.battery.level', 'reach':'.ready', 'isLowBat':'.battery.isLow'});
168
+ this.log.info('Zwave Devices wurden ausgewählt. Lade Daten...');
169
+ }
170
+
171
+ this.log.debug(JSON.stringify(myArrDev));
172
+
173
+ /*=============================================
174
+ = Start of main loop =
175
+ =============================================*/
176
+ for (let i = 0; i < myArrDev.length; i++) {
177
+ const devices = await this.getForeignStatesAsync(myArrDev[i].Selektor);
178
+ const deviceAdapterName = myArrDev[i].adapter;
179
+
180
+ this.log.debug(JSON.stringify(devices));
181
+
182
+ const myBlacklist = this.config.tableBlacklist;
183
+ const myBlacklistArr = [];
184
+
185
+ /*---------- Loop for blacklist ----------*/
186
+ for(const i in myBlacklist){
187
+ myBlacklistArr.push(myBlacklist[i].device);
188
+ this.log.debug('Found items on the blacklist: ' + myBlacklistArr);
189
+ }
190
+
191
+ /*---------- Start of second main loop ----------*/
192
+ for(const [id] of Object.entries(devices)) {
193
+ if (!myBlacklistArr.includes(id)) {
194
+
195
+ const currDeviceString = id.slice(0, (id.lastIndexOf('.') + 1) - 1);
196
+
197
+ //Get device name
198
+ const deviceObject = await this.getForeignObjectAsync(currDeviceString);
199
+ let deviceName;
200
+
201
+ if (deviceObject && typeof deviceObject === 'object') {
202
+ deviceName = deviceObject.common.name;
203
+ }
204
+
205
+
206
+ //Get room name (not implement yet)
207
+ //const getRoomName = await this.getEnumAsync('rooms');
208
+ //let currRoom;
209
+ //this.log.warn(JSON.stringify(getRoomName));
210
+
211
+ /*for(const [id] of Object.entries(getRoomName.result)) {
212
+ currRoom = await capitalize(id.substring(id.lastIndexOf('.') + 1)) ;
213
+ this.log.warn(currRoom);
214
+ }*/
215
+
216
+ // 1. Get link quality
217
+ const deviceQualityState = await this.getForeignStateAsync(id);
218
+ let linkQuality;
219
+
220
+ if (deviceQualityState){
221
+ if (this.config.trueState) {
222
+ linkQuality = deviceQualityState.val;
223
+ } else if ((deviceQualityState.val != null) && (typeof deviceQualityState.val === 'number')) {
224
+ if (deviceQualityState.val < 0) {
225
+ linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
226
+ } else if ((deviceQualityState.val) >= 0) {
227
+ linkQuality = parseFloat((100/255 * deviceQualityState.val).toFixed(0)) + '%';
228
+ }
229
+ }
230
+ }
231
+ jsonLinkQualityDevices.push(
232
+ {
233
+ Device: deviceName,
234
+ Adapter: deviceAdapterName,
235
+ Link_quality: linkQuality
236
+ }
237
+ );
238
+
239
+ // 1b. Count how many devices are exists
240
+ deviceCounter = jsonLinkQualityDevices.length;
241
+
242
+ // 2. When was the last contact to the device?
243
+ if (deviceQualityState) {
244
+ try {
245
+ const time = new Date();
246
+ const lastContact = Math.round((time.getTime() - deviceQualityState.ts) / 1000 / 60);
247
+ const currDeviceUnreachString = currDeviceString + myArrDev[i].reach;
248
+ const deviceUnreachState = await this.getForeignStateAsync(currDeviceUnreachString);
249
+
250
+ // 2b. wenn seit X Minuten kein Kontakt mehr besteht, nimm Gerät in Liste auf
251
+ //Rechne auf Tage um, wenn mehr als 48 Stunden seit letztem Kontakt vergangen sind
252
+ //lastContactString = Math.round(lastContact) + ' Minuten';
253
+ lastContactString = this.formatDate(new Date((deviceQualityState.ts)), 'hh:mm') + ' Uhr';
254
+ if (Math.round(lastContact) > 100) {
255
+ lastContactString = Math.round(lastContact/60) + ' Stunden';
256
+ }
257
+ if (Math.round(lastContact/60) > 48) {
258
+ lastContactString = Math.round(lastContact/60/24) + ' Tagen';
259
+ }
260
+ if (myArrDev[i].reach === 'none') {
261
+ if (lastContact > this.config.maxMinutes) {
262
+ arrOfflineDevices.push(
263
+ {
264
+ Device: deviceName,
265
+ Adapter: deviceAdapterName,
266
+ Last_contact: lastContactString
267
+ }
268
+ );
269
+ }
270
+ } else {
271
+ if (deviceUnreachState) {
272
+ if ((deviceUnreachState.val === true) && (myArrDev[i].adapter === 'Homematic')) {
273
+ arrOfflineDevices.push(
274
+ {
275
+ Device: deviceName,
276
+ Adapter: deviceAdapterName,
277
+ Last_contact: lastContactString
278
+ }
279
+ );
280
+ } else if ((deviceUnreachState.val === false) && (myArrDev[i].adapter != 'Homematic')) {
281
+ arrOfflineDevices.push(
282
+ {
283
+ Device: deviceName,
284
+ Adapter: deviceAdapterName,
285
+ Last_contact: lastContactString
286
+ }
287
+ );
288
+ }
289
+ }
290
+ }
291
+ } catch (e) {
292
+ this.log.error('(03) Error while getting timestate ' + e);
293
+ }
294
+ }
295
+
296
+
297
+ // 2c. Count how many devcies are offline
298
+ offlineDevicesCount = arrOfflineDevices.length;
299
+
300
+ // 3. Get battery states
301
+ const currDeviceBatteryString = currDeviceString + myArrDev[i].battery;
302
+ const deviceBatteryState = await this.getForeignStateAsync(currDeviceBatteryString);
303
+ let batteryHealth;
304
+
305
+ if (!deviceBatteryState) {
306
+ batteryHealth = ' - ';
307
+ } else if ((myArrDev[i].adapter === 'Homematic') && (deviceBatteryState).val === 0) {
308
+ batteryHealth = ' - ';
309
+ } else if ((deviceBatteryState) && (myArrDev[i].adapter != 'Homematic')) {
310
+ batteryHealth = (deviceBatteryState).val + '%';
311
+ arrBatteryPowered.push(
312
+ {
313
+ Device: deviceName,
314
+ Adapter: deviceAdapterName,
315
+ Battery: batteryHealth
316
+ }
317
+ );
318
+ } else if ((deviceBatteryState) && (deviceBatteryState).val != 0 && myArrDev[i].adapter === 'Homematic') {
319
+ batteryHealth = (deviceBatteryState).val + 'V';
320
+ arrBatteryPowered.push(
321
+ {
322
+ Device: deviceName,
323
+ Adapter: deviceAdapterName,
324
+ Battery: batteryHealth
325
+ }
326
+ );
327
+ }
328
+ // 3b. Count how many devices are with battery
329
+ batteryPoweredCount = arrBatteryPowered.length;
330
+
331
+ // 3c. Count how many devices are with low battery
332
+ if (deviceBatteryState && deviceBatteryState.val) {
333
+ const batteryWarningMin = this.config.minWarnBatterie;
334
+ if ((deviceBatteryState.val < batteryWarningMin) && (myArrDev[i].adapter != 'Homematic')) {
335
+ arrBatteryLowPowered.push(
336
+ {
337
+ Device: deviceName,
338
+ Adapter: deviceAdapterName,
339
+ Battery: batteryHealth
340
+ }
341
+ );
342
+ }
343
+
344
+ }
345
+ // 3d. Count how many devices are with low battery
346
+ lowBatteryPoweredCount = arrBatteryLowPowered.length;
347
+
348
+ // 4. Add all devices in the list
349
+ arrListAllDevices.push(
350
+ {
351
+ Device: deviceName,
352
+ Adapter: deviceAdapterName,
353
+ Battery: batteryHealth,
354
+ Last_contact: lastContactString,
355
+ Link_quality: linkQuality
356
+ }
357
+ );
358
+ }
359
+ } //<--End of second loop
360
+ } //<---End of main loop
361
+
362
+ /*=============================================
363
+ = Notifications =
364
+ =============================================*/
365
+
366
+ /*---------- oflline notification ----------*/
367
+ if(this.config.checkSendOfflineMsg) {
368
+ try {
369
+ let msg = '';
370
+ const offlineDevicesCountOld = await this.getStateAsync('offlineCount');
371
+
372
+ if ((offlineDevicesCountOld != undefined) && (offlineDevicesCountOld != null)) {
373
+ if ((offlineDevicesCount != offlineDevicesCountOld.val) && (offlineDevicesCount != 0)) {
374
+ if (offlineDevicesCount == 1) {
375
+ msg = 'Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n';
376
+ } else if (offlineDevicesCount >= 2) {
377
+ msg = 'Folgende ' + offlineDevicesCount + ' Geräte sind seit einiger Zeit nicht erreichbar: \n';
378
+ }
379
+ for (const id of arrOfflineDevices) {
380
+ msg = msg + '\n' + id['Device'] + ' ' + /*id['room'] +*/ ' (' + id['Last_contact'] + ')';
381
+ }
382
+ this.log.info(msg);
383
+ await this.setStateAsync('lastNotification', msg, true);
384
+ if (pushover.instance) {
385
+ try {
386
+ await sendPushover(msg);
387
+ } catch (e) {
388
+ this.log.warn ('Getting error at sending notification' + (e));
389
+ }
390
+ }
391
+ if (telegram.instance) {
392
+ try {
393
+ await sendTelegram(msg);
394
+ } catch (e) {
395
+ this.log.warn ('Getting error at sending notification' + (e));
396
+ }
397
+ }
398
+ if (email.instance) {
399
+ try {
400
+ await sendEmail(msg);
401
+ } catch (e) {
402
+ this.log.warn ('Getting error at sending notification' + (e));
403
+ }
404
+ }
405
+ if (jarvis.instance) {
406
+ try {
407
+ await sendJarvis('{"title":"'+ jarvis.title +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message":" ' + offlineDevicesCount + ' Geräte sind nicht erreichbar","display": "drawer"}');
408
+ } catch (e) {
409
+ this.log.warn ('Getting error at sending notification' + (e));
410
+ }
411
+ }
412
+
413
+
414
+ }
415
+ }
416
+
417
+ } catch (e) {
418
+ this.log.debug('Getting error at sending offline notification ' + e);
419
+ }
420
+
421
+ }
422
+
423
+ /*---------- Low battery Notification ----------*/
424
+ const now = new Date();
425
+ const today = now.getDay();
426
+ const checkDays = [];
427
+ let checkToday;
428
+
429
+ if (choosedDays.monday) checkDays.push(1);
430
+ if (choosedDays.tuesday) checkDays.push(2);
431
+ if (choosedDays.wednesday) checkDays.push(3);
432
+ if (choosedDays.thursday) checkDays.push(4);
433
+ if (choosedDays.friday) checkDays.push(5);
434
+ if (choosedDays.saturday) checkDays.push(6);
435
+ if (choosedDays.sunday) checkDays.push(0);
436
+
437
+ if (this.config.checkSendBatteryMsg) this.log.debug(JSON.stringify(checkDays));
438
+
439
+ checkDays.forEach(object => {
440
+ if((object >= 0) && today == object){
441
+ checkToday = true;
442
+ }
443
+ });
444
+
445
+ if (this.config.checkSendBatteryMsg) {
446
+ try {
447
+ //Nur einmal abfragen
448
+ const lastBatteryNotifyIndicator = await this.getStateAsync('info.lastBatteryNotification');
449
+
450
+ if ((lastBatteryNotifyIndicator != undefined) && (lastBatteryNotifyIndicator != null)) {
451
+ if (now.getHours() < 11) {await this.setStateAsync('info.lastBatteryNotification', false, true);}
452
+ if ((now.getHours() > 11) && (lastBatteryNotifyIndicator.val == false) && (checkToday != undefined)){
453
+ let batteryMinCount = 0;
454
+ const batteryWarningMin = this.config.minWarnBatterie;
455
+
456
+ let infotext = '';
457
+ for (const id of arrBatteryPowered) {
458
+ if (id['Battery']) {
459
+ const batteryValue = parseFloat(id['Battery'].replace('%', ''));
460
+ if ((batteryValue < batteryWarningMin) && (id['Adapter'] != 'Homematic')) {
461
+ infotext = infotext + '\n' + id['Device'] + ' ' + /*id['room'] +*/ ' (' + id['Battery'] + ')'.split(', ');
462
+ ++batteryMinCount;
463
+ }
464
+ }
465
+ }
466
+ if (batteryMinCount > 0) {
467
+ this.log.info('Batteriezustände: ' + infotext);
468
+ await this.setStateAsync('lastNotification', infotext, true);
469
+ if (jarvis.instance) {
470
+ try {
471
+ await sendJarvis('{"title":"'+ jarvis.title +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message":" ' + batteryMinCount + ' Geräte mit schwacher Batterie","display": "drawer"}');
472
+ } catch (e) {
473
+ this.log.warn ('Getting error at sending notification' + (e));
474
+ }
475
+ }
476
+ if (pushover.instance) {
477
+ try {
478
+ await sendPushover('Batteriezustände: ' + infotext);
479
+ } catch (e) {
480
+ this.log.warn ('Getting error at sending notification' + (e));
481
+ }
482
+ }
483
+ if (telegram.instance) {
484
+ try {
485
+ await sendTelegram('Batteriezuständ: ' + infotext);
486
+ } catch (e) {
487
+ this.log.warn ('Getting error at sending notification' + (e));
488
+ }
489
+ }
490
+ await this.setStateAsync('info.lastBatteryNotification', true, true);
491
+ }
492
+ }
493
+ }
494
+ } catch (e) {
495
+ this.log.debug('Getting error at batterynotification ' + e);
496
+ }
497
+ }
498
+
499
+
500
+ /*===== End of Section notifications ======*/
501
+
502
+
503
+ /*=============================================
504
+ = Write Datapoints =
505
+ =============================================*/
506
+ this.log.debug('write the datapoints ' + this.main.name);
507
+
508
+ try {
509
+ await this.setStateAsync('offlineCount', {val: offlineDevicesCount, ack: true});
510
+ await this.setStateAsync('countAll', {val: deviceCounter, ack: true});
511
+ await this.setStateAsync('batteryCount', {val: batteryPoweredCount, ack: true});
512
+ await this.setStateAsync('lowBatteryCount', {val: lowBatteryPoweredCount, ack: true});
513
+
514
+ if (deviceCounter == 0) {
515
+ jsonLinkQualityDevices = [{Device: '--keine--', Adapter: '', Link_quality: ''}]; //JSON-Info alle mit LinkQuality
516
+ arrListAllDevices = [{Device: '--keine--', Adapter: '', Battery: '', Last_contact: '', Link_quality: ''}]; //JSON-Info Gesamtliste mit Info je Gerät
517
+
518
+ await this.setStateAsync('linkQualityList', {val: JSON.stringify(jsonLinkQualityDevices), ack: true});
519
+ await this.setStateAsync('listAll', {val: JSON.stringify(arrListAllDevices), ack: true});
520
+ } else {
521
+ await this.setStateAsync('linkQualityList', {val: JSON.stringify(jsonLinkQualityDevices), ack: true});
522
+ await this.setStateAsync('listAll', {val: JSON.stringify(arrListAllDevices), ack: true});
523
+ }
524
+
525
+ if (offlineDevicesCount == 0) {
526
+ arrOfflineDevices = [{Device: '--keine--', Adapter: '', Last_contact: ''}]; //JSON-Info alle offline-Geräte = 0
527
+
528
+ await this.setStateAsync('offlineList', {val: JSON.stringify(arrOfflineDevices), ack: true});
529
+ } else {
530
+ await this.setStateAsync('offlineList', {val: JSON.stringify(arrOfflineDevices), ack: true});
531
+ }
532
+
533
+ if (batteryPoweredCount == 0) {
534
+ arrBatteryPowered = [{Device: '--keine--', Adapter: '', Battery: ''}]; //JSON-Info alle batteriebetriebenen Geräte
535
+
536
+ await this.setStateAsync('batteryList', {val: JSON.stringify(arrBatteryPowered), ack: true});
537
+ } else {
538
+ await this.setStateAsync('batteryList', {val: JSON.stringify(arrBatteryPowered), ack: true});
539
+ }
540
+
541
+ if (lowBatteryPoweredCount == 0) {
542
+ arrBatteryLowPowered = [{Device: '--keine--', Adapter: '', Battery: ''}]; //JSON-Info alle batteriebetriebenen Geräte
543
+
544
+ await this.setStateAsync('lowBatteryList', {val: JSON.stringify(arrBatteryLowPowered), ack: true});
545
+ } else {
546
+ await this.setStateAsync('lowBatteryList', {val: JSON.stringify(arrBatteryLowPowered), ack: true});
547
+ }
548
+
549
+ //Zeitstempel wann die Datenpunkte zuletzt gecheckt wurden
550
+ const lastCheck = this.formatDate(new Date(), 'DD.MM.YYYY') + ' - ' + this.formatDate(new Date(), 'hh:mm:ss');
551
+ await this.setStateAsync('lastCheck', lastCheck, true);
552
+
553
+ this.log.debug('write the datapoints finished ' + this.main.name);
554
+ }
555
+ catch (e) {
556
+ this.log.error('(05) Error while writing the states ' + e);
557
+ }
558
+ /*===== End of writing Datapoints ======*/
559
+
560
+ this.log.debug('Function finished: ' + this.main.name);
561
+ }
562
+
563
+ onUnload(callback) {
564
+ try {
565
+ this.log.info('cleaned everything up...');
566
+ callback();
567
+ } catch (e) {
568
+ callback();
569
+ }
570
+ }
571
+ }
572
+
573
+ if (require.main !== module) {
574
+ // Export the constructor in compact mode
575
+ /**
576
+ * @param {Partial<utils.AdapterOptions>} [options={}]
577
+ */
578
+ module.exports = (options) => new DeviceWatcher(options);
579
+ } else {
580
+ // otherwise start the instance directly
581
+ new DeviceWatcher();
582
+ }
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "iobroker.device-watcher",
3
+ "version": "0.0.6",
4
+ "description": "Watchdog for wireless devices",
5
+ "author": "Christian Behrends <mail@christian-behrends.de>",
6
+ "homepage": "https://github.com/ciddi89/ioBroker.device-watcher",
7
+ "license": "MIT",
8
+ "keywords": [
9
+ "watchdog",
10
+ "devices",
11
+ "wireless",
12
+ "watcher"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+ssh://git@github.com/ciddi89/ioBroker.device-watcher.git"
17
+ },
18
+ "dependencies": {
19
+ "@iobroker/adapter-core": "^2.6.0"
20
+ },
21
+ "devDependencies": {
22
+ "@alcalzone/release-script": "^3.5.9",
23
+ "@iobroker/adapter-dev": "^1.0.0",
24
+ "@iobroker/testing": "^3.0.2",
25
+ "@types/chai": "^4.3.1",
26
+ "@types/chai-as-promised": "^7.1.5",
27
+ "@types/mocha": "^9.1.1",
28
+ "@types/node": "^17.0.38",
29
+ "@types/proxyquire": "^1.3.28",
30
+ "@types/sinon": "^10.0.11",
31
+ "@types/sinon-chai": "^3.2.8",
32
+ "chai": "^4.3.6",
33
+ "chai-as-promised": "^7.1.1",
34
+ "eslint": "^8.16.0",
35
+ "mocha": "^10.0.0",
36
+ "proxyquire": "^2.1.3",
37
+ "sinon": "^14.0.0",
38
+ "sinon-chai": "^3.7.0",
39
+ "typescript": "~4.7.2"
40
+ },
41
+ "main": "main.js",
42
+ "files": [
43
+ "admin{,/!(src)/**}/!(tsconfig|tsconfig.*).json",
44
+ "admin{,/!(src)/**}/*.{html,css,png,svg,jpg,js}",
45
+ "lib/",
46
+ "www/",
47
+ "io-package.json",
48
+ "LICENSE",
49
+ "main.js"
50
+ ],
51
+ "scripts": {
52
+ "test:js": "mocha --config test/mocharc.custom.json \"{!(node_modules|test)/**/*.test.js,*.test.js,test/**/test!(PackageFiles|Startup).js}\"",
53
+ "test:package": "mocha test/package --exit",
54
+ "test:unit": "mocha test/unit --exit",
55
+ "test:integration": "mocha test/integration --exit",
56
+ "test": "npm run test:js && npm run test:package",
57
+ "check": "tsc --noEmit -p tsconfig.check.json",
58
+ "lint": "eslint",
59
+ "translate": "translate-adapter",
60
+ "release": "release-script"
61
+ },
62
+ "bugs": {
63
+ "url": "https://github.com/ciddi89/ioBroker.device-watcher/issues"
64
+ },
65
+ "directories": {
66
+ "lib": "lib",
67
+ "test": "test"
68
+ }
69
+ }