iobroker.device-watcher 1.0.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -2
- package/admin/i18n/de/translations.json +8 -1
- package/admin/i18n/en/translations.json +7 -1
- package/admin/i18n/es/translations.json +8 -1
- package/admin/i18n/fr/translations.json +8 -1
- package/admin/i18n/it/translations.json +8 -1
- package/admin/i18n/nl/translations.json +8 -1
- package/admin/i18n/pl/translations.json +8 -1
- package/admin/i18n/pt/translations.json +8 -1
- package/admin/i18n/ru/translations.json +8 -1
- package/admin/i18n/zh-cn/translations.json +8 -1
- package/admin/images/add_blacklist.png +0 -0
- package/admin/jsonConfig.json +220 -29
- package/io-package.json +47 -83
- package/lib/arrApart.js +297 -0
- package/main.js +727 -1189
- package/package.json +11 -9
package/main.js
CHANGED
|
@@ -6,10 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
const utils = require('@iobroker/adapter-core');
|
|
8
8
|
const adapterName = require('./package.json').name.split('.').pop();
|
|
9
|
+
const schedule = require('node-schedule');
|
|
10
|
+
const arrApart = require('./lib/arrApart.js'); // list of supported adapters
|
|
9
11
|
|
|
10
12
|
// Sentry error reporting, disable when testing code!
|
|
11
13
|
const enableSendSentry = true;
|
|
12
14
|
|
|
15
|
+
// indicator if the adapter is running or not (for intervall/shedule)
|
|
13
16
|
let isUnloaded = false;
|
|
14
17
|
|
|
15
18
|
class DeviceWatcher extends utils.Adapter {
|
|
@@ -27,7 +30,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
27
30
|
this.batteryPowered = [];
|
|
28
31
|
this.batteryLowPowered = [];
|
|
29
32
|
this.listAllDevices = [];
|
|
30
|
-
this.
|
|
33
|
+
this.listAllDevicesRaw = [];
|
|
34
|
+
this.blacklistLists = [];
|
|
35
|
+
this.blacklistNotify = [];
|
|
31
36
|
this.arrDev = [];
|
|
32
37
|
this.adapterSelected = [];
|
|
33
38
|
|
|
@@ -38,284 +43,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
38
43
|
this.batteryPoweredCount = 0;
|
|
39
44
|
this.lowBatteryPoweredCount = 0;
|
|
40
45
|
|
|
41
|
-
this.deviceReachable = '';
|
|
42
|
-
|
|
43
46
|
// Interval timer
|
|
44
47
|
this.refreshDataTimeout = null;
|
|
45
48
|
|
|
46
|
-
// Information for dev: add ' 0_userdata.0. ' to selector for testing with own datapoints.
|
|
47
|
-
/*
|
|
48
|
-
This is the main template:
|
|
49
|
-
'Selektor': '',
|
|
50
|
-
'adapter': '',
|
|
51
|
-
'battery': 'none',
|
|
52
|
-
'reach': 'none',
|
|
53
|
-
'isLowBat': 'none',
|
|
54
|
-
'id': 'none''
|
|
55
|
-
*/
|
|
56
|
-
|
|
57
|
-
// arrays of supported adapters
|
|
58
|
-
this.arrApart = {
|
|
59
|
-
alexa2: {
|
|
60
|
-
'Selektor': 'alexa2.*.online',
|
|
61
|
-
'adapter': 'alexa2',
|
|
62
|
-
'battery': 'none',
|
|
63
|
-
'reach': '.online',
|
|
64
|
-
'isLowBat': 'none'
|
|
65
|
-
},
|
|
66
|
-
ble: {
|
|
67
|
-
'Selektor': 'ble.*.rssi',
|
|
68
|
-
'adapter': 'ble',
|
|
69
|
-
'battery': '.battery',
|
|
70
|
-
'reach': 'none',
|
|
71
|
-
'isLowBat': 'none'
|
|
72
|
-
},
|
|
73
|
-
deconz: {
|
|
74
|
-
'Selektor': 'deconz.*.reachable',
|
|
75
|
-
'adapter': 'deconz',
|
|
76
|
-
'battery': '.battery',
|
|
77
|
-
'reach': '.reachable',
|
|
78
|
-
'isLowBat': 'none'
|
|
79
|
-
},
|
|
80
|
-
enocean: {
|
|
81
|
-
'Selektor': 'enocean.*.rssi',
|
|
82
|
-
'adapter': 'enocean',
|
|
83
|
-
'battery': '.BS',
|
|
84
|
-
'reach': 'none',
|
|
85
|
-
'isLowBat': 'none'
|
|
86
|
-
},
|
|
87
|
-
esphome: {
|
|
88
|
-
'Selektor': 'esphome.*._online',
|
|
89
|
-
'adapter': 'esphome',
|
|
90
|
-
'battery': 'none',
|
|
91
|
-
'reach': '._online',
|
|
92
|
-
'isLowBat': 'none',
|
|
93
|
-
'id': '.name'
|
|
94
|
-
},
|
|
95
|
-
fritzdect: {
|
|
96
|
-
'Selektor': 'fritzdect.*.present',
|
|
97
|
-
'adapter': 'fritzDect',
|
|
98
|
-
'battery': '.battery',
|
|
99
|
-
'reach': '.present',
|
|
100
|
-
'isLowBat': '.batterylow'
|
|
101
|
-
},
|
|
102
|
-
harmony: {
|
|
103
|
-
'Selektor': 'harmony.*.hubConnected',
|
|
104
|
-
'adapter': 'harmony',
|
|
105
|
-
'battery': 'none',
|
|
106
|
-
'reach': '.hubConnected',
|
|
107
|
-
'isLowBat': 'none'
|
|
108
|
-
},
|
|
109
|
-
ham: {
|
|
110
|
-
'Selektor': 'ham.*.Battery-Level',
|
|
111
|
-
'adapter': 'ham',
|
|
112
|
-
'battery': '.Battery-Level',
|
|
113
|
-
'reach': 'none',
|
|
114
|
-
'isLowBat': 'none',
|
|
115
|
-
'id': '.Name'
|
|
116
|
-
},
|
|
117
|
-
hmiP: {
|
|
118
|
-
'Selektor': 'hmip.*.rssiDeviceValue',
|
|
119
|
-
'adapter': 'hmiP',
|
|
120
|
-
'rssiState': '.rssiDeviceValue',
|
|
121
|
-
'battery': 'none',
|
|
122
|
-
'reach': '.unreach',
|
|
123
|
-
'isLowBat': '.lowBat',
|
|
124
|
-
},
|
|
125
|
-
homematic: {
|
|
126
|
-
'Selektor': 'hm-rpc.*.UNREACH',
|
|
127
|
-
'adapter': 'homematic',
|
|
128
|
-
'rssiState': '.RSSI_DEVICE',
|
|
129
|
-
'battery': '.OPERATING_VOLTAGE',
|
|
130
|
-
'reach': '.UNREACH',
|
|
131
|
-
'isLowBat': '.LOW_BAT',
|
|
132
|
-
'isLowBat2': '.LOWBAT',
|
|
133
|
-
'stateValue': '.1.STATE'
|
|
134
|
-
},
|
|
135
|
-
hue: {
|
|
136
|
-
'Selektor': 'hue.*.reachable',
|
|
137
|
-
'adapter': 'hue',
|
|
138
|
-
'battery': '.battery',
|
|
139
|
-
'reach': '.reachable',
|
|
140
|
-
'isLowBat': 'none'
|
|
141
|
-
},
|
|
142
|
-
hueExt: {
|
|
143
|
-
'Selektor': 'hue-extended.*.reachable',
|
|
144
|
-
'adapter': 'hue-extended',
|
|
145
|
-
'battery': '.config.battery',
|
|
146
|
-
'reach': '.reachable',
|
|
147
|
-
'isLowBat': 'none'
|
|
148
|
-
},
|
|
149
|
-
jeelink: {
|
|
150
|
-
'Selektor': 'jeelink.*.lowBatt',
|
|
151
|
-
'adapter': 'jeelink',
|
|
152
|
-
'battery': 'none',
|
|
153
|
-
'reach': 'none',
|
|
154
|
-
'isLowBat': '.lowBatt'
|
|
155
|
-
},
|
|
156
|
-
meross: {
|
|
157
|
-
'Selektor': 'meross.*.online',
|
|
158
|
-
'adapter': 'meross',
|
|
159
|
-
'battery': '.battery',
|
|
160
|
-
'reach': '.online',
|
|
161
|
-
'isLowBat': 'none'
|
|
162
|
-
},
|
|
163
|
-
mihome: {
|
|
164
|
-
'Selektor': 'mihome.*.percent',
|
|
165
|
-
'adapter': 'miHome',
|
|
166
|
-
'battery': '.percent',
|
|
167
|
-
'reach': 'none',
|
|
168
|
-
'isLowBat': 'none'
|
|
169
|
-
},
|
|
170
|
-
mihomeGW: {
|
|
171
|
-
'Selektor': 'mihome.*.connected',
|
|
172
|
-
'adapter': 'miHome',
|
|
173
|
-
'battery': 'none',
|
|
174
|
-
'reach': '.connected',
|
|
175
|
-
'isLowBat': 'none'
|
|
176
|
-
},
|
|
177
|
-
mihomeVacuum: {
|
|
178
|
-
'Selektor': 'mihome-vacuum.*.connection',
|
|
179
|
-
'adapter': 'mihomeVacuum',
|
|
180
|
-
'rssiState': '.deviceInfo.wifi_signal',
|
|
181
|
-
'battery': '.info.battery',
|
|
182
|
-
'battery2': '.control.battary_life',
|
|
183
|
-
'reach': '.info.connection',
|
|
184
|
-
'isLowBat': 'none',
|
|
185
|
-
'id': '.deviceInfo.model'
|
|
186
|
-
},
|
|
187
|
-
netatmo: {
|
|
188
|
-
'Selektor': 'netatmo.*.LastUpdate',
|
|
189
|
-
'adapter': 'netatmo',
|
|
190
|
-
'rssiState': '.WifiStatus',
|
|
191
|
-
'rfState': '.RfStatus',
|
|
192
|
-
'battery': '.BatteryStatus',
|
|
193
|
-
'reach': 'none',
|
|
194
|
-
'isLowBat': 'none'
|
|
195
|
-
},
|
|
196
|
-
nukiExt: {
|
|
197
|
-
'Selektor': 'nuki-extended.*.lastDataUpdate',
|
|
198
|
-
'adapter': 'nuki-extended',
|
|
199
|
-
'rssiState': 'none',
|
|
200
|
-
'battery': '.batteryChargeState',
|
|
201
|
-
'reach': 'none',
|
|
202
|
-
'isLowBat': '.batteryCritical'
|
|
203
|
-
},
|
|
204
|
-
nut: {
|
|
205
|
-
'Selektor': 'nut.*.charge',
|
|
206
|
-
'adapter': 'nut',
|
|
207
|
-
'battery': '.charge',
|
|
208
|
-
'reach': 'none',
|
|
209
|
-
'isLowBat': 'none'
|
|
210
|
-
},
|
|
211
|
-
ping: {
|
|
212
|
-
'Selektor': 'ping.*.alive',
|
|
213
|
-
'adapter': 'ping',
|
|
214
|
-
'battery': 'none',
|
|
215
|
-
'reach': '.alive',
|
|
216
|
-
'isLowBat': 'none'
|
|
217
|
-
},
|
|
218
|
-
roomba: {
|
|
219
|
-
'Selektor': 'roomba.*.signal',
|
|
220
|
-
'adapter': 'roomba',
|
|
221
|
-
'battery': '.battery',
|
|
222
|
-
'reach': '._connected',
|
|
223
|
-
'isLowBat': 'none',
|
|
224
|
-
'id': '.device.name'
|
|
225
|
-
},
|
|
226
|
-
shelly: {
|
|
227
|
-
'Selektor': 'shelly.*.online',
|
|
228
|
-
'adapter': 'shelly',
|
|
229
|
-
'rssiState': '.rssi',
|
|
230
|
-
'battery': '.sensor.battery',
|
|
231
|
-
'reach': '.online',
|
|
232
|
-
'isLowBat': 'none'
|
|
233
|
-
},
|
|
234
|
-
sonoff: {
|
|
235
|
-
'Selektor': 'sonoff.*.alive',
|
|
236
|
-
'adapter': 'sonoff',
|
|
237
|
-
'rssiState': '.Wifi_Signal',
|
|
238
|
-
'battery': '.battery',
|
|
239
|
-
'reach': '.alive',
|
|
240
|
-
'isLowBat': 'none'
|
|
241
|
-
},
|
|
242
|
-
sonos: {
|
|
243
|
-
'Selektor': 'sonos.*.alive',
|
|
244
|
-
'adapter': 'sonos',
|
|
245
|
-
'battery': 'none',
|
|
246
|
-
'reach': '.alive',
|
|
247
|
-
'isLowBat': 'none'
|
|
248
|
-
},
|
|
249
|
-
switchbotBle: {
|
|
250
|
-
'Selektor': 'switchbot-ble.*.rssi',
|
|
251
|
-
'adapter': 'switchbotBle',
|
|
252
|
-
'battery': '.battery',
|
|
253
|
-
'reach': 'none',
|
|
254
|
-
'isLowBat': 'none',
|
|
255
|
-
'id': '.id'
|
|
256
|
-
},
|
|
257
|
-
tado: {
|
|
258
|
-
'Selektor': 'tado.*.batteryState',
|
|
259
|
-
'adapter': 'tado',
|
|
260
|
-
'rssiState': 'none',
|
|
261
|
-
'battery': 'none',
|
|
262
|
-
'reach': '.connectionState.value',
|
|
263
|
-
'isLowBat': '.batteryState',
|
|
264
|
-
'id': 'none'
|
|
265
|
-
},
|
|
266
|
-
tradfri: {
|
|
267
|
-
'Selektor': 'tradfri.*.lastSeen',
|
|
268
|
-
'adapter': 'tradfri',
|
|
269
|
-
'rssiState': 'none',
|
|
270
|
-
'battery': '.batteryPercentage',
|
|
271
|
-
'reach': '.alive',
|
|
272
|
-
'isLowBat': 'none',
|
|
273
|
-
'id': 'none'
|
|
274
|
-
},
|
|
275
|
-
unifi: {
|
|
276
|
-
'Selektor': 'unifi.*.state',
|
|
277
|
-
'adapter': 'unifi',
|
|
278
|
-
'battery': 'none',
|
|
279
|
-
'reach': '.state',
|
|
280
|
-
'isLowBat': 'none',
|
|
281
|
-
'id': 'none'
|
|
282
|
-
},
|
|
283
|
-
wled: {
|
|
284
|
-
'Selektor': 'wled.*._online',
|
|
285
|
-
'adapter': 'wled',
|
|
286
|
-
'rssiState': '.wifi.rssi',
|
|
287
|
-
'battery': 'none',
|
|
288
|
-
'reach': '._online',
|
|
289
|
-
'isLowBat': 'none',
|
|
290
|
-
'id': 'none'
|
|
291
|
-
},
|
|
292
|
-
yeelight: {
|
|
293
|
-
'Selektor': 'yeelight-2.*.connect',
|
|
294
|
-
'adapter': 'yeelight-2',
|
|
295
|
-
'battery': 'none',
|
|
296
|
-
'reach': '.connect',
|
|
297
|
-
'isLowBat': 'none'
|
|
298
|
-
},
|
|
299
|
-
zigbee: {
|
|
300
|
-
'Selektor': 'zigbee.*.link_quality',
|
|
301
|
-
'adapter': 'zigbee',
|
|
302
|
-
'battery': '.battery',
|
|
303
|
-
'reach': '.available',
|
|
304
|
-
'isLowBat': '.battery_low'
|
|
305
|
-
},
|
|
306
|
-
zwave: {
|
|
307
|
-
'Selektor': 'zwave2.*.ready',
|
|
308
|
-
'adapter': 'zwave',
|
|
309
|
-
'battery': '.Battery.level',
|
|
310
|
-
'reach': '.ready',
|
|
311
|
-
'isLowBat': '.Battery.isLow'
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
|
|
315
49
|
this.on('ready', this.onReady.bind(this));
|
|
316
|
-
|
|
50
|
+
this.on('stateChange', this.onStateChange.bind(this));
|
|
317
51
|
// this.on('objectChange', this.onObjectChange.bind(this));
|
|
318
|
-
|
|
52
|
+
this.on('message', this.onMessage.bind(this));
|
|
319
53
|
this.on('unload', this.onUnload.bind(this));
|
|
320
54
|
|
|
321
55
|
}
|
|
@@ -326,6 +60,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
326
60
|
isUnloaded = false;
|
|
327
61
|
|
|
328
62
|
try {
|
|
63
|
+
this.listOnlyBattery = this.config.listOnlyBattery;
|
|
64
|
+
|
|
329
65
|
this.supAdapter = {
|
|
330
66
|
alexa2: this.config.alexa2Devices,
|
|
331
67
|
ble: this.config.bleDevices,
|
|
@@ -336,10 +72,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
336
72
|
ham: this.config.hamDevices,
|
|
337
73
|
harmony: this.config.harmonyDevices,
|
|
338
74
|
hmiP : this.config.hmiPDevices,
|
|
339
|
-
|
|
75
|
+
hmrpc: this.config.hmrpcDevices,
|
|
76
|
+
hs100: this.config.hs100Devices,
|
|
340
77
|
hue: this.config.hueDevices,
|
|
341
78
|
hueExt: this.config.hueExtDevices,
|
|
342
79
|
jeelink: this.config.jeelinkDevices,
|
|
80
|
+
lupusec: this.config.lupusecDevices,
|
|
81
|
+
maxcube: this.config.maxcubeDevices,
|
|
343
82
|
meross: this.config.merossDevices,
|
|
344
83
|
mihome: this.config.mihomeDevices,
|
|
345
84
|
mihomeGW: this.config.mihomeDevices,
|
|
@@ -359,13 +98,54 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
359
98
|
wled: this.config.wledDevices,
|
|
360
99
|
yeelight: this.config.yeelightDevices,
|
|
361
100
|
zigbee: this.config.zigbeeDevices,
|
|
101
|
+
zigbee2MQTT: this.config.zigbee2mqttDevices,
|
|
362
102
|
zwave: this.config.zwaveDevices,
|
|
363
103
|
};
|
|
364
104
|
|
|
365
|
-
|
|
105
|
+
this.maxMinutes = {
|
|
106
|
+
alexa2: this.config.alexa2MaxMinutes,
|
|
107
|
+
ble: this.config.bleMaxMinutes,
|
|
108
|
+
deconz: this.config.deconzMaxMinutes,
|
|
109
|
+
enocean: this.config.enoceanMaxMinutes,
|
|
110
|
+
esphome: this.config.esphomeMaxMinutes,
|
|
111
|
+
fritzdect: this.config.fritzdectMaxMinutes,
|
|
112
|
+
ham: this.config.hamMaxMinutes,
|
|
113
|
+
harmony: this.config.harmonyMaxMinutes,
|
|
114
|
+
hmiP : this.config.hmiPMaxMinutes,
|
|
115
|
+
hmrpc: this.config.hmrpcMaxMinutes,
|
|
116
|
+
hs100: this.config.hs100MaxMinutes,
|
|
117
|
+
hue: this.config.hueMaxMinutes,
|
|
118
|
+
hueExt: this.config.hueextMaxMinutes,
|
|
119
|
+
jeelink: this.config.jeelinkMaxMinutes,
|
|
120
|
+
lupusec: this.config.lupusecMaxMinutes,
|
|
121
|
+
maxcube: this.config.maxcubeMaxMinutes,
|
|
122
|
+
meross: this.config.merossMaxMinutes,
|
|
123
|
+
mihome: this.config.mihomeMaxMinutes,
|
|
124
|
+
mihomeGW: this.config.mihomeMaxMinutes,
|
|
125
|
+
mihomeVacuum: this.config.mihomeVacuumMaxMinutes,
|
|
126
|
+
netatmo: this.config.netatmoMaxMinutes,
|
|
127
|
+
nukiExt: this.config.nukiextendMaxMinutes,
|
|
128
|
+
nut: this.config.nutMaxMinutes,
|
|
129
|
+
ping: this.config.pingMaxMinutes,
|
|
130
|
+
roomba: this.config.roombaMaxMinutes,
|
|
131
|
+
shelly: this.config.shellyMaxMinutes,
|
|
132
|
+
sonoff: this.config.sonoffMaxMinutes,
|
|
133
|
+
sonos: this.config.sonosMaxMinutes,
|
|
134
|
+
switchbotBle: this.config.switchbotMaxMinutes,
|
|
135
|
+
tado: this.config.tadoMaxMinutes,
|
|
136
|
+
tradfri: this.config.tradfriMaxMinutes,
|
|
137
|
+
unifi: this.config.unifiMaxMinutes,
|
|
138
|
+
wled: this.config.wledMaxMinutes,
|
|
139
|
+
yeelight: this.config.yeelightMaxMinutes,
|
|
140
|
+
zigbee: this.config.zigbeeMaxMinutes,
|
|
141
|
+
zigbee2MQTT: this.config.zigbee2mqttMaxMinutes,
|
|
142
|
+
zwave: this.config.zwaveMaxMinutes,
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
for (const [id] of Object.entries(arrApart)) {
|
|
366
146
|
if (!isUnloaded) {
|
|
367
147
|
if (this.supAdapter[id]) {
|
|
368
|
-
this.arrDev.push(
|
|
148
|
+
this.arrDev.push(arrApart[id]);
|
|
369
149
|
this.adapterSelected.push(await this.capitalize(id));
|
|
370
150
|
}
|
|
371
151
|
} else {
|
|
@@ -393,7 +173,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
393
173
|
|
|
394
174
|
//create and fill datapoints for each adapter if selected
|
|
395
175
|
try {
|
|
396
|
-
for (const [id] of Object.entries(
|
|
176
|
+
for (const [id] of Object.entries(arrApart)) {
|
|
397
177
|
if (!isUnloaded) {
|
|
398
178
|
if ((this.supAdapter !== undefined) && (this.supAdapter[id])) {
|
|
399
179
|
|
|
@@ -417,12 +197,65 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
417
197
|
// update data in interval
|
|
418
198
|
await this.refreshData();
|
|
419
199
|
|
|
200
|
+
// send overview for low battery devices
|
|
201
|
+
if (this.config.checkSendBatteryMsg) await this.sendBatteryNotifyShedule();
|
|
202
|
+
|
|
203
|
+
// send overview of offline devices
|
|
204
|
+
if (this.config.checkSendOfflineMsgDaily) await this.sendOfflineNotificationsShedule();
|
|
205
|
+
|
|
420
206
|
} catch (error) {
|
|
421
207
|
this.errorReporting('[onReady]', error);
|
|
422
208
|
this.terminate ? this.terminate(15) : process.exit(15);
|
|
423
209
|
}
|
|
424
210
|
} // <-- onReady end
|
|
425
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Is called if a subscribed state changes
|
|
214
|
+
* @param {string} id
|
|
215
|
+
* @param {ioBroker.State | null | undefined} state
|
|
216
|
+
*/
|
|
217
|
+
onStateChange(id, state) {
|
|
218
|
+
if (state) {
|
|
219
|
+
// The state was changed
|
|
220
|
+
this.log.warn(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
|
|
221
|
+
} else {
|
|
222
|
+
// The state was deleted
|
|
223
|
+
this.log.warn(`state ${id} deleted`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @param {ioBroker.Message} obj
|
|
229
|
+
*/
|
|
230
|
+
onMessage(obj) {
|
|
231
|
+
const devices = [];
|
|
232
|
+
let myCount = 0;
|
|
233
|
+
let result;
|
|
234
|
+
|
|
235
|
+
switch (obj.command) {
|
|
236
|
+
case 'devicesList':
|
|
237
|
+
if(obj.message){
|
|
238
|
+
try{
|
|
239
|
+
result = this.listAllDevicesRaw;
|
|
240
|
+
for(const element in result){
|
|
241
|
+
const label = 'Device: ' + result[element].Device + ' - Adapter: ' + result[element].Adapter;
|
|
242
|
+
const myValueObject = {deviceName: result[element].Device, adapter: result[element].Adapter, path: result[element].Path};
|
|
243
|
+
devices[myCount] = {label: label,value: JSON.stringify(myValueObject)};
|
|
244
|
+
myCount ++;
|
|
245
|
+
}
|
|
246
|
+
this.sendTo(obj.from, obj.command, devices, obj.callback);
|
|
247
|
+
}
|
|
248
|
+
catch(error){
|
|
249
|
+
this.sendTo(obj.from, obj.command, obj.callback);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else{
|
|
253
|
+
this.sendTo(obj.from, obj.command, obj.callback);
|
|
254
|
+
}
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
426
259
|
async refreshData() {
|
|
427
260
|
const nextTimeout = this.config.updateinterval * 1000;
|
|
428
261
|
|
|
@@ -433,7 +266,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
433
266
|
this.log.debug('clearing old refresh timeout');
|
|
434
267
|
this.clearTimeout(this.refreshDataTimeout);
|
|
435
268
|
}
|
|
436
|
-
|
|
437
269
|
if (!isUnloaded) {
|
|
438
270
|
this.refreshDataTimeout = this.setTimeout(() => {
|
|
439
271
|
this.log.debug('Updating Data');
|
|
@@ -450,38 +282,31 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
450
282
|
async main() {
|
|
451
283
|
this.log.debug(`Function started: ${this.main.name}`);
|
|
452
284
|
|
|
285
|
+
// fill datapoints for each adapter if selected
|
|
453
286
|
try {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
if (this.config.createOwnFolder) {
|
|
461
|
-
await this.createDataForEachAdapter(id);
|
|
462
|
-
this.log.debug(`Created and filled data for each adapter`);
|
|
463
|
-
}
|
|
287
|
+
for (const [id] of Object.entries(arrApart)) {
|
|
288
|
+
if (!isUnloaded) {
|
|
289
|
+
if ((this.supAdapter !== undefined) && (this.supAdapter[id])) {
|
|
290
|
+
if (this.config.createOwnFolder) {
|
|
291
|
+
await this.createDataForEachAdapter(id);
|
|
292
|
+
this.log.debug(`Created and filled data for ${await this.capitalize(id)}`);
|
|
464
293
|
}
|
|
465
|
-
} else {
|
|
466
|
-
this.log.warn('broke up');
|
|
467
|
-
return; // cancel run if unloaded was called.
|
|
468
294
|
}
|
|
295
|
+
} else {
|
|
296
|
+
this.log.warn('broke up');
|
|
297
|
+
return; // cancel run if unloaded was called.
|
|
469
298
|
}
|
|
470
|
-
|
|
471
|
-
} catch (error) {
|
|
472
|
-
this.errorReporting('[main - create and fill datapoints for each adapter]', error);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// fill counts and lists of all selected adapter
|
|
476
|
-
try {
|
|
477
|
-
await this.createDataOfAllAdapter();
|
|
478
|
-
this.log.debug(`Created and filled data for all adapters`);
|
|
479
|
-
} catch (error) {
|
|
480
|
-
this.errorReporting('[main - create data of all adapter]', error);
|
|
481
299
|
}
|
|
300
|
+
} catch (error) {
|
|
301
|
+
this.errorReporting('[main - create and fill datapoints for each adapter]', error);
|
|
302
|
+
}
|
|
482
303
|
|
|
304
|
+
// fill counts and lists of all selected adapter
|
|
305
|
+
try {
|
|
306
|
+
await this.createDataOfAllAdapter();
|
|
307
|
+
this.log.debug(`Created and filled data for all adapters`);
|
|
483
308
|
} catch (error) {
|
|
484
|
-
this.errorReporting('[main]', error);
|
|
309
|
+
this.errorReporting('[main - create data of all adapter]', error);
|
|
485
310
|
}
|
|
486
311
|
|
|
487
312
|
this.log.debug(`Function finished: ${this.main.name}`);
|
|
@@ -490,15 +315,23 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
490
315
|
|
|
491
316
|
/**
|
|
492
317
|
* @param {string} sentence - Word which should be capitalize
|
|
493
|
-
|
|
318
|
+
*/
|
|
494
319
|
async capitalize(sentence) {
|
|
495
320
|
//make the first letter uppercase
|
|
496
321
|
return sentence && sentence[0].toUpperCase() + sentence.slice(1);
|
|
497
322
|
}
|
|
498
323
|
|
|
324
|
+
/**
|
|
325
|
+
* @param {number} dpValue - get Time of this datapoint
|
|
326
|
+
*/
|
|
327
|
+
async getTimestamp(dpValue) {
|
|
328
|
+
const time = new Date();
|
|
329
|
+
return dpValue = Math.round((time.getTime() - dpValue) / 1000 / 60);
|
|
330
|
+
}
|
|
331
|
+
|
|
499
332
|
/**
|
|
500
333
|
* @param {object} obj - State of datapoint
|
|
501
|
-
|
|
334
|
+
*/
|
|
502
335
|
async getInitValue(obj) {
|
|
503
336
|
//state can be null or undefinded
|
|
504
337
|
const foreignState = await this.getForeignStateAsync(obj);
|
|
@@ -507,7 +340,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
507
340
|
|
|
508
341
|
/**
|
|
509
342
|
* @param {object} obj - State of own datapoint
|
|
510
|
-
|
|
343
|
+
*/
|
|
511
344
|
async getOwnInitValue(obj) {
|
|
512
345
|
//state can be null or undefinded for own states
|
|
513
346
|
const stateVal = await this.getStateAsync(obj);
|
|
@@ -517,874 +350,578 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
517
350
|
async createBlacklist() {
|
|
518
351
|
this.log.debug(`Function started: ${this.createBlacklist.name}`);
|
|
519
352
|
|
|
520
|
-
|
|
353
|
+
if (!isUnloaded) {
|
|
354
|
+
const myBlacklist = this.config.tableBlacklist;
|
|
521
355
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
356
|
+
for (const i in myBlacklist) {
|
|
357
|
+
const blacklistParse = JSON.parse(myBlacklist[i].devices);
|
|
358
|
+
// push devices in list to ignor device in lists
|
|
359
|
+
if (myBlacklist[i].checkIgnorLists) {
|
|
360
|
+
this.blacklistLists.push(blacklistParse.path);
|
|
361
|
+
}
|
|
362
|
+
// push devices in list to ignor device in notifications
|
|
363
|
+
if (myBlacklist[i].checkIgnorNotify) {
|
|
364
|
+
this.blacklistNotify.push(blacklistParse.deviceName);
|
|
365
|
+
}
|
|
527
366
|
}
|
|
367
|
+
|
|
368
|
+
if (this.blacklistLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistLists}`);
|
|
369
|
+
if (this.blacklistNotify.length >= 1) this.log.info(`Found items on blacklist for notificatioons: ${this.blacklistNotify}`);
|
|
370
|
+
} else {
|
|
371
|
+
return; // cancel run if unloaded was called.
|
|
528
372
|
}
|
|
529
|
-
|
|
373
|
+
|
|
530
374
|
this.log.debug(`Function finished: ${this.createBlacklist.name}`);
|
|
531
375
|
}
|
|
532
376
|
|
|
533
377
|
/**
|
|
534
|
-
* @param {object}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
case 'nuki-extended':
|
|
566
|
-
case 'wled':
|
|
567
|
-
if (shortDeviceObject && typeof shortDeviceObject === 'object') {
|
|
568
|
-
deviceName = shortDeviceObject.common.name;
|
|
569
|
-
}
|
|
570
|
-
break;
|
|
571
|
-
|
|
572
|
-
// Get ID with short short currDeviceString vom objectjson
|
|
573
|
-
case 'hmiP':
|
|
574
|
-
if (shortshortDeviceObject && typeof shortshortDeviceObject === 'object') {
|
|
575
|
-
deviceName = shortshortDeviceObject.common.name;
|
|
576
|
-
}
|
|
577
|
-
break;
|
|
578
|
-
|
|
579
|
-
// Get ID with short currDeviceString from datapoint
|
|
580
|
-
case 'mihomeVacuum':
|
|
581
|
-
case 'roomba':
|
|
582
|
-
deviceName = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].id);
|
|
583
|
-
break;
|
|
584
|
-
|
|
585
|
-
//Get ID of foldername
|
|
586
|
-
case 'tado':
|
|
587
|
-
deviceName = currDeviceString.slice(currDeviceString.lastIndexOf('.') + 1);
|
|
588
|
-
break;
|
|
589
|
-
|
|
590
|
-
//Get ID of foldername
|
|
591
|
-
case 'yeelight-2':
|
|
592
|
-
deviceName = shortCurrDeviceString.slice(shortCurrDeviceString.lastIndexOf('.') + 1);
|
|
593
|
-
break;
|
|
378
|
+
* @param {object} id - deviceID
|
|
379
|
+
* @param {object} i - each Device
|
|
380
|
+
*/
|
|
381
|
+
async getDeviceName(id, i) {
|
|
382
|
+
const currDeviceString = id.slice(0, (id.lastIndexOf('.') + 1) - 1);
|
|
383
|
+
const shortCurrDeviceString = currDeviceString.slice(0, (currDeviceString.lastIndexOf('.') + 1) - 1);
|
|
384
|
+
const shortshortCurrDeviceString = shortCurrDeviceString.slice(0, (shortCurrDeviceString.lastIndexOf('.') + 1) - 1);
|
|
385
|
+
|
|
386
|
+
// Get device name
|
|
387
|
+
const deviceObject = await this.getForeignObjectAsync(currDeviceString);
|
|
388
|
+
const shortDeviceObject = await this.getForeignObjectAsync(shortCurrDeviceString);
|
|
389
|
+
const shortshortDeviceObject = await this.getForeignObjectAsync(shortshortCurrDeviceString);
|
|
390
|
+
let deviceName;
|
|
391
|
+
|
|
392
|
+
// Get ID with currDeviceString from datapoint
|
|
393
|
+
switch (this.arrDev[i].adapter) {
|
|
394
|
+
// Get ID for Switchbot and ESPHome Devices
|
|
395
|
+
case 'switchbotBle':
|
|
396
|
+
case 'esphome':
|
|
397
|
+
deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
|
|
398
|
+
break;
|
|
399
|
+
|
|
400
|
+
// Get ID with short currDeviceString from objectjson
|
|
401
|
+
case 'hue-extended':
|
|
402
|
+
case 'hmrpc':
|
|
403
|
+
case 'nuki-extended':
|
|
404
|
+
case 'wled':
|
|
405
|
+
if (shortDeviceObject && typeof shortDeviceObject === 'object') {
|
|
406
|
+
deviceName = shortDeviceObject.common.name;
|
|
407
|
+
}
|
|
408
|
+
break;
|
|
594
409
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
410
|
+
// Get ID with short short currDeviceString from objectjson (HMiP Devices)
|
|
411
|
+
case 'hmiP':
|
|
412
|
+
if (shortshortDeviceObject && typeof shortshortDeviceObject === 'object') {
|
|
413
|
+
deviceName = shortshortDeviceObject.common.name;
|
|
414
|
+
}
|
|
415
|
+
break;
|
|
416
|
+
|
|
417
|
+
// Get ID with short currDeviceString from datapoint
|
|
418
|
+
case 'mihomeVacuum':
|
|
419
|
+
case 'roomba':
|
|
420
|
+
deviceName = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].id);
|
|
421
|
+
break;
|
|
422
|
+
|
|
423
|
+
//Get ID of foldername
|
|
424
|
+
case 'tado':
|
|
425
|
+
deviceName = currDeviceString.slice(currDeviceString.lastIndexOf('.') + 1);
|
|
426
|
+
break;
|
|
427
|
+
|
|
428
|
+
//Get ID of foldername
|
|
429
|
+
case 'yeelight-2':
|
|
430
|
+
deviceName = shortCurrDeviceString.slice(shortCurrDeviceString.lastIndexOf('.') + 1);
|
|
431
|
+
break;
|
|
432
|
+
|
|
433
|
+
// Get ID with main selektor from objectjson
|
|
434
|
+
default:
|
|
435
|
+
if (deviceObject && typeof deviceObject === 'object') {
|
|
436
|
+
if (deviceObject.common.name['de'] != undefined) {
|
|
437
|
+
deviceName = deviceObject.common.name['de'];
|
|
438
|
+
} else if (deviceObject.common.name['en'] != undefined) {
|
|
439
|
+
deviceName = deviceObject.common.name['en'];
|
|
440
|
+
} else {
|
|
441
|
+
deviceName = deviceObject.common.name;
|
|
601
442
|
}
|
|
443
|
+
}
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
446
|
+
return deviceName;
|
|
447
|
+
}
|
|
602
448
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
let deviceQualityState;
|
|
613
|
-
let linkQuality;
|
|
614
|
-
|
|
615
|
-
switch (this.arrDev[i].adapter) {
|
|
616
|
-
case 'sonoff':
|
|
617
|
-
case 'hmiP':
|
|
618
|
-
case 'homematic':
|
|
619
|
-
case 'wled':
|
|
620
|
-
case 'shelly':
|
|
621
|
-
deviceQualityState = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rssiState);
|
|
622
|
-
break;
|
|
449
|
+
/**
|
|
450
|
+
* Create Lists
|
|
451
|
+
*/
|
|
452
|
+
async createLists() {
|
|
453
|
+
this.linkQualityDevices = [];
|
|
454
|
+
this.batteryPowered = [];
|
|
455
|
+
this.batteryLowPowered = [];
|
|
456
|
+
this.listAllDevices = [];
|
|
457
|
+
this.offlineDevices = [];
|
|
623
458
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
459
|
+
for (const device of this.listAllDevicesRaw) {
|
|
460
|
+
if (!this.blacklistLists.includes(device['Path'])) {
|
|
461
|
+
this.listAllDevices.push(
|
|
462
|
+
{
|
|
463
|
+
'Device': device['Device'],
|
|
464
|
+
'Adapter': device['Adapter'],
|
|
465
|
+
'Battery': device['Battery'],
|
|
466
|
+
'Signal strength': device['Signal strength'],
|
|
467
|
+
'Last contact': device['Last contact'],
|
|
468
|
+
'Status': device['Status']
|
|
469
|
+
}
|
|
470
|
+
);
|
|
471
|
+
// LinkQuality lists
|
|
472
|
+
if (device['Signal strength'] != ' - ') {
|
|
473
|
+
this.linkQualityDevices.push(
|
|
474
|
+
{
|
|
475
|
+
'Device': device['Device'],
|
|
476
|
+
'Adapter': device['Adapter'],
|
|
477
|
+
'Signal strength': device['Signal strength']
|
|
478
|
+
}
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
// Battery lists
|
|
482
|
+
if (device['Battery'] != ' - ') {
|
|
483
|
+
this.batteryPowered.push(
|
|
484
|
+
{
|
|
485
|
+
'Device': device['Device'],
|
|
486
|
+
'Adapter': device['Adapter'],
|
|
487
|
+
'Battery': device['Battery']
|
|
488
|
+
}
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
// Low Bat lists
|
|
492
|
+
if (device['LowBat']) {
|
|
493
|
+
this.batteryLowPowered.push(
|
|
494
|
+
{
|
|
495
|
+
'Device': device['Device'],
|
|
496
|
+
'Adapter': device['Adapter'],
|
|
497
|
+
'Battery': device['Battery']
|
|
498
|
+
}
|
|
499
|
+
);
|
|
500
|
+
}
|
|
627
501
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
502
|
+
// Offline List
|
|
503
|
+
if (device['Status'] === 'Offline') {
|
|
504
|
+
this.offlineDevices.push(
|
|
505
|
+
{
|
|
506
|
+
'Device': device['Device'],
|
|
507
|
+
'Adapter': device['Adapter'],
|
|
508
|
+
'Last contact': device['Last contact']
|
|
509
|
+
}
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
636
515
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
516
|
+
/**
|
|
517
|
+
* Count devices for each type
|
|
518
|
+
*/
|
|
519
|
+
async countDevices() {
|
|
520
|
+
// Count how many devices with link Quality
|
|
521
|
+
this.linkQualityCount = this.linkQualityDevices.length;
|
|
643
522
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
break;
|
|
647
|
-
}
|
|
523
|
+
// Count how many devcies are offline
|
|
524
|
+
this.offlineDevicesCount = this.offlineDevices.length;
|
|
648
525
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
linkQuality = deviceQualityState.val;
|
|
652
|
-
} else {
|
|
653
|
-
// If Quality State is already an percent value
|
|
654
|
-
switch (this.arrDev[i].adapter) {
|
|
655
|
-
case 'roomba':
|
|
656
|
-
linkQuality = deviceQualityState.val + '%';
|
|
657
|
-
break;
|
|
526
|
+
// Count how many devices are with battery
|
|
527
|
+
this.batteryPoweredCount = this.batteryPowered.length;
|
|
658
528
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
if (deviceQualityState.val == -255) {
|
|
662
|
-
linkQuality = ' - ';
|
|
663
|
-
} else if (deviceQualityState.val < 0) {
|
|
664
|
-
linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
|
|
529
|
+
// 3d. Count how many devices are with low battery
|
|
530
|
+
this.lowBatteryPoweredCount = this.batteryLowPowered.length;
|
|
665
531
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
}
|
|
670
|
-
break;
|
|
671
|
-
}
|
|
532
|
+
// Count how many devices are exists
|
|
533
|
+
this.deviceCounter = this.listAllDevices.length;
|
|
534
|
+
}
|
|
672
535
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
'Adapter': deviceAdapterName,
|
|
680
|
-
'Signal strength': linkQuality
|
|
681
|
-
}
|
|
682
|
-
);
|
|
683
|
-
}
|
|
684
|
-
} else {
|
|
685
|
-
this.linkQualityDevices.push(
|
|
686
|
-
{
|
|
687
|
-
'Device': deviceName,
|
|
688
|
-
'Adapter': deviceAdapterName,
|
|
689
|
-
'Signal strength': linkQuality
|
|
690
|
-
}
|
|
691
|
-
);
|
|
692
|
-
}
|
|
693
|
-
} else if ((deviceQualityState) && (typeof deviceQualityState.val === 'string')) {
|
|
694
|
-
switch (this.arrDev[i].adapter) {
|
|
695
|
-
case 'netatmo':
|
|
696
|
-
// for Netatmo devices
|
|
697
|
-
linkQuality = deviceQualityState.val;
|
|
698
|
-
break;
|
|
699
|
-
case 'nuki-extended':
|
|
700
|
-
linkQuality = ' - ';
|
|
701
|
-
break;
|
|
702
|
-
}
|
|
536
|
+
/**
|
|
537
|
+
* @param {object} i - Device Object
|
|
538
|
+
*/
|
|
539
|
+
async createData(i) {
|
|
540
|
+
const devices = await this.getForeignStatesAsync(this.arrDev[i].Selektor);
|
|
541
|
+
const deviceAdapterName = await this.capitalize(this.arrDev[i].adapter);
|
|
703
542
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
{
|
|
708
|
-
'Device': deviceName,
|
|
709
|
-
'Adapter': deviceAdapterName,
|
|
710
|
-
'Signal strength': linkQuality
|
|
711
|
-
}
|
|
712
|
-
);
|
|
713
|
-
}
|
|
714
|
-
} else {
|
|
715
|
-
this.linkQualityDevices.push(
|
|
716
|
-
{
|
|
717
|
-
'Device': deviceName,
|
|
718
|
-
'Adapter': deviceAdapterName,
|
|
719
|
-
'Signal strength': linkQuality
|
|
720
|
-
}
|
|
721
|
-
);
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
else {
|
|
725
|
-
linkQuality = ' - '; // no linkQuality available for powered devices
|
|
726
|
-
}
|
|
543
|
+
/*---------- Start of second main loop ----------*/
|
|
544
|
+
for (const [id] of Object.entries(devices)) {
|
|
545
|
+
if (!isUnloaded) {
|
|
727
546
|
|
|
728
|
-
// Count how many devices with link Quality
|
|
729
|
-
this.linkQualityCount = this.linkQualityDevices.length;
|
|
730
547
|
|
|
731
|
-
// When was the last contact to the device?
|
|
732
|
-
let lastContactString;
|
|
733
548
|
|
|
734
|
-
|
|
735
|
-
if (deviceMainSelector) {
|
|
736
|
-
try {
|
|
737
|
-
const time = new Date();
|
|
738
|
-
const lastContact = Math.round((time.getTime() - deviceMainSelector.ts) / 1000 / 60);
|
|
739
|
-
const lastStateChange = Math.round((time.getTime() - deviceMainSelector.lc) / 1000 / 60);
|
|
740
|
-
const deviceUnreachState = await this.getInitValue(currDeviceString + this.arrDev[i].reach);
|
|
741
|
-
const shortDeviceUnreachState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].reach);
|
|
549
|
+
const deviceName = await this.getDeviceName(id, i);
|
|
742
550
|
|
|
551
|
+
const currDeviceString = id.slice(0, (id.lastIndexOf('.') + 1) - 1);
|
|
552
|
+
const shortCurrDeviceString = currDeviceString.slice(0, (currDeviceString.lastIndexOf('.') + 1) - 1);
|
|
743
553
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
}
|
|
749
|
-
if (Math.round(lastContact / 60) > 48) {
|
|
750
|
-
lastContactString = Math.round(lastContact / 60 / 24) + ' Tagen';
|
|
751
|
-
}
|
|
752
|
-
return lastContactString;
|
|
753
|
-
};
|
|
554
|
+
// Get battery states
|
|
555
|
+
const deviceBatteryState = await this.getInitValue(currDeviceString + this.arrDev[i].battery);
|
|
556
|
+
const shortDeviceBatteryState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery);
|
|
557
|
+
const shortDeviceBatteryState2 = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery2);
|
|
754
558
|
|
|
755
|
-
const getLastStateChange = async () => {
|
|
756
|
-
lastContactString = this.formatDate(new Date((deviceMainSelector.lc)), 'hh:mm') + ' Uhr';
|
|
757
|
-
if (Math.round(lastStateChange) > 100) {
|
|
758
|
-
lastContactString = Math.round(lastStateChange / 60) + ' Stunden';
|
|
759
|
-
}
|
|
760
|
-
if (Math.round(lastStateChange / 60) > 48) {
|
|
761
|
-
lastContactString = Math.round(lastStateChange / 60 / 24) + ' Tagen';
|
|
762
|
-
}
|
|
763
|
-
return lastContactString;
|
|
764
|
-
};
|
|
765
559
|
|
|
560
|
+
//this.devices[deviceName] = currDeviceString + this.arrDev[i].reach;
|
|
766
561
|
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
562
|
+
/*for (const [value] of Object.entries(this.devices)) {
|
|
563
|
+
this.log.warn(`${value}`);
|
|
564
|
+
this.subscribeForeignStatesAsync(value);
|
|
565
|
+
}*/
|
|
566
|
+
//this.subscribeForeignStatesAsync(currDeviceString + this.arrDev[i].reach);
|
|
567
|
+
// <--- END TEST
|
|
773
568
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
if (linkQuality != ' - ') {
|
|
778
|
-
if (deviceUnreachState) {
|
|
779
|
-
await getLastStateChange();
|
|
780
|
-
} else {
|
|
781
|
-
await getLastContact();
|
|
782
|
-
}
|
|
783
|
-
} else {
|
|
784
|
-
if (deviceStateSelector) { // because old hm devices don't send rssi states
|
|
785
|
-
const lastContactOfState = Math.round((time.getTime() - deviceStateSelector.ts) / 1000 / 60);
|
|
786
|
-
const getLastContactOfState = async () => {
|
|
787
|
-
lastContactString = this.formatDate(new Date((deviceStateSelector.ts)), 'hh:mm') + ' Uhr';
|
|
788
|
-
if (Math.round(lastContactOfState) > 100) {
|
|
789
|
-
lastContactString = Math.round(lastContactOfState / 60) + ' Stunden';
|
|
790
|
-
}
|
|
791
|
-
if (Math.round(lastContactOfState / 60) > 48) {
|
|
792
|
-
lastContactString = Math.round(lastContactOfState / 60 / 24) + ' Tagen';
|
|
793
|
-
}
|
|
794
|
-
return lastContactString;
|
|
795
|
-
};
|
|
796
|
-
await getLastContactOfState();
|
|
797
|
-
}
|
|
798
|
-
}
|
|
569
|
+
// Get link quality
|
|
570
|
+
let deviceQualityState;
|
|
571
|
+
let linkQuality;
|
|
799
572
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
await getLastContact();
|
|
805
|
-
}
|
|
806
|
-
break;
|
|
807
|
-
}
|
|
808
|
-
}
|
|
573
|
+
switch (this.arrDev[i].adapter) {
|
|
574
|
+
case 'mihomeVacuum':
|
|
575
|
+
deviceQualityState = await this.getForeignStateAsync(shortCurrDeviceString + this.arrDev[i].rssiState);
|
|
576
|
+
break;
|
|
809
577
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
'Adapter': deviceAdapterName,
|
|
817
|
-
'Last contact': lastContactString
|
|
818
|
-
}
|
|
819
|
-
);
|
|
820
|
-
}
|
|
821
|
-
} else {
|
|
822
|
-
this.offlineDevices.push( //else push all devices
|
|
823
|
-
{
|
|
824
|
-
'Device': deviceName,
|
|
825
|
-
'Adapter': deviceAdapterName,
|
|
826
|
-
'Last contact': lastContactString
|
|
827
|
-
}
|
|
828
|
-
);
|
|
829
|
-
}
|
|
830
|
-
};
|
|
578
|
+
case 'netatmo':
|
|
579
|
+
deviceQualityState = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rssiState);
|
|
580
|
+
if (!deviceQualityState) {
|
|
581
|
+
deviceQualityState = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rfState);
|
|
582
|
+
}
|
|
583
|
+
break;
|
|
831
584
|
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
} else if (lastContact > this.config.deconzMaxMinutes) {
|
|
862
|
-
deviceState = 'Offline'; //set online state to offline
|
|
863
|
-
await pushOfflineDevice();
|
|
864
|
-
}
|
|
865
|
-
break;
|
|
866
|
-
case 'enocean':
|
|
867
|
-
if (this.config.enoceanMaxMinutes === -1) {
|
|
868
|
-
if (!deviceUnreachState) {
|
|
869
|
-
deviceState = 'Offline'; //set online state to offline
|
|
870
|
-
await pushOfflineDevice();
|
|
871
|
-
}
|
|
872
|
-
} else if (lastContact > this.config.enoceanMaxMinutes) {
|
|
873
|
-
deviceState = 'Offline'; //set online state to offline
|
|
874
|
-
await pushOfflineDevice();
|
|
875
|
-
}
|
|
876
|
-
break;
|
|
877
|
-
case 'esphome':
|
|
878
|
-
if (this.config.esphomeMaxMinutes === -1) {
|
|
879
|
-
if (!deviceUnreachState) {
|
|
880
|
-
deviceState = 'Offline'; //set online state to offline
|
|
881
|
-
await pushOfflineDevice();
|
|
882
|
-
}
|
|
883
|
-
} else if (lastContact > this.config.esphomeMaxMinutes) {
|
|
884
|
-
deviceState = 'Offline'; //set online state to offline
|
|
885
|
-
await pushOfflineDevice();
|
|
886
|
-
}
|
|
887
|
-
break;
|
|
888
|
-
case 'fritzDect':
|
|
889
|
-
if (this.config.fritzdectMaxMinutes === -1) {
|
|
890
|
-
if (!deviceUnreachState) {
|
|
891
|
-
deviceState = 'Offline'; //set online state to offline
|
|
892
|
-
await pushOfflineDevice();
|
|
893
|
-
}
|
|
894
|
-
} else if (lastContact > this.config.fritzdectMaxMinutes) {
|
|
895
|
-
deviceState = 'Offline'; //set online state to offline
|
|
896
|
-
await pushOfflineDevice();
|
|
897
|
-
}
|
|
898
|
-
break;
|
|
899
|
-
case 'harmony':
|
|
900
|
-
if (this.config.harmonyMaxMinutes === -1) {
|
|
901
|
-
if (!deviceUnreachState) {
|
|
902
|
-
deviceState = 'Offline'; //set online state to offline
|
|
903
|
-
await pushOfflineDevice();
|
|
904
|
-
}
|
|
905
|
-
} else if (lastContact > this.config.harmonyMaxMinutes) {
|
|
906
|
-
deviceState = 'Offline'; //set online state to offline
|
|
907
|
-
await pushOfflineDevice();
|
|
908
|
-
}
|
|
909
|
-
break;
|
|
910
|
-
case 'ham':
|
|
911
|
-
if (this.config.hamMaxMinutes === -1) {
|
|
912
|
-
if (!deviceUnreachState) {
|
|
913
|
-
deviceState = 'Offline'; //set online state to offline
|
|
914
|
-
await pushOfflineDevice();
|
|
915
|
-
}
|
|
916
|
-
} else if (lastContact > this.config.hamMaxMinutes) {
|
|
917
|
-
deviceState = 'Offline'; //set online state to offline
|
|
918
|
-
await pushOfflineDevice();
|
|
919
|
-
}
|
|
920
|
-
break;
|
|
921
|
-
case 'hmiP':
|
|
922
|
-
if (this.config.hmiPMaxMinutes === -1) {
|
|
923
|
-
if (deviceUnreachState) {
|
|
924
|
-
deviceState = 'Offline'; //set online state to offline
|
|
925
|
-
await pushOfflineDevice();
|
|
926
|
-
}
|
|
927
|
-
} else if (lastContact > this.config.hmiPMaxMinutes) {
|
|
928
|
-
deviceState = 'Offline'; //set online state to offline
|
|
929
|
-
await pushOfflineDevice();
|
|
930
|
-
}
|
|
931
|
-
break;
|
|
932
|
-
case 'homematic':
|
|
933
|
-
if (this.config.homematicMaxMinutes === -1) {
|
|
934
|
-
if (deviceUnreachState) {
|
|
935
|
-
deviceState = 'Offline'; //set online state to offline
|
|
936
|
-
await pushOfflineDevice();
|
|
937
|
-
}
|
|
938
|
-
} else if (lastContact > this.config.homematicMaxMinutes) {
|
|
939
|
-
deviceState = 'Offline'; //set online state to offline
|
|
940
|
-
await pushOfflineDevice();
|
|
941
|
-
}
|
|
942
|
-
break;
|
|
943
|
-
case 'hue':
|
|
944
|
-
if (this.config.hueMaxMinutes === -1) {
|
|
945
|
-
if (!deviceUnreachState) {
|
|
946
|
-
deviceState = 'Offline'; //set online state to offline
|
|
947
|
-
await pushOfflineDevice();
|
|
948
|
-
}
|
|
949
|
-
} else if (lastContact > this.config.hueMaxMinutes) {
|
|
950
|
-
deviceState = 'Offline'; //set online state to offline
|
|
951
|
-
await pushOfflineDevice();
|
|
952
|
-
}
|
|
953
|
-
break;
|
|
954
|
-
case 'hue-extended':
|
|
955
|
-
if (this.config.hueextMaxMinutes === -1) {
|
|
956
|
-
if (!deviceUnreachState) {
|
|
957
|
-
deviceState = 'Offline'; //set online state to offline
|
|
958
|
-
await pushOfflineDevice();
|
|
959
|
-
}
|
|
960
|
-
} else if (lastContact > this.config.hueextMaxMinutes) {
|
|
961
|
-
deviceState = 'Offline'; //set online state to offline
|
|
962
|
-
await pushOfflineDevice();
|
|
963
|
-
}
|
|
964
|
-
break;
|
|
965
|
-
case 'jeelink':
|
|
966
|
-
if (this.config.jeelinkMaxMinutes === -1) {
|
|
967
|
-
if (!deviceUnreachState) {
|
|
968
|
-
deviceState = 'Offline'; //set online state to offline
|
|
969
|
-
await pushOfflineDevice();
|
|
970
|
-
}
|
|
971
|
-
} else if (lastContact > this.config.jeelinkMaxMinutes) {
|
|
972
|
-
deviceState = 'Offline'; //set online state to offline
|
|
973
|
-
await pushOfflineDevice();
|
|
974
|
-
}
|
|
975
|
-
break;
|
|
976
|
-
case 'meross':
|
|
977
|
-
if (this.config.merossMaxMinutes === -1) {
|
|
978
|
-
if (!deviceUnreachState) {
|
|
979
|
-
deviceState = 'Offline'; //set online state to offline
|
|
980
|
-
await pushOfflineDevice();
|
|
981
|
-
}
|
|
982
|
-
} else if (lastContact > this.config.merossMaxMinutes) {
|
|
983
|
-
deviceState = 'Offline'; //set online state to offline
|
|
984
|
-
await pushOfflineDevice();
|
|
985
|
-
}
|
|
986
|
-
break;
|
|
987
|
-
case 'miHome':
|
|
988
|
-
if (this.config.mihomeMaxMinutes === -1) {
|
|
989
|
-
if (!deviceUnreachState) {
|
|
990
|
-
deviceState = 'Offline'; //set online state to offline
|
|
991
|
-
await pushOfflineDevice();
|
|
992
|
-
}
|
|
993
|
-
} else if (lastContact > this.config.mihomeMaxMinutes) {
|
|
994
|
-
deviceState = 'Offline'; //set online state to offline
|
|
995
|
-
await pushOfflineDevice();
|
|
996
|
-
}
|
|
997
|
-
break;
|
|
998
|
-
case 'mihomeVacuum':
|
|
999
|
-
if (this.config.mihomeVacuumMaxMinutes === -1) {
|
|
1000
|
-
if (!shortDeviceUnreachState) {
|
|
1001
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1002
|
-
await pushOfflineDevice();
|
|
585
|
+
default:
|
|
586
|
+
deviceQualityState = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rssiState);
|
|
587
|
+
break;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
if (deviceQualityState != null) {
|
|
591
|
+
switch (typeof deviceQualityState.val) {
|
|
592
|
+
case 'number':
|
|
593
|
+
if (this.config.trueState) {
|
|
594
|
+
linkQuality = deviceQualityState.val;
|
|
595
|
+
} else {
|
|
596
|
+
switch (this.arrDev[i].adapter) {
|
|
597
|
+
case 'roomba':
|
|
598
|
+
case 'sonoff':
|
|
599
|
+
linkQuality = deviceQualityState.val + '%'; // If quality state is already an percent value
|
|
600
|
+
break;
|
|
601
|
+
case 'lupusec':
|
|
602
|
+
linkQuality = deviceQualityState.val;
|
|
603
|
+
break;
|
|
604
|
+
|
|
605
|
+
default:
|
|
606
|
+
// If quality state is an RSSI value calculate in percent:
|
|
607
|
+
if (deviceQualityState.val == -255) {
|
|
608
|
+
linkQuality = ' - ';
|
|
609
|
+
} else if (deviceQualityState.val < 0) {
|
|
610
|
+
linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
|
|
611
|
+
// If Quality State is an value between 0-255 (zigbee) calculate in percent:
|
|
612
|
+
} else if ((deviceQualityState.val) >= 0) {
|
|
613
|
+
linkQuality = parseFloat((100 / 255 * deviceQualityState.val).toFixed(0)) + '%';
|
|
1003
614
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
break;
|
|
619
|
+
|
|
620
|
+
case 'string':
|
|
621
|
+
switch (this.arrDev[i].adapter) {
|
|
1009
622
|
case 'netatmo':
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1013
|
-
await pushOfflineDevice();
|
|
1014
|
-
}
|
|
1015
|
-
} else if (lastContact > this.config.netatmoMaxMinutes) {
|
|
1016
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1017
|
-
await pushOfflineDevice();
|
|
1018
|
-
}
|
|
623
|
+
// for Netatmo devices
|
|
624
|
+
linkQuality = deviceQualityState.val;
|
|
1019
625
|
break;
|
|
1020
626
|
case 'nuki-extended':
|
|
1021
|
-
|
|
1022
|
-
if (!deviceUnreachState) {
|
|
1023
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1024
|
-
await pushOfflineDevice();
|
|
1025
|
-
}
|
|
1026
|
-
} else if (lastContact > this.config.nukiextendMaxMinutes) {
|
|
1027
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1028
|
-
await pushOfflineDevice();
|
|
1029
|
-
}
|
|
1030
|
-
break;
|
|
1031
|
-
case 'nut':
|
|
1032
|
-
if (this.config.nutMaxMinutes === -1) {
|
|
1033
|
-
if (!deviceUnreachState) {
|
|
1034
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1035
|
-
await pushOfflineDevice();
|
|
1036
|
-
}
|
|
1037
|
-
} else if (lastContact > this.config.nutMaxMinutes) {
|
|
1038
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1039
|
-
await pushOfflineDevice();
|
|
1040
|
-
}
|
|
1041
|
-
break;
|
|
1042
|
-
case 'ping':
|
|
1043
|
-
if (this.config.pingMaxMinutes === -1) {
|
|
1044
|
-
if (!deviceUnreachState) {
|
|
1045
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1046
|
-
await pushOfflineDevice();
|
|
1047
|
-
}
|
|
1048
|
-
} else if ((lastStateChange > this.config.pingMaxMinutes) && (!deviceUnreachState)) {
|
|
1049
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1050
|
-
await pushOfflineDevice();
|
|
1051
|
-
}
|
|
1052
|
-
break;
|
|
1053
|
-
case 'roomba':
|
|
1054
|
-
if (this.config.roombaMaxMinutes === -1) {
|
|
1055
|
-
if (!deviceUnreachState) {
|
|
1056
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1057
|
-
await pushOfflineDevice();
|
|
1058
|
-
}
|
|
1059
|
-
} else if (lastContact > this.config.roombaMaxMinutes) {
|
|
1060
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1061
|
-
await pushOfflineDevice();
|
|
1062
|
-
}
|
|
627
|
+
linkQuality = ' - ';
|
|
1063
628
|
break;
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
629
|
+
}
|
|
630
|
+
break;
|
|
631
|
+
}
|
|
632
|
+
} else {
|
|
633
|
+
linkQuality = ' - ';
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// When was the last contact to the device?
|
|
637
|
+
let lastContactString;
|
|
638
|
+
let deviceState = 'Online';
|
|
639
|
+
let lastDeviceUnreachStateChange;
|
|
640
|
+
|
|
641
|
+
const deviceMainSelector = await this.getForeignStateAsync(id);
|
|
642
|
+
const deviceStateSelector = await this.getForeignStateAsync(shortCurrDeviceString + this.arrDev[i].stateValue); // for hmrpc devices
|
|
643
|
+
const rssiPeerSelector = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rssiPeerState);
|
|
644
|
+
|
|
645
|
+
if (deviceMainSelector) {
|
|
646
|
+
try {
|
|
647
|
+
const lastContact = await this.getTimestamp(deviceMainSelector.ts);
|
|
648
|
+
const lastStateChange = await this.getTimestamp(deviceMainSelector.lc);
|
|
649
|
+
const deviceUnreachState = await this.getInitValue(currDeviceString + this.arrDev[i].reach);
|
|
650
|
+
const deviceUnreachSelector = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].reach);
|
|
651
|
+
if (deviceUnreachSelector) {lastDeviceUnreachStateChange = await this.getTimestamp(deviceUnreachSelector.lc);}
|
|
652
|
+
const shortDeviceUnreachState = await this.getForeignStateAsync(shortCurrDeviceString + this.arrDev[i].reach);
|
|
653
|
+
|
|
654
|
+
const getLastContact = async () => {
|
|
655
|
+
lastContactString = this.formatDate(new Date((deviceMainSelector.ts)), 'hh:mm') + ' Uhr';
|
|
656
|
+
if (Math.round(lastContact) > 100) {
|
|
657
|
+
lastContactString = Math.round(lastContact / 60) + ' Stunden';
|
|
658
|
+
}
|
|
659
|
+
if (Math.round(lastContact / 60) > 48) {
|
|
660
|
+
lastContactString = Math.round(lastContact / 60 / 24) + ' Tagen';
|
|
661
|
+
}
|
|
662
|
+
return lastContactString;
|
|
663
|
+
};
|
|
664
|
+
|
|
665
|
+
const getLastStateChange = async () => {
|
|
666
|
+
lastContactString = this.formatDate(new Date((deviceMainSelector.lc)), 'hh:mm') + ' Uhr';
|
|
667
|
+
if (Math.round(lastStateChange) > 100) {
|
|
668
|
+
lastContactString = Math.round(lastStateChange / 60) + ' Stunden';
|
|
669
|
+
}
|
|
670
|
+
if (Math.round(lastStateChange / 60) > 48) {
|
|
671
|
+
lastContactString = Math.round(lastStateChange / 60 / 24) + ' Tagen';
|
|
672
|
+
}
|
|
673
|
+
return lastContactString;
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
// If there is no contact since user sets minutes add device in offline list
|
|
677
|
+
// calculate to days after 48 hours
|
|
678
|
+
switch (this.arrDev[i].reach) {
|
|
679
|
+
case 'none':
|
|
680
|
+
await getLastContact();
|
|
681
|
+
break;
|
|
682
|
+
|
|
683
|
+
default:
|
|
684
|
+
//State changed
|
|
685
|
+
if (this.arrDev[i].adapter === 'hmrpc') {
|
|
686
|
+
if (linkQuality != ' - ') {
|
|
687
|
+
if (deviceUnreachState) {
|
|
688
|
+
await getLastStateChange();
|
|
689
|
+
} else {
|
|
690
|
+
await getLastContact();
|
|
1069
691
|
}
|
|
1070
|
-
} else
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
692
|
+
} else {
|
|
693
|
+
if (deviceStateSelector) { // because old hm devices don't send rssi states
|
|
694
|
+
const lastContactOfState = await this.getTimestamp(deviceStateSelector.ts);
|
|
695
|
+
const getLastContactOfState = async () => {
|
|
696
|
+
lastContactString = this.formatDate(new Date((deviceStateSelector.ts)), 'hh:mm') + ' Uhr';
|
|
697
|
+
if (Math.round(lastContactOfState) > 100) {
|
|
698
|
+
lastContactString = Math.round(lastContactOfState / 60) + ' Stunden';
|
|
699
|
+
}
|
|
700
|
+
if (Math.round(lastContactOfState / 60) > 48) {
|
|
701
|
+
lastContactString = Math.round(lastContactOfState / 60 / 24) + ' Tagen';
|
|
702
|
+
}
|
|
703
|
+
return lastContactString;
|
|
704
|
+
};
|
|
705
|
+
await getLastContactOfState();
|
|
706
|
+
} else if (rssiPeerSelector) { // because old hm sensors don't send rssi/state values
|
|
707
|
+
const lastContactOfState = await this.getTimestamp(rssiPeerSelector.ts);
|
|
708
|
+
const getLastContactOfState = async () => {
|
|
709
|
+
lastContactString = this.formatDate(new Date((rssiPeerSelector.ts)), 'hh:mm') + ' Uhr';
|
|
710
|
+
if (Math.round(lastContactOfState) > 100) {
|
|
711
|
+
lastContactString = Math.round(lastContactOfState / 60) + ' Stunden';
|
|
712
|
+
}
|
|
713
|
+
if (Math.round(lastContactOfState / 60) > 48) {
|
|
714
|
+
lastContactString = Math.round(lastContactOfState / 60 / 24) + ' Tagen';
|
|
715
|
+
}
|
|
716
|
+
return lastContactString;
|
|
717
|
+
};
|
|
718
|
+
await getLastContactOfState();
|
|
1080
719
|
}
|
|
1081
|
-
} else if (lastContact > this.config.sonoffMaxMinutes) {
|
|
1082
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1083
|
-
await pushOfflineDevice();
|
|
1084
720
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
if (
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
}
|
|
1092
|
-
} else if (lastContact > this.config.sonosMaxMinutes) {
|
|
1093
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1094
|
-
await pushOfflineDevice();
|
|
721
|
+
|
|
722
|
+
} else {
|
|
723
|
+
if (!deviceUnreachState) {
|
|
724
|
+
await getLastStateChange();
|
|
725
|
+
} else {
|
|
726
|
+
await getLastContact();
|
|
1095
727
|
}
|
|
1096
728
|
break;
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
const adapterID = this.arrDev[i].adapter;
|
|
733
|
+
|
|
734
|
+
switch (adapterID) {
|
|
735
|
+
case 'hmrpc':
|
|
736
|
+
case 'hmiP':
|
|
737
|
+
case 'maxcube':
|
|
738
|
+
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
739
|
+
if (deviceUnreachState) {
|
|
1104
740
|
deviceState = 'Offline'; //set online state to offline
|
|
1105
|
-
await pushOfflineDevice();
|
|
1106
741
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
} else if (lastContact > this.config.tadoMaxMinutes) {
|
|
742
|
+
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
743
|
+
deviceState = 'Offline'; //set online state to offline
|
|
744
|
+
}
|
|
745
|
+
break;
|
|
746
|
+
case 'ping':
|
|
747
|
+
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
748
|
+
if (!deviceUnreachState) {
|
|
1115
749
|
deviceState = 'Offline'; //set online state to offline
|
|
1116
|
-
await pushOfflineDevice();
|
|
1117
750
|
}
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
} else if (lastContact > this.config.tradfriMaxMinutes) {
|
|
751
|
+
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID]) && (!deviceUnreachState)) {
|
|
752
|
+
deviceState = 'Offline'; //set online state to offline
|
|
753
|
+
}
|
|
754
|
+
break;
|
|
755
|
+
case 'unifi':
|
|
756
|
+
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
757
|
+
if (deviceUnreachState === 0) {
|
|
1126
758
|
deviceState = 'Offline'; //set online state to offline
|
|
1127
|
-
await pushOfflineDevice();
|
|
1128
759
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
760
|
+
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
761
|
+
deviceState = 'Offline'; //set online state to offline
|
|
762
|
+
|
|
763
|
+
}
|
|
764
|
+
break;
|
|
765
|
+
case 'shelly':
|
|
766
|
+
case 'sonoff':
|
|
767
|
+
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
768
|
+
if (!deviceUnreachState) {
|
|
1137
769
|
deviceState = 'Offline'; //set online state to offline
|
|
1138
|
-
await pushOfflineDevice();
|
|
1139
770
|
}
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
} else if (lastContact > this.config.wledMaxMinutes) {
|
|
771
|
+
} else if ((!deviceUnreachState) && (typeof lastDeviceUnreachStateChange !== 'undefined') && (this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
772
|
+
deviceState = 'Offline'; //set online state to offline
|
|
773
|
+
}
|
|
774
|
+
break;
|
|
775
|
+
case 'mihomeVacuum':
|
|
776
|
+
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
777
|
+
if (!shortDeviceUnreachState) {
|
|
1148
778
|
deviceState = 'Offline'; //set online state to offline
|
|
1149
|
-
await pushOfflineDevice();
|
|
1150
779
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
780
|
+
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
781
|
+
deviceState = 'Offline'; //set online state to offline
|
|
782
|
+
}
|
|
783
|
+
break;
|
|
784
|
+
case 'miHome':
|
|
785
|
+
if (this.arrDev[i].battery === 'none') {
|
|
786
|
+
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
1154
787
|
if (!deviceUnreachState) {
|
|
1155
788
|
deviceState = 'Offline'; //set online state to offline
|
|
1156
|
-
await pushOfflineDevice();
|
|
1157
789
|
}
|
|
1158
|
-
} else if (lastContact > this.
|
|
790
|
+
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
1159
791
|
deviceState = 'Offline'; //set online state to offline
|
|
1160
|
-
await pushOfflineDevice();
|
|
1161
792
|
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
if (!deviceUnreachState) {
|
|
793
|
+
} else {
|
|
794
|
+
if (this.config.mihomeMaxMinutes === -1) {
|
|
795
|
+
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
1166
796
|
deviceState = 'Offline'; //set online state to offline
|
|
1167
|
-
await pushOfflineDevice();
|
|
1168
797
|
}
|
|
1169
|
-
} else if (lastContact > this.
|
|
798
|
+
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
1170
799
|
deviceState = 'Offline'; //set online state to offline
|
|
1171
|
-
await pushOfflineDevice();
|
|
1172
800
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
}
|
|
1180
|
-
} else if (lastContact > this.config.zwaveMaxMinutes) {
|
|
1181
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1182
|
-
await pushOfflineDevice();
|
|
801
|
+
}
|
|
802
|
+
break;
|
|
803
|
+
default:
|
|
804
|
+
if ((this.maxMinutes !== undefined) && (this.maxMinutes[adapterID] === -1)) {
|
|
805
|
+
if (!deviceUnreachState) {
|
|
806
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1183
807
|
}
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
808
|
+
} else if ((this.maxMinutes !== undefined) && (lastContact > this.maxMinutes[adapterID])) {
|
|
809
|
+
deviceState = 'Offline'; //set online state to offline
|
|
810
|
+
}
|
|
811
|
+
break;
|
|
1188
812
|
}
|
|
813
|
+
} catch (error) {
|
|
814
|
+
this.errorReporting('[getLastContact]', error);
|
|
1189
815
|
}
|
|
816
|
+
}
|
|
1190
817
|
|
|
818
|
+
// Get battery states
|
|
819
|
+
let batteryHealth;
|
|
820
|
+
let lowBatIndicator;
|
|
821
|
+
let deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat);
|
|
822
|
+
if (deviceLowBatState === undefined) {
|
|
823
|
+
deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat2);
|
|
824
|
+
}
|
|
1191
825
|
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
let batteryHealth;
|
|
1198
|
-
const deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat);
|
|
1199
|
-
const deviceLowBatStateHM = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat2);
|
|
1200
|
-
|
|
1201
|
-
if ((!deviceBatteryState) && (!shortDeviceBatteryState) && (!shortDeviceBatteryState2)) {
|
|
1202
|
-
if ((deviceLowBatState !== undefined) || (deviceLowBatState !== undefined) || (deviceLowBatStateHM !== undefined)) {
|
|
1203
|
-
switch (this.arrDev[i].isLowBat) {
|
|
1204
|
-
case 'none':
|
|
1205
|
-
batteryHealth = ' - ';
|
|
1206
|
-
break;
|
|
1207
|
-
default:
|
|
1208
|
-
if ((!deviceLowBatState) || (deviceLowBatState == 'NORMAL')) {
|
|
1209
|
-
batteryHealth = 'ok';
|
|
1210
|
-
} else {
|
|
1211
|
-
batteryHealth = 'low';
|
|
1212
|
-
}
|
|
1213
|
-
break;
|
|
1214
|
-
}
|
|
1215
|
-
switch (this.arrDev[i].isLowBat2) {
|
|
1216
|
-
case 'none':
|
|
1217
|
-
batteryHealth = ' - ';
|
|
1218
|
-
break;
|
|
1219
|
-
default:
|
|
1220
|
-
if ((!deviceLowBatState) || (deviceLowBatState == 'NORMAL')) {
|
|
1221
|
-
batteryHealth = 'ok';
|
|
1222
|
-
} else {
|
|
1223
|
-
batteryHealth = 'low';
|
|
1224
|
-
}
|
|
1225
|
-
break;
|
|
1226
|
-
}
|
|
1227
|
-
this.batteryPowered.push(
|
|
1228
|
-
{
|
|
1229
|
-
'Device': deviceName,
|
|
1230
|
-
'Adapter': deviceAdapterName,
|
|
1231
|
-
'Battery': batteryHealth
|
|
1232
|
-
}
|
|
1233
|
-
);
|
|
1234
|
-
} else {
|
|
1235
|
-
batteryHealth = ' - ';
|
|
1236
|
-
}
|
|
1237
|
-
} else {
|
|
1238
|
-
switch (this.arrDev[i].adapter) {
|
|
1239
|
-
case 'homematic':
|
|
1240
|
-
if (deviceBatteryState === 0) {
|
|
1241
|
-
batteryHealth = ' - ';
|
|
1242
|
-
} else {
|
|
1243
|
-
batteryHealth = deviceBatteryState + 'V';
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
this.batteryPowered.push(
|
|
1247
|
-
{
|
|
1248
|
-
'Device': deviceName,
|
|
1249
|
-
'Adapter': deviceAdapterName,
|
|
1250
|
-
'Battery': batteryHealth
|
|
1251
|
-
}
|
|
1252
|
-
);
|
|
1253
|
-
break;
|
|
1254
|
-
case 'hue-extended':
|
|
1255
|
-
if (shortDeviceBatteryState) {
|
|
1256
|
-
batteryHealth = shortDeviceBatteryState + '%';
|
|
1257
|
-
this.batteryPowered.push(
|
|
1258
|
-
{
|
|
1259
|
-
'Device': deviceName,
|
|
1260
|
-
'Adapter': deviceAdapterName,
|
|
1261
|
-
'Battery': batteryHealth
|
|
1262
|
-
}
|
|
1263
|
-
);
|
|
1264
|
-
}
|
|
826
|
+
if ((!deviceBatteryState) && (!shortDeviceBatteryState) && (!shortDeviceBatteryState2)) {
|
|
827
|
+
if (deviceLowBatState !== undefined) {
|
|
828
|
+
switch (this.arrDev[i].isLowBat || this.arrDev[i].isLowBat2) {
|
|
829
|
+
case 'none':
|
|
830
|
+
batteryHealth = ' - ';
|
|
1265
831
|
break;
|
|
1266
|
-
|
|
1267
|
-
if (
|
|
1268
|
-
batteryHealth =
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
'Device': deviceName,
|
|
1272
|
-
'Adapter': deviceAdapterName,
|
|
1273
|
-
'Battery': batteryHealth
|
|
1274
|
-
}
|
|
1275
|
-
);
|
|
1276
|
-
} else if (shortDeviceBatteryState2) {
|
|
1277
|
-
batteryHealth = shortDeviceBatteryState2 + '%';
|
|
1278
|
-
this.batteryPowered.push(
|
|
1279
|
-
{
|
|
1280
|
-
'Device': deviceName,
|
|
1281
|
-
'Adapter': deviceAdapterName,
|
|
1282
|
-
'Battery': batteryHealth
|
|
1283
|
-
}
|
|
1284
|
-
);
|
|
832
|
+
default:
|
|
833
|
+
if ((deviceLowBatState === false) || (deviceLowBatState === 'NORMAL') || (deviceLowBatState === 1)) {
|
|
834
|
+
batteryHealth = 'ok';
|
|
835
|
+
} else {
|
|
836
|
+
batteryHealth = 'low';
|
|
1285
837
|
}
|
|
1286
838
|
break;
|
|
1287
|
-
default:
|
|
1288
|
-
batteryHealth = (deviceBatteryState) + '%';
|
|
1289
|
-
this.batteryPowered.push(
|
|
1290
|
-
{
|
|
1291
|
-
'Device': deviceName,
|
|
1292
|
-
'Adapter': deviceAdapterName,
|
|
1293
|
-
'Battery': batteryHealth
|
|
1294
|
-
}
|
|
1295
|
-
);
|
|
1296
839
|
}
|
|
840
|
+
} else {
|
|
841
|
+
batteryHealth = ' - ';
|
|
1297
842
|
}
|
|
1298
|
-
|
|
1299
|
-
// Count how many devices are with battery
|
|
1300
|
-
this.batteryPoweredCount = this.batteryPowered.length;
|
|
1301
|
-
|
|
1302
|
-
// Count how many devices are with low battery
|
|
1303
|
-
const batteryWarningMin = this.config.minWarnBatterie;
|
|
1304
|
-
|
|
1305
|
-
// fill list with low battery devices
|
|
843
|
+
} else {
|
|
1306
844
|
switch (this.arrDev[i].adapter) {
|
|
1307
|
-
case '
|
|
1308
|
-
if (
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
'Adapter': deviceAdapterName,
|
|
1313
|
-
'Battery': batteryHealth
|
|
1314
|
-
}
|
|
1315
|
-
);
|
|
845
|
+
case 'hmrpc':
|
|
846
|
+
if (deviceBatteryState === 0) {
|
|
847
|
+
batteryHealth = ' - ';
|
|
848
|
+
} else {
|
|
849
|
+
batteryHealth = deviceBatteryState + 'V';
|
|
1316
850
|
}
|
|
1317
851
|
break;
|
|
1318
852
|
|
|
1319
|
-
case '
|
|
1320
|
-
if (
|
|
1321
|
-
|
|
1322
|
-
{
|
|
1323
|
-
'Device': deviceName,
|
|
1324
|
-
'Adapter': deviceAdapterName,
|
|
1325
|
-
'Battery': batteryHealth
|
|
1326
|
-
}
|
|
1327
|
-
);
|
|
853
|
+
case 'hue-extended':
|
|
854
|
+
if (shortDeviceBatteryState) {
|
|
855
|
+
batteryHealth = shortDeviceBatteryState + '%';
|
|
1328
856
|
}
|
|
1329
857
|
break;
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
'Device': deviceName,
|
|
1336
|
-
'Adapter': deviceAdapterName,
|
|
1337
|
-
'Battery': batteryHealth
|
|
1338
|
-
}
|
|
1339
|
-
);
|
|
1340
|
-
} else if (deviceBatteryState && (deviceBatteryState < batteryWarningMin)) { // if the battery state is under the set limit
|
|
1341
|
-
this.batteryLowPowered.push(
|
|
1342
|
-
{
|
|
1343
|
-
'Device': deviceName,
|
|
1344
|
-
'Adapter': deviceAdapterName,
|
|
1345
|
-
'Battery': batteryHealth
|
|
1346
|
-
}
|
|
1347
|
-
);
|
|
858
|
+
case 'mihomeVacuum':
|
|
859
|
+
if (shortDeviceBatteryState) {
|
|
860
|
+
batteryHealth = shortDeviceBatteryState + '%';
|
|
861
|
+
} else if (shortDeviceBatteryState2) {
|
|
862
|
+
batteryHealth = shortDeviceBatteryState2 + '%';
|
|
1348
863
|
}
|
|
864
|
+
break;
|
|
865
|
+
default:
|
|
866
|
+
batteryHealth = (deviceBatteryState) + '%';
|
|
1349
867
|
}
|
|
868
|
+
}
|
|
1350
869
|
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
870
|
+
// fill list with low battery devices
|
|
871
|
+
switch (this.arrDev[i].adapter) {
|
|
872
|
+
case 'hmrpc': // there are differnt low bat states between hm and hmIp devices
|
|
873
|
+
if (deviceLowBatState) {
|
|
874
|
+
lowBatIndicator = true;
|
|
875
|
+
}
|
|
876
|
+
break;
|
|
877
|
+
case 'tado': // there is an string as indicator
|
|
878
|
+
if (deviceLowBatState != 'NORMAL') {
|
|
879
|
+
lowBatIndicator = true;
|
|
880
|
+
}
|
|
881
|
+
break;
|
|
882
|
+
|
|
883
|
+
default: // for all other devices with low bat states
|
|
884
|
+
if ((deviceLowBatState === true) || (deviceLowBatState === 0)) {
|
|
885
|
+
lowBatIndicator = true;
|
|
886
|
+
} else if (deviceBatteryState && (deviceBatteryState < this.config.minWarnBatterie)) { // if the battery state is under the set limit
|
|
887
|
+
lowBatIndicator = true;
|
|
1366
888
|
}
|
|
1367
|
-
|
|
1368
|
-
|
|
889
|
+
}
|
|
890
|
+
if (this.listOnlyBattery) { // Add only devices with battery in the list
|
|
891
|
+
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
892
|
+
this.listAllDevicesRaw.push(
|
|
1369
893
|
{
|
|
894
|
+
'Path': id,
|
|
1370
895
|
'Device': deviceName,
|
|
1371
896
|
'Adapter': deviceAdapterName,
|
|
1372
897
|
'Battery': batteryHealth,
|
|
898
|
+
'LowBat': lowBatIndicator,
|
|
1373
899
|
'Signal strength': linkQuality,
|
|
1374
900
|
'Last contact': lastContactString,
|
|
1375
901
|
'Status': deviceState
|
|
1376
902
|
}
|
|
1377
903
|
);
|
|
1378
904
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
905
|
+
} else { // Add all devices
|
|
906
|
+
this.listAllDevicesRaw.push(
|
|
907
|
+
{
|
|
908
|
+
'Path': id,
|
|
909
|
+
'Device': deviceName,
|
|
910
|
+
'Adapter': deviceAdapterName,
|
|
911
|
+
'Battery': batteryHealth,
|
|
912
|
+
'LowBat': lowBatIndicator,
|
|
913
|
+
'Signal strength': linkQuality,
|
|
914
|
+
'Last contact': lastContactString,
|
|
915
|
+
'Status': deviceState
|
|
916
|
+
}
|
|
917
|
+
);
|
|
1383
918
|
}
|
|
1384
919
|
} else {
|
|
1385
920
|
return; // cancel run if unloaded was called.
|
|
1386
921
|
}
|
|
1387
922
|
} // <-- end of loop
|
|
923
|
+
await this.createLists();
|
|
924
|
+
await this.countDevices();
|
|
1388
925
|
} // <-- end of createData
|
|
1389
926
|
|
|
1390
927
|
|
|
@@ -1396,8 +933,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1396
933
|
this.log.debug(`Function started: ${this.createDataForEachAdapter.name}`);
|
|
1397
934
|
|
|
1398
935
|
try {
|
|
1399
|
-
await this.resetVars(); // reset the arrays and counts
|
|
1400
|
-
|
|
1401
936
|
for (let i = 0; i < this.arrDev.length; i++) {
|
|
1402
937
|
|
|
1403
938
|
if (this.arrDev[i].adapter.includes(adptName)) { // list device only if selected adapter matched with device
|
|
@@ -1405,6 +940,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1405
940
|
}
|
|
1406
941
|
}
|
|
1407
942
|
await this.writeDatapoints(adptName); // fill the datapoints
|
|
943
|
+
await this.resetVars(); // reset the arrays and counts
|
|
944
|
+
|
|
1408
945
|
} catch (error) {
|
|
1409
946
|
this.errorReporting('[createDataForEachAdapter]', error);
|
|
1410
947
|
}
|
|
@@ -1427,10 +964,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1427
964
|
}
|
|
1428
965
|
}
|
|
1429
966
|
|
|
1430
|
-
|
|
1431
|
-
if (this.config.
|
|
1432
|
-
|
|
967
|
+
// send message if new devices are offline
|
|
968
|
+
if (this.config.checkSendOfflineMsg) await this.sendOfflineNotifications();
|
|
969
|
+
|
|
1433
970
|
await this.writeDatapoints(); // fill the datapoints
|
|
971
|
+
|
|
1434
972
|
} catch (error) {
|
|
1435
973
|
this.errorReporting('[createDataOfAllAdapter]', error);
|
|
1436
974
|
}
|
|
@@ -1442,7 +980,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1442
980
|
/**
|
|
1443
981
|
* Notification service
|
|
1444
982
|
* @param {string} text - Text which should be send
|
|
1445
|
-
|
|
983
|
+
*/
|
|
1446
984
|
async sendNotification(text) {
|
|
1447
985
|
|
|
1448
986
|
// Pushover
|
|
@@ -1560,6 +1098,55 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1560
1098
|
}
|
|
1561
1099
|
} // <-- End of sendNotification function
|
|
1562
1100
|
|
|
1101
|
+
async sendBatteryNotifyShedule() {
|
|
1102
|
+
// send message for low battery devices
|
|
1103
|
+
|
|
1104
|
+
const time = (this.config.checkSendBatteryTime).split(':');
|
|
1105
|
+
|
|
1106
|
+
const checkDays = []; // list of selected days
|
|
1107
|
+
|
|
1108
|
+
// push the selected days in list
|
|
1109
|
+
if (this.config.checkMonday) checkDays.push(1);
|
|
1110
|
+
if (this.config.checkTuesday) checkDays.push(2);
|
|
1111
|
+
if (this.config.checkWednesday) checkDays.push(3);
|
|
1112
|
+
if (this.config.checkThursday) checkDays.push(4);
|
|
1113
|
+
if (this.config.checkFriday) checkDays.push(5);
|
|
1114
|
+
if (this.config.checkSaturday) checkDays.push(6);
|
|
1115
|
+
if (this.config.checkSunday) checkDays.push(0);
|
|
1116
|
+
|
|
1117
|
+
if (checkDays.length >= 1) { // check if an day is selected
|
|
1118
|
+
this.log.debug(`Number of selected days for daily battery message: ${checkDays.length}. Send Message on: ${(checkDays).join(', ')} ...`);
|
|
1119
|
+
} else {
|
|
1120
|
+
this.log.warn(`No days selected for daily battery message. Please check the instance configuration!`);
|
|
1121
|
+
return; // cancel function if no day is selected
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
if (!isUnloaded) {
|
|
1125
|
+
const cron = '10 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
1126
|
+
schedule.scheduleJob(cron, () => {
|
|
1127
|
+
try {
|
|
1128
|
+
let deviceList = '';
|
|
1129
|
+
|
|
1130
|
+
for (const id of this.batteryLowPowered) {
|
|
1131
|
+
if (!this.blacklistNotify.includes(id['Device'])) {
|
|
1132
|
+
deviceList = `${deviceList}\n${id['Device']} (${id['Battery']})`;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
if ((this.lowBatteryPoweredCount > 0) && (deviceList.length > 0)) {
|
|
1137
|
+
this.log.info(`Niedrige Batteriezustände: ${deviceList}`);
|
|
1138
|
+
this.setStateAsync('lastNotification', `Niedrige Batteriezustände: ${deviceList}`, true);
|
|
1139
|
+
|
|
1140
|
+
this.sendNotification(`Niedriege Batteriezustände: ${deviceList}`);
|
|
1141
|
+
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
} catch (error) {
|
|
1145
|
+
this.errorReporting('[sendBatteryNotifyShedule]', error);
|
|
1146
|
+
}
|
|
1147
|
+
});
|
|
1148
|
+
}
|
|
1149
|
+
} //<--End of battery notification
|
|
1563
1150
|
|
|
1564
1151
|
async sendOfflineNotifications() {
|
|
1565
1152
|
// send message if an device is offline
|
|
@@ -1568,24 +1155,30 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1568
1155
|
|
|
1569
1156
|
try {
|
|
1570
1157
|
let msg = '';
|
|
1158
|
+
let deviceList = '';
|
|
1571
1159
|
const offlineDevicesCountOld = await this.getOwnInitValue('offlineCount');
|
|
1572
1160
|
|
|
1573
1161
|
if ((this.offlineDevicesCount !== offlineDevicesCountOld)) {
|
|
1574
|
-
if (this.offlineDevicesCount == 0) {
|
|
1575
|
-
msg = 'Alle Geräte sind Online.';
|
|
1576
|
-
} else if (this.offlineDevicesCount == 1) { // make singular if it is only one device
|
|
1577
|
-
msg = 'Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n';
|
|
1578
|
-
} else if (this.offlineDevicesCount >= 2) { //make plural if it is more than one device
|
|
1579
|
-
msg = `Folgende ${this.offlineDevicesCount} Geräte sind seit einiger Zeit nicht erreichbar: \n`;
|
|
1580
|
-
}
|
|
1581
1162
|
|
|
1582
1163
|
for (const id of this.offlineDevices) {
|
|
1583
|
-
|
|
1164
|
+
if (!this.blacklistNotify.includes(id['Device'])) {
|
|
1165
|
+
deviceList = `${deviceList}\n${id['Device']} (${id['Last contact']})`;
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
if (deviceList.length > 0) {
|
|
1169
|
+
if (deviceList.length == 0) {
|
|
1170
|
+
msg = 'Alle Geräte sind Online.';
|
|
1171
|
+
} else if (deviceList.length == 1) { // make singular if it is only one device
|
|
1172
|
+
msg = 'Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n';
|
|
1173
|
+
} else if (deviceList.length >= 2) { //make plural if it is more than one device
|
|
1174
|
+
msg = `Folgende Geräte sind seit einiger Zeit nicht erreichbar: \n`;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
this.log.info(msg + deviceList);
|
|
1178
|
+
await this.setStateAsync('lastNotification', msg + deviceList, true);
|
|
1179
|
+
await this.sendNotification(msg + deviceList);
|
|
1584
1180
|
}
|
|
1585
1181
|
|
|
1586
|
-
this.log.info(msg);
|
|
1587
|
-
await this.setStateAsync('lastNotification', msg, true);
|
|
1588
|
-
await this.sendNotification(msg);
|
|
1589
1182
|
}
|
|
1590
1183
|
} catch (error) {
|
|
1591
1184
|
this.errorReporting('[sendOfflineMessage]', error);
|
|
@@ -1593,107 +1186,54 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1593
1186
|
this.log.debug(`Finished the function: ${this.sendOfflineNotifications.name}`);
|
|
1594
1187
|
}//<--End of offline notification
|
|
1595
1188
|
|
|
1596
|
-
async
|
|
1189
|
+
async sendOfflineNotificationsShedule() {
|
|
1597
1190
|
// send daily an overview with offline devices
|
|
1598
1191
|
|
|
1599
|
-
|
|
1192
|
+
const time = (this.config.checkSendOfflineTime).split(':');
|
|
1600
1193
|
|
|
1601
|
-
|
|
1602
|
-
// Check if the daily message for offline devices was already sent today
|
|
1603
|
-
const lastOfflineNotifyIndicator = await this.getOwnInitValue('info.lastOfflineNotification');
|
|
1604
|
-
const now = new Date(); // get date
|
|
1605
|
-
|
|
1606
|
-
// set indicator for send message first to 'false', after sending to 'true'
|
|
1607
|
-
if (now.getHours() < 11) await this.setStateAsync('info.lastOfflineNotification', false, true);
|
|
1608
|
-
|
|
1609
|
-
// if time is > 11 (12:00 pm create message for offline devices devices)
|
|
1610
|
-
if ((now.getHours() > 11) && (!lastOfflineNotifyIndicator)) {
|
|
1611
|
-
let msg = '';
|
|
1612
|
-
|
|
1613
|
-
for (const id of this.offlineDevices) {
|
|
1614
|
-
msg = `${msg}\n${id['Device']} (${id['Last contact']})`;
|
|
1615
|
-
}
|
|
1194
|
+
const checkDays = []; // list of selected days
|
|
1616
1195
|
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1196
|
+
// push the selected days in list
|
|
1197
|
+
if (this.config.checkOfflineMonday) checkDays.push(1);
|
|
1198
|
+
if (this.config.checkOfflineTuesday) checkDays.push(2);
|
|
1199
|
+
if (this.config.checkOfflineWednesday) checkDays.push(3);
|
|
1200
|
+
if (this.config.checkOfflineThursday) checkDays.push(4);
|
|
1201
|
+
if (this.config.checkOfflineFriday) checkDays.push(5);
|
|
1202
|
+
if (this.config.checkOfflineSaturday) checkDays.push(6);
|
|
1203
|
+
if (this.config.checkOfflineSunday) checkDays.push(0);
|
|
1620
1204
|
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
} catch (error) {
|
|
1627
|
-
this.errorReporting('[sendDailyOfflineNotifications]', error);
|
|
1205
|
+
if (checkDays.length >= 1) { // check if an day is selected
|
|
1206
|
+
this.log.debug(`Number of selected days for daily offline message: ${checkDays.length}. Send Message on: ${(checkDays).join(', ')} ...`);
|
|
1207
|
+
} else {
|
|
1208
|
+
this.log.warn(`No days selected for daily offline message. Please check the instance configuration!`);
|
|
1209
|
+
return; // cancel function if no day is selected
|
|
1628
1210
|
}
|
|
1629
|
-
this.log.debug(`Finished the function: ${this.sendDailyOfflineNotifications.name}`);
|
|
1630
|
-
}//<--End of daily offline notification
|
|
1631
1211
|
|
|
1632
|
-
|
|
1633
|
-
|
|
1212
|
+
if (!isUnloaded) {
|
|
1213
|
+
const cron = '10 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
1214
|
+
schedule.scheduleJob(cron, () => {
|
|
1215
|
+
try {
|
|
1216
|
+
let deviceList = '';
|
|
1217
|
+
|
|
1218
|
+
for (const id of this.offlineDevices) {
|
|
1219
|
+
if (!this.blacklistNotify.includes(id['Device'])) {
|
|
1220
|
+
deviceList = `${deviceList}\n${id['Device']} (${id['Last contact']})`;
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1634
1223
|
|
|
1635
|
-
|
|
1224
|
+
if (deviceList.length > 0) {
|
|
1225
|
+
this.log.info(`Geräte Offline: ${deviceList}`);
|
|
1226
|
+
this.setStateAsync('lastNotification', `Geräte Offline: ${deviceList}`, true);
|
|
1636
1227
|
|
|
1637
|
-
|
|
1228
|
+
this.sendNotification(`Geräte Offline: ${deviceList}`);
|
|
1229
|
+
}
|
|
1638
1230
|
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
const checkDays = []; // list of selected days
|
|
1642
|
-
let checkToday; // indicator if selected day is today
|
|
1643
|
-
|
|
1644
|
-
// push the selected days in list
|
|
1645
|
-
if (this.config.checkMonday) checkDays.push(1);
|
|
1646
|
-
if (this.config.checkTuesday) checkDays.push(2);
|
|
1647
|
-
if (this.config.checkWednesday) checkDays.push(3);
|
|
1648
|
-
if (this.config.checkThursday) checkDays.push(4);
|
|
1649
|
-
if (this.config.checkFriday) checkDays.push(5);
|
|
1650
|
-
if (this.config.checkSaturday) checkDays.push(6);
|
|
1651
|
-
if (this.config.checkSunday) checkDays.push(0);
|
|
1652
|
-
|
|
1653
|
-
//Check if the message should be send today
|
|
1654
|
-
checkDays.forEach(object => {
|
|
1655
|
-
if ((object >= 0) && today == object) {
|
|
1656
|
-
checkToday = true;
|
|
1231
|
+
} catch (error) {
|
|
1232
|
+
this.errorReporting('[sendOfflineNotificationsShedule]', error);
|
|
1657
1233
|
}
|
|
1658
1234
|
});
|
|
1659
|
-
|
|
1660
|
-
if (checkDays.length >= 1) { // check if an day is selected
|
|
1661
|
-
this.log.debug(`Number of selected days: ${checkDays.length}. Send Message on: ${(checkDays).join(', ')} ...`);
|
|
1662
|
-
} else {
|
|
1663
|
-
this.log.warn(`No days selected. Please check the instance configuration!`);
|
|
1664
|
-
return; // cancel function if no day is selected
|
|
1665
|
-
}
|
|
1666
|
-
|
|
1667
|
-
// Check if the message for low battery was already sent today
|
|
1668
|
-
const lastBatteryNotifyIndicator = await this.getOwnInitValue('info.lastBatteryNotification');
|
|
1669
|
-
|
|
1670
|
-
// set indicator for send message first to 'false', after sending to 'true'
|
|
1671
|
-
if (now.getHours() < 11) await this.setStateAsync('info.lastBatteryNotification', false, true);
|
|
1672
|
-
|
|
1673
|
-
// if time is > 11 (12:00 pm create message for low battery devices)
|
|
1674
|
-
if ((now.getHours() > 11) && (!lastBatteryNotifyIndicator) && (checkToday != undefined)) {
|
|
1675
|
-
let msg = '';
|
|
1676
|
-
|
|
1677
|
-
for (const id of this.batteryLowPowered) {
|
|
1678
|
-
msg = `${msg}\n${id['Device']} (${id['Battery']})`;
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
if (this.lowBatteryPoweredCount > 0) {
|
|
1682
|
-
this.log.info(`Niedrige Batteriezustände: ${msg}`);
|
|
1683
|
-
await this.setStateAsync('lastNotification', `Niedrige Batteriezustände: ${msg}`, true);
|
|
1684
|
-
|
|
1685
|
-
await this.sendNotification(`Niedriege Batteriezustände: ${msg}`);
|
|
1686
|
-
|
|
1687
|
-
await this.setStateAsync('info.lastBatteryNotification', true, true);
|
|
1688
|
-
}
|
|
1689
|
-
}
|
|
1690
|
-
} catch (error) {
|
|
1691
|
-
this.errorReporting('[sendOfflineMessage]', error);
|
|
1692
1235
|
}
|
|
1693
|
-
|
|
1694
|
-
this.log.debug(`Finished the function: ${this.sendBatteryNotifications.name}`);
|
|
1695
|
-
}//<--End of battery notification
|
|
1696
|
-
|
|
1236
|
+
}//<--End of daily offline notification
|
|
1697
1237
|
|
|
1698
1238
|
async resetVars() {
|
|
1699
1239
|
//Reset all arrays and counts
|
|
@@ -1705,7 +1245,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1705
1245
|
this.batteryPowered = [];
|
|
1706
1246
|
this.batteryLowPowered = [];
|
|
1707
1247
|
this.listAllDevices = [];
|
|
1708
|
-
|
|
1248
|
+
this.listAllDevicesRaw = [];
|
|
1709
1249
|
// counts
|
|
1710
1250
|
this.offlineDevicesCount = 0;
|
|
1711
1251
|
this.deviceCounter = 0;
|
|
@@ -1713,8 +1253,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1713
1253
|
this.batteryPoweredCount = 0;
|
|
1714
1254
|
this.lowBatteryPoweredCount = 0;
|
|
1715
1255
|
|
|
1716
|
-
this.deviceReachable = '';
|
|
1717
|
-
|
|
1718
1256
|
this.log.debug(`Function finished: ${this.resetVars.name}`);
|
|
1719
1257
|
} // <-- end of resetVars
|
|
1720
1258
|
|
|
@@ -1900,7 +1438,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1900
1438
|
// create datapoints for each adapter
|
|
1901
1439
|
/**
|
|
1902
1440
|
* @param {object} adptName - Adaptername of devices
|
|
1903
|
-
|
|
1441
|
+
*/
|
|
1904
1442
|
async createDPsForEachAdapter(adptName) {
|
|
1905
1443
|
|
|
1906
1444
|
await this.setObjectNotExistsAsync(`${adptName}`, {
|