iobroker.device-watcher 0.2.2 → 1.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/LICENSE +1 -1
- package/README.md +30 -6
- package/admin/i18n/de/translations.json +14 -5
- package/admin/i18n/en/translations.json +8 -2
- package/admin/i18n/es/translations.json +12 -3
- package/admin/i18n/fr/translations.json +13 -4
- package/admin/i18n/it/translations.json +11 -2
- package/admin/i18n/nl/translations.json +11 -2
- package/admin/i18n/pl/translations.json +12 -3
- package/admin/i18n/pt/translations.json +11 -2
- package/admin/i18n/ru/translations.json +11 -2
- package/admin/i18n/zh-cn/translations.json +12 -3
- package/admin/jsonConfig.json +129 -11
- package/admin/words.js +36 -72
- package/io-package.json +169 -78
- package/main.js +1207 -786
- package/package.json +22 -19
package/main.js
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
const utils = require('@iobroker/adapter-core');
|
|
8
8
|
const adapterName = require('./package.json').name.split('.').pop();
|
|
9
9
|
|
|
10
|
+
// Sentry error reporting, disable when testing code!
|
|
11
|
+
const enableSendSentry = true;
|
|
12
|
+
|
|
10
13
|
class DeviceWatcher extends utils.Adapter {
|
|
11
14
|
|
|
12
15
|
constructor(options) {
|
|
@@ -16,246 +19,384 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
16
19
|
useFormatDate: true,
|
|
17
20
|
});
|
|
18
21
|
|
|
19
|
-
this.on('ready', this.onReady.bind(this));
|
|
20
|
-
//this.on('stateChange', this.onStateChange.bind(this));
|
|
21
|
-
// this.on('objectChange', this.onObjectChange.bind(this));
|
|
22
|
-
// this.on('message', this.onMessage.bind(this));
|
|
23
|
-
this.on('unload', this.onUnload.bind(this));
|
|
24
|
-
|
|
25
22
|
// arrays
|
|
26
|
-
this.offlineDevices
|
|
27
|
-
this.linkQualityDevices
|
|
28
|
-
this.batteryPowered
|
|
29
|
-
this.batteryLowPowered
|
|
30
|
-
this.listAllDevices
|
|
31
|
-
this.blacklistArr
|
|
32
|
-
this.arrDev
|
|
33
|
-
this.adapterSelected
|
|
23
|
+
this.offlineDevices = [];
|
|
24
|
+
this.linkQualityDevices = [];
|
|
25
|
+
this.batteryPowered = [];
|
|
26
|
+
this.batteryLowPowered = [];
|
|
27
|
+
this.listAllDevices = [];
|
|
28
|
+
this.blacklistArr = [];
|
|
29
|
+
this.arrDev = [];
|
|
30
|
+
this.adapterSelected = [];
|
|
34
31
|
|
|
35
32
|
// counts
|
|
36
|
-
this.offlineDevicesCount
|
|
37
|
-
this.deviceCounter
|
|
38
|
-
this.linkQualityCount
|
|
39
|
-
this.batteryPoweredCount
|
|
40
|
-
this.lowBatteryPoweredCount
|
|
33
|
+
this.offlineDevicesCount = 0;
|
|
34
|
+
this.deviceCounter = 0;
|
|
35
|
+
this.linkQualityCount = 0;
|
|
36
|
+
this.batteryPoweredCount = 0;
|
|
37
|
+
this.lowBatteryPoweredCount = 0;
|
|
41
38
|
|
|
42
|
-
this.deviceReachable
|
|
39
|
+
this.deviceReachable = '';
|
|
40
|
+
|
|
41
|
+
// Interval timer
|
|
42
|
+
this.refreshDataTimeout = null;
|
|
43
43
|
|
|
44
44
|
// arrays of supported adapters
|
|
45
45
|
this.arrApart = {
|
|
46
|
-
alexa2:
|
|
47
|
-
'Selektor':'alexa2.*.online',
|
|
48
|
-
'adapter':'alexa2',
|
|
49
|
-
'battery':'none',
|
|
50
|
-
'reach':'.online',
|
|
51
|
-
'isLowBat':'none'
|
|
46
|
+
alexa2: {
|
|
47
|
+
'Selektor': 'alexa2.*.online',
|
|
48
|
+
'adapter': 'alexa2',
|
|
49
|
+
'battery': 'none',
|
|
50
|
+
'reach': '.online',
|
|
51
|
+
'isLowBat': 'none'
|
|
52
|
+
},
|
|
53
|
+
ble: {
|
|
54
|
+
'Selektor': 'ble.*.rssi',
|
|
55
|
+
'adapter': 'ble',
|
|
56
|
+
'battery': '.battery',
|
|
57
|
+
'reach': 'none',
|
|
58
|
+
'isLowBat': 'none'
|
|
52
59
|
},
|
|
53
|
-
|
|
54
|
-
'Selektor':'
|
|
55
|
-
'adapter':'
|
|
56
|
-
'battery':'.battery',
|
|
57
|
-
'reach':'
|
|
58
|
-
'isLowBat':'none'
|
|
60
|
+
deconz: {
|
|
61
|
+
'Selektor': 'deconz.*.reachable',
|
|
62
|
+
'adapter': 'deconz',
|
|
63
|
+
'battery': '.battery',
|
|
64
|
+
'reach': '.reachable',
|
|
65
|
+
'isLowBat': 'none'
|
|
59
66
|
},
|
|
60
|
-
|
|
61
|
-
'Selektor':'
|
|
62
|
-
'adapter':'
|
|
63
|
-
'battery':'
|
|
64
|
-
'reach':'
|
|
65
|
-
'isLowBat':'none'
|
|
66
|
-
'id':'.name'
|
|
67
|
+
enocean: {
|
|
68
|
+
'Selektor': 'enocean.*.rssi',
|
|
69
|
+
'adapter': 'enocean',
|
|
70
|
+
'battery': '.BS',
|
|
71
|
+
'reach': 'none',
|
|
72
|
+
'isLowBat': 'none'
|
|
67
73
|
},
|
|
68
|
-
|
|
69
|
-
'Selektor':'
|
|
70
|
-
'adapter':'
|
|
71
|
-
'battery':'
|
|
72
|
-
'reach':'.
|
|
73
|
-
'isLowBat':'none'
|
|
74
|
+
esphome: {
|
|
75
|
+
'Selektor': 'esphome.*._online',
|
|
76
|
+
'adapter': 'esphome',
|
|
77
|
+
'battery': 'none',
|
|
78
|
+
'reach': '._online',
|
|
79
|
+
'isLowBat': 'none',
|
|
80
|
+
'id': '.name'
|
|
74
81
|
},
|
|
75
|
-
|
|
76
|
-
'Selektor':'
|
|
77
|
-
'adapter':'
|
|
78
|
-
'
|
|
79
|
-
'
|
|
80
|
-
'
|
|
81
|
-
'isLowBat':'none'
|
|
82
|
+
fritzdect: {
|
|
83
|
+
'Selektor': 'fritzdect.*.present',
|
|
84
|
+
'adapter': 'fritzDect',
|
|
85
|
+
'battery': '.battery',
|
|
86
|
+
'reach': '.present',
|
|
87
|
+
'isLowBat': '.batterylow'
|
|
82
88
|
},
|
|
83
|
-
|
|
84
|
-
'Selektor':'
|
|
85
|
-
'adapter':'
|
|
86
|
-
'battery':'
|
|
87
|
-
'reach':'.
|
|
88
|
-
'isLowBat':'none'
|
|
89
|
+
harmony: {
|
|
90
|
+
'Selektor': 'harmony.*.hubConnected',
|
|
91
|
+
'adapter': 'harmony',
|
|
92
|
+
'battery': 'none',
|
|
93
|
+
'reach': '.hubConnected',
|
|
94
|
+
'isLowBat': 'none'
|
|
89
95
|
},
|
|
90
|
-
homematic:
|
|
91
|
-
'Selektor':'hm-rpc.*.UNREACH',
|
|
92
|
-
'adapter':'homematic',
|
|
93
|
-
'rssiState':'.RSSI_DEVICE',
|
|
94
|
-
'battery':'.OPERATING_VOLTAGE',
|
|
95
|
-
'reach':'.UNREACH',
|
|
96
|
-
'isLowBat':'.LOW_BAT',
|
|
97
|
-
'isLowBat2':'.LOWBAT'
|
|
96
|
+
homematic: {
|
|
97
|
+
'Selektor': 'hm-rpc.*.UNREACH',
|
|
98
|
+
'adapter': 'homematic',
|
|
99
|
+
'rssiState': '.RSSI_DEVICE',
|
|
100
|
+
'battery': '.OPERATING_VOLTAGE',
|
|
101
|
+
'reach': '.UNREACH',
|
|
102
|
+
'isLowBat': '.LOW_BAT',
|
|
103
|
+
'isLowBat2': '.LOWBAT'
|
|
98
104
|
},
|
|
99
|
-
|
|
100
|
-
'Selektor':'
|
|
101
|
-
'adapter':'
|
|
102
|
-
'battery':'.battery',
|
|
103
|
-
'reach':'.reachable',
|
|
104
|
-
'isLowBat':'none'
|
|
105
|
+
hue: {
|
|
106
|
+
'Selektor': 'hue.*.reachable',
|
|
107
|
+
'adapter': 'hue',
|
|
108
|
+
'battery': '.battery',
|
|
109
|
+
'reach': '.reachable',
|
|
110
|
+
'isLowBat': 'none'
|
|
105
111
|
},
|
|
106
|
-
|
|
107
|
-
'Selektor':'
|
|
108
|
-
'adapter':'
|
|
109
|
-
'battery':'.
|
|
110
|
-
'reach':'.
|
|
111
|
-
'isLowBat':'
|
|
112
|
+
hueExt: {
|
|
113
|
+
'Selektor': 'hue-extended.*.reachable',
|
|
114
|
+
'adapter': 'hue-extended',
|
|
115
|
+
'battery': '.config.battery',
|
|
116
|
+
'reach': '.reachable',
|
|
117
|
+
'isLowBat': 'none'
|
|
112
118
|
},
|
|
113
|
-
|
|
114
|
-
'Selektor':'
|
|
115
|
-
'adapter':'
|
|
116
|
-
'battery':'
|
|
117
|
-
'reach':'
|
|
118
|
-
'isLowBat':'.
|
|
119
|
+
jeelink: {
|
|
120
|
+
'Selektor': 'jeelink.*.lowBatt',
|
|
121
|
+
'adapter': 'jeelink',
|
|
122
|
+
'battery': 'none',
|
|
123
|
+
'reach': 'none',
|
|
124
|
+
'isLowBat': '.lowBatt'
|
|
119
125
|
},
|
|
120
|
-
|
|
121
|
-
'Selektor':'
|
|
122
|
-
'adapter':'
|
|
123
|
-
'battery':'.
|
|
124
|
-
'reach':'
|
|
125
|
-
'isLowBat':'none'
|
|
126
|
+
mihome: {
|
|
127
|
+
'Selektor': 'mihome.*.percent',
|
|
128
|
+
'adapter': 'miHome',
|
|
129
|
+
'battery': '.percent',
|
|
130
|
+
'reach': 'none',
|
|
131
|
+
'isLowBat': 'none'
|
|
126
132
|
},
|
|
127
|
-
|
|
128
|
-
'Selektor':'
|
|
129
|
-
'adapter':'
|
|
130
|
-
'battery':'
|
|
131
|
-
'reach':'.
|
|
132
|
-
'isLowBat':'none'
|
|
133
|
+
mihomeGW: {
|
|
134
|
+
'Selektor': 'mihome.*.connected',
|
|
135
|
+
'adapter': 'miHome',
|
|
136
|
+
'battery': 'none',
|
|
137
|
+
'reach': '.connected',
|
|
138
|
+
'isLowBat': 'none'
|
|
133
139
|
},
|
|
134
|
-
|
|
135
|
-
'Selektor':'
|
|
136
|
-
'adapter':'
|
|
137
|
-
'
|
|
138
|
-
'
|
|
139
|
-
'
|
|
140
|
+
mihomeVacuum: {
|
|
141
|
+
'Selektor': 'mihome-vacuum.*.connection',
|
|
142
|
+
'adapter': 'mihomeVacuum',
|
|
143
|
+
'rssiState': '.deviceInfo.wifi_signal',
|
|
144
|
+
'battery': '.info.battery',
|
|
145
|
+
'battery2': '.control.battary_life',
|
|
146
|
+
'reach': '.info.connection',
|
|
147
|
+
'isLowBat': 'none',
|
|
148
|
+
'id': '.deviceInfo.model'
|
|
140
149
|
},
|
|
141
|
-
|
|
142
|
-
'Selektor':'
|
|
143
|
-
'adapter':'
|
|
144
|
-
'
|
|
145
|
-
'
|
|
146
|
-
'
|
|
147
|
-
'
|
|
150
|
+
nukiExt: {
|
|
151
|
+
'Selektor': 'nuki-extended.*.lastDataUpdate',
|
|
152
|
+
'adapter': 'nuki-extended',
|
|
153
|
+
'rssiState': 'none',
|
|
154
|
+
'battery': '.batteryChargeState',
|
|
155
|
+
'reach': 'none',
|
|
156
|
+
'isLowBat': '.batteryCritical'
|
|
148
157
|
},
|
|
149
|
-
|
|
150
|
-
'Selektor':'
|
|
151
|
-
'adapter':'
|
|
152
|
-
'battery':'none',
|
|
153
|
-
'reach':'.alive',
|
|
154
|
-
'isLowBat':'none'
|
|
158
|
+
ping: {
|
|
159
|
+
'Selektor': 'ping.*.alive',
|
|
160
|
+
'adapter': 'ping',
|
|
161
|
+
'battery': 'none',
|
|
162
|
+
'reach': '.alive',
|
|
163
|
+
'isLowBat': 'none'
|
|
155
164
|
},
|
|
156
|
-
|
|
157
|
-
'Selektor':'
|
|
158
|
-
'adapter':'
|
|
159
|
-
'battery':'.
|
|
160
|
-
'reach':'
|
|
161
|
-
'isLowBat':'none'
|
|
165
|
+
shelly: {
|
|
166
|
+
'Selektor': 'shelly.*.rssi',
|
|
167
|
+
'adapter': 'shelly',
|
|
168
|
+
'battery': '.sensor.battery',
|
|
169
|
+
'reach': '.online',
|
|
170
|
+
'isLowBat': 'none'
|
|
162
171
|
},
|
|
163
|
-
|
|
164
|
-
'Selektor':'
|
|
165
|
-
'adapter':'
|
|
166
|
-
'
|
|
167
|
-
'
|
|
168
|
-
'
|
|
172
|
+
sonoff: {
|
|
173
|
+
'Selektor': 'sonoff.*.Uptime',
|
|
174
|
+
'adapter': 'sonoff',
|
|
175
|
+
'rssiState': '.Wifi_Signal',
|
|
176
|
+
'battery': '.battery',
|
|
177
|
+
'reach': '.alive',
|
|
178
|
+
'isLowBat': 'none'
|
|
169
179
|
},
|
|
170
|
-
|
|
171
|
-
'Selektor':'
|
|
172
|
-
'adapter':'
|
|
173
|
-
'battery':'
|
|
174
|
-
'reach':'
|
|
175
|
-
'isLowBat':'
|
|
180
|
+
sonos: {
|
|
181
|
+
'Selektor': 'sonos.*.alive',
|
|
182
|
+
'adapter': 'sonos',
|
|
183
|
+
'battery': 'none',
|
|
184
|
+
'reach': '.alive',
|
|
185
|
+
'isLowBat': 'none'
|
|
186
|
+
},
|
|
187
|
+
switchbotBle: {
|
|
188
|
+
'Selektor': 'switchbot-ble.*.rssi',
|
|
189
|
+
'adapter': 'switchbotBle',
|
|
190
|
+
'battery': '.battery',
|
|
191
|
+
'reach': 'none',
|
|
192
|
+
'isLowBat': 'none',
|
|
193
|
+
'id': '.id'
|
|
194
|
+
},
|
|
195
|
+
zigbee: {
|
|
196
|
+
'Selektor': 'zigbee.*.link_quality',
|
|
197
|
+
'adapter': 'zigbee',
|
|
198
|
+
'battery': '.battery',
|
|
199
|
+
'reach': '.available',
|
|
200
|
+
'isLowBat': '.battery_low'
|
|
201
|
+
},
|
|
202
|
+
zwave: {
|
|
203
|
+
'Selektor': 'zwave2.*.ready',
|
|
204
|
+
'adapter': 'zwave',
|
|
205
|
+
'battery': '.Battery.level',
|
|
206
|
+
'reach': '.ready',
|
|
207
|
+
'isLowBat': '.Battery.isLow'
|
|
208
|
+
},
|
|
209
|
+
test: { // Only for Dev
|
|
210
|
+
'Selektor': '0_userdata.*.UNREACH',
|
|
211
|
+
'adapter': 'homematic',
|
|
212
|
+
'rssiState': '.RSSI_DEVICE',
|
|
213
|
+
'battery': '.OPERATING_VOLTAGE',
|
|
214
|
+
'reach': '.UNREACH',
|
|
215
|
+
'isLowBat': '.LOW_BAT',
|
|
216
|
+
'isLowBat2': '.LOWBAT'
|
|
176
217
|
}
|
|
177
218
|
};
|
|
219
|
+
|
|
220
|
+
this.on('ready', this.onReady.bind(this));
|
|
221
|
+
this.on('stateChange', this.onStateChange.bind(this));
|
|
222
|
+
// this.on('objectChange', this.onObjectChange.bind(this));
|
|
223
|
+
// this.on('message', this.onMessage.bind(this));
|
|
224
|
+
this.on('unload', this.onUnload.bind(this));
|
|
225
|
+
|
|
178
226
|
}
|
|
179
227
|
|
|
180
228
|
async onReady() {
|
|
181
229
|
this.log.debug(`Adapter ${adapterName} was started`);
|
|
182
230
|
|
|
183
231
|
try {
|
|
232
|
+
this.supAdapter = {
|
|
233
|
+
alexa2: this.config.alexa2Devices,
|
|
234
|
+
ble: this.config.bleDevices,
|
|
235
|
+
deconz: this.config.deconzDevices,
|
|
236
|
+
enocean: this.config.enoceanDevices,
|
|
237
|
+
esphome: this.config.esphomeDevices,
|
|
238
|
+
fritzdect: this.config.fritzdectDevices,
|
|
239
|
+
harmony: this.config.harmonyDevices,
|
|
240
|
+
homematic: this.config.homematicDevices,
|
|
241
|
+
hue: this.config.hueDevices,
|
|
242
|
+
hueExt: this.config.hueExtDevices,
|
|
243
|
+
jeelink: this.config.jeelinkDevices,
|
|
244
|
+
mihome: this.config.mihomeDevices,
|
|
245
|
+
mihomeGW: this.config.mihomeDevices,
|
|
246
|
+
mihomeVacuum: this.config.mihomeVacuumDevices,
|
|
247
|
+
nukiExt: this.config.nukiExtDevices,
|
|
248
|
+
ping: this.config.pingDevices,
|
|
249
|
+
shelly: this.config.shellyDevices,
|
|
250
|
+
sonoff: this.config.sonoffDevices,
|
|
251
|
+
sonos: this.config.sonosDevices,
|
|
252
|
+
switchbotBle: this.config.switchbotBleDevices,
|
|
253
|
+
zigbee: this.config.zigbeeDevices,
|
|
254
|
+
zwave: this.config.zwaveDevices,
|
|
255
|
+
test: false // Only for Dev
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
for (const [id] of Object.entries(this.arrApart)) {
|
|
259
|
+
if (this.supAdapter[id]) {
|
|
260
|
+
this.arrDev.push(this.arrApart[id]);
|
|
261
|
+
this.adapterSelected.push(await this.capitalize(id));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
//Check if an Adapter is selected.
|
|
266
|
+
if (this.adapterSelected.length >= 1) {
|
|
267
|
+
// show list in debug log
|
|
268
|
+
this.log.debug(JSON.stringify(this.arrDev));
|
|
269
|
+
|
|
270
|
+
this.log.info(`Number of selected adapters: ${this.adapterSelected.length}. Loading data from: ${(this.adapterSelected).join(', ')} ...`);
|
|
271
|
+
} else {
|
|
272
|
+
this.log.warn(`No adapter selected. Please check the instance configuration!`);
|
|
273
|
+
return; // cancel run if no adapter is selected
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
//create Blacklist
|
|
277
|
+
try {
|
|
278
|
+
await this.createBlacklist();
|
|
279
|
+
} catch (error) {
|
|
280
|
+
this.errorReporting('[onReady - create blacklist]', error);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// update data now
|
|
184
284
|
await this.main();
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
await this.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
this.log.error(`Error while running Device-Watcher. Error Message: ${e}`);
|
|
285
|
+
|
|
286
|
+
// update data in interval
|
|
287
|
+
await this.refreshData();
|
|
288
|
+
|
|
289
|
+
} catch (error) {
|
|
290
|
+
this.errorReporting('[onReady]', error);
|
|
192
291
|
this.terminate ? this.terminate(15) : process.exit(15);
|
|
193
292
|
}
|
|
194
293
|
}
|
|
195
294
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
295
|
+
/**
|
|
296
|
+
* Is called if a subscribed state changes
|
|
297
|
+
* @param {string} id
|
|
298
|
+
* @param {ioBroker.State | null | undefined} state
|
|
299
|
+
*/
|
|
300
|
+
async onStateChange(id, state) {
|
|
301
|
+
if (state) {
|
|
302
|
+
// The state was changed
|
|
303
|
+
this.log.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
|
|
304
|
+
await this.main();
|
|
305
|
+
} else {
|
|
306
|
+
// The state was deleted
|
|
307
|
+
this.log.debug(`state ${id} deleted`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
async refreshData() {
|
|
312
|
+
const nextTimeout = this.config.updateinterval * 1000;
|
|
313
|
+
|
|
314
|
+
await this.main();
|
|
315
|
+
|
|
316
|
+
// Clear existing timeout
|
|
317
|
+
if (this.refreshDataTimeout) {
|
|
318
|
+
this.log.debug('clearing old refresh timeout');
|
|
319
|
+
this.clearTimeout(this.refreshDataTimeout);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
this.refreshDataTimeout = this.setTimeout(() => {
|
|
323
|
+
this.log.debug('Updating Data');
|
|
324
|
+
|
|
325
|
+
this.refreshDataTimeout = null;
|
|
326
|
+
this.refreshData();
|
|
327
|
+
}, nextTimeout);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async main() {
|
|
331
|
+
this.log.debug(`Function started: ${this.main.name}`);
|
|
332
|
+
|
|
333
|
+
try {
|
|
334
|
+
|
|
335
|
+
//create and fill datapoints for each adapter if selected
|
|
336
|
+
try {
|
|
337
|
+
for (const [id] of Object.entries(this.arrApart)) {
|
|
338
|
+
if ((this.supAdapter !== undefined) && (this.supAdapter[id])) {
|
|
339
|
+
|
|
340
|
+
if (this.config.createOwnFolder) {
|
|
341
|
+
await this.createDPsForEachAdapter(id);
|
|
342
|
+
if (this.config.createHtmlList) await this.createHtmlListDatapoints(id);
|
|
343
|
+
this.log.debug(`Created datapoints for ${await this.capitalize(id)}`);
|
|
344
|
+
await this.createDataForEachAdapter(id);
|
|
345
|
+
this.log.debug(`Created and filled data for each adapter`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
} catch (error) {
|
|
350
|
+
this.errorReporting('[main - create and fill datapoints for each adapter]', error);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// creating counts and lists of all selected adapter
|
|
354
|
+
try {
|
|
355
|
+
if (this.config.createHtmlList) await this.createHtmlListDatapoints();
|
|
356
|
+
await this.createDataOfAllAdapter();
|
|
357
|
+
this.log.debug(`Created and filled data for all adapters`);
|
|
358
|
+
} catch (error) {
|
|
359
|
+
this.errorReporting('[main - create data of all adapter]', error);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
} catch (error) {
|
|
363
|
+
this.errorReporting('[main]', error);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
this.log.debug(`Function finished: ${this.main.name}`);
|
|
367
|
+
} //<--End of main function
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* @param {string} sentence - Word which should be capitalize
|
|
372
|
+
**/
|
|
373
|
+
async capitalize(sentence) {
|
|
199
374
|
//make the first letter uppercase
|
|
200
375
|
return sentence && sentence[0].toUpperCase() + sentence.slice(1);
|
|
201
376
|
}
|
|
202
377
|
|
|
378
|
+
/**
|
|
379
|
+
* @param {object} obj - State of datapoint
|
|
380
|
+
**/
|
|
203
381
|
async getInitValue(obj) {
|
|
204
382
|
//state can be null or undefinded
|
|
205
383
|
const foreignState = await this.getForeignStateAsync(obj);
|
|
206
384
|
if (foreignState) return foreignState.val;
|
|
207
385
|
}
|
|
208
386
|
|
|
387
|
+
/**
|
|
388
|
+
* @param {object} obj - State of own datapoint
|
|
389
|
+
**/
|
|
209
390
|
async getOwnInitValue(obj) {
|
|
210
391
|
//state can be null or undefinded for own states
|
|
211
392
|
const stateVal = await this.getStateAsync(obj);
|
|
212
393
|
if (stateVal) return stateVal.val;
|
|
213
394
|
}
|
|
214
395
|
|
|
215
|
-
//Notification services
|
|
216
|
-
async sendPushover(text) {
|
|
217
|
-
await this.sendToAsync(this.config.instancePushover, 'send', {
|
|
218
|
-
message: text,
|
|
219
|
-
title: this.config.titlePushover,
|
|
220
|
-
device: this.config.devicePushover,
|
|
221
|
-
priority: this.config.prioPushover
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
async sendTelegram(text) {
|
|
226
|
-
await this.sendToAsync(this.config.instanceTelegram, 'send', {
|
|
227
|
-
text: text,
|
|
228
|
-
user: this.config.deviceTelegram,
|
|
229
|
-
chatId: this.config.chatIdTelegram
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
async sendWhatsapp(text) {
|
|
234
|
-
await this.sendToAsync(this.config.instanceWhatsapp, 'send', {
|
|
235
|
-
text: text,
|
|
236
|
-
phone: this.config.phoneWhatsapp
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
async sendEmail(text) {
|
|
241
|
-
await this.sendToAsync(this.config.instanceEmail, 'send', {
|
|
242
|
-
sendTo: this.config.sendToEmail,
|
|
243
|
-
text: text,
|
|
244
|
-
subject: this.config.subjectEmail
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
async sendJarvis(text) {
|
|
249
|
-
await this.setForeignStateAsync(`${this.config.instanceJarvis}.addNotification`, text);
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
async sendLovelace(text) {
|
|
254
|
-
await this.setForeignStateAsync(`${this.config.instanceLovelace}.notifications.add`, text);
|
|
255
|
-
|
|
256
|
-
}
|
|
257
|
-
|
|
258
396
|
//create datapoints for each adapter
|
|
397
|
+
/**
|
|
398
|
+
* @param {object} adptName - Adaptername of devices
|
|
399
|
+
**/
|
|
259
400
|
async createDPsForEachAdapter(adptName) {
|
|
260
401
|
|
|
261
402
|
await this.setObjectNotExistsAsync(`${adptName}`, {
|
|
@@ -288,6 +429,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
288
429
|
},
|
|
289
430
|
'native': {}
|
|
290
431
|
});
|
|
432
|
+
|
|
291
433
|
await this.setObjectNotExistsAsync(`${adptName}.offlineList`, {
|
|
292
434
|
'type': 'state',
|
|
293
435
|
'common': {
|
|
@@ -310,6 +452,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
310
452
|
},
|
|
311
453
|
'native': {}
|
|
312
454
|
});
|
|
455
|
+
|
|
313
456
|
await this.setObjectNotExistsAsync(`${adptName}.listAll`, {
|
|
314
457
|
'type': 'state',
|
|
315
458
|
'common': {
|
|
@@ -332,6 +475,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
332
475
|
},
|
|
333
476
|
'native': {}
|
|
334
477
|
});
|
|
478
|
+
|
|
335
479
|
await this.setObjectNotExistsAsync(`${adptName}.linkQualityList`, {
|
|
336
480
|
'type': 'state',
|
|
337
481
|
'common': {
|
|
@@ -354,6 +498,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
354
498
|
},
|
|
355
499
|
'native': {}
|
|
356
500
|
});
|
|
501
|
+
|
|
357
502
|
await this.setObjectNotExistsAsync(`${adptName}.countAll`, {
|
|
358
503
|
'type': 'state',
|
|
359
504
|
'common': {
|
|
@@ -376,6 +521,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
376
521
|
},
|
|
377
522
|
'native': {}
|
|
378
523
|
});
|
|
524
|
+
|
|
379
525
|
await this.setObjectNotExistsAsync(`${adptName}.batteryList`, {
|
|
380
526
|
'type': 'state',
|
|
381
527
|
'common': {
|
|
@@ -398,6 +544,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
398
544
|
},
|
|
399
545
|
'native': {}
|
|
400
546
|
});
|
|
547
|
+
|
|
401
548
|
await this.setObjectNotExistsAsync(`${adptName}.lowBatteryList`, {
|
|
402
549
|
'type': 'state',
|
|
403
550
|
'common': {
|
|
@@ -420,6 +567,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
420
567
|
},
|
|
421
568
|
'native': {}
|
|
422
569
|
});
|
|
570
|
+
|
|
423
571
|
await this.setObjectNotExistsAsync(`${adptName}.lowBatteryCount`, {
|
|
424
572
|
'type': 'state',
|
|
425
573
|
'common': {
|
|
@@ -442,6 +590,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
442
590
|
},
|
|
443
591
|
'native': {}
|
|
444
592
|
});
|
|
593
|
+
|
|
445
594
|
await this.setObjectNotExistsAsync(`${adptName}.batteryCount`, {
|
|
446
595
|
'type': 'state',
|
|
447
596
|
'common': {
|
|
@@ -466,41 +615,161 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
466
615
|
});
|
|
467
616
|
}
|
|
468
617
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
618
|
+
/**
|
|
619
|
+
* @param {object} [adptName] - Adaptername of devices
|
|
620
|
+
**/
|
|
621
|
+
async createHtmlListDatapoints(adptName) {
|
|
622
|
+
|
|
623
|
+
let dpSubFolder;
|
|
624
|
+
//write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
|
|
625
|
+
if (adptName) {
|
|
626
|
+
dpSubFolder = `${adptName}.`;
|
|
627
|
+
} else {
|
|
628
|
+
dpSubFolder = '';
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
await this.setObjectNotExistsAsync(`${dpSubFolder}offlineListHTML`, {
|
|
632
|
+
'type': 'state',
|
|
633
|
+
'common': {
|
|
634
|
+
'name': {
|
|
635
|
+
'en': 'HTML List of offline devices',
|
|
636
|
+
'de': 'HTML Liste der Offline-Geräte',
|
|
637
|
+
'ru': 'HTML Список оффлайн устройств',
|
|
638
|
+
'pt': 'HTML Lista de dispositivos off-line',
|
|
639
|
+
'nl': 'HTML List van offline apparatuur',
|
|
640
|
+
'fr': 'HTML Liste des dispositifs hors ligne',
|
|
641
|
+
'it': 'HTML Elenco dei dispositivi offline',
|
|
642
|
+
'es': 'HTML Lista de dispositivos sin conexión',
|
|
643
|
+
'pl': 'HTML Lista urządzeń offline',
|
|
644
|
+
'zh-cn': 'HTML 线装置清单'
|
|
645
|
+
},
|
|
646
|
+
'type': 'string',
|
|
647
|
+
'role': 'html',
|
|
648
|
+
'read': true,
|
|
649
|
+
'write': false,
|
|
650
|
+
},
|
|
651
|
+
'native': {}
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
await this.setObjectNotExistsAsync(`${dpSubFolder}linkQualityListHTML`, {
|
|
655
|
+
'type': 'state',
|
|
656
|
+
'common': {
|
|
657
|
+
'name': {
|
|
658
|
+
'en': 'HTML List of devices with signal strength',
|
|
659
|
+
'de': 'HTML Liste der Geräte mit Signalstärke',
|
|
660
|
+
'ru': 'HTML Список устройств с силой сигнала',
|
|
661
|
+
'pt': 'HTML Lista de dispositivos com força de sinal',
|
|
662
|
+
'nl': 'HTML List van apparaten met signaalkracht',
|
|
663
|
+
'fr': 'HTML Liste des dispositifs avec force de signal',
|
|
664
|
+
'it': 'HTML Elenco dei dispositivi con forza del segnale',
|
|
665
|
+
'es': 'HTML Lista de dispositivos con fuerza de señal',
|
|
666
|
+
'pl': 'HTML Lista urządzeń z siłą sygnałową',
|
|
667
|
+
'zh-cn': 'HTML 具有信号实力的装置清单'
|
|
668
|
+
},
|
|
669
|
+
'type': 'string',
|
|
670
|
+
'role': 'value',
|
|
671
|
+
'read': true,
|
|
672
|
+
'write': false,
|
|
673
|
+
},
|
|
674
|
+
'native': {}
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
await this.setObjectNotExistsAsync(`${dpSubFolder}batteryListHTML`, {
|
|
678
|
+
'type': 'state',
|
|
679
|
+
'common': {
|
|
680
|
+
'name': {
|
|
681
|
+
'en': 'HTML List of devices with battery state',
|
|
682
|
+
'de': 'HTML Liste der Geräte mit Batteriezustand',
|
|
683
|
+
'ru': 'HTML Список устройств с состоянием батареи',
|
|
684
|
+
'pt': 'HTML Lista de dispositivos com estado da bateria',
|
|
685
|
+
'nl': 'HTML List van apparaten met batterij staat',
|
|
686
|
+
'fr': 'HTML Liste des appareils avec état de batterie',
|
|
687
|
+
'it': 'HTML Elenco dei dispositivi con stato della batteria',
|
|
688
|
+
'es': 'HTML Lista de dispositivos con estado de batería',
|
|
689
|
+
'pl': 'HTML Lista urządzeń z baterią stanową',
|
|
690
|
+
'zh-cn': 'HTML 电池国装置清单'
|
|
691
|
+
},
|
|
692
|
+
'type': 'string',
|
|
693
|
+
'role': 'html',
|
|
694
|
+
'read': true,
|
|
695
|
+
'write': false,
|
|
696
|
+
},
|
|
697
|
+
'native': {}
|
|
698
|
+
});
|
|
473
699
|
|
|
474
|
-
|
|
475
|
-
|
|
700
|
+
await this.setObjectNotExistsAsync(`${dpSubFolder}lowBatteryListHTML`, {
|
|
701
|
+
'type': 'state',
|
|
702
|
+
'common': {
|
|
703
|
+
'name': {
|
|
704
|
+
'en': 'HTML List of devices with low battery state',
|
|
705
|
+
'de': 'HTML Liste der Geräte mit niedrigem Batteriezustand',
|
|
706
|
+
'ru': 'HTML Список устройств с низким состоянием батареи',
|
|
707
|
+
'pt': 'HTML Lista de dispositivos com baixo estado da bateria',
|
|
708
|
+
'nl': 'HTML List van apparaten met lage batterij staat',
|
|
709
|
+
'fr': 'HTML Liste des appareils à faible état de batterie',
|
|
710
|
+
'it': 'HTML Elenco di dispositivi con stato di batteria basso',
|
|
711
|
+
'es': 'HTML Lista de dispositivos con estado de batería bajo',
|
|
712
|
+
'pl': 'HTML Lista urządzeń o niskim stanie baterii',
|
|
713
|
+
'zh-cn': 'HTML 低电池国家装置清单'
|
|
714
|
+
},
|
|
715
|
+
'type': 'string',
|
|
716
|
+
'role': 'html',
|
|
717
|
+
'read': true,
|
|
718
|
+
'write': false,
|
|
719
|
+
},
|
|
720
|
+
'native': {}
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
async createBlacklist() {
|
|
725
|
+
this.log.debug(`Function started: ${this.createBlacklist.name}`);
|
|
726
|
+
|
|
727
|
+
const myBlacklist = this.config.tableBlacklist;
|
|
728
|
+
|
|
729
|
+
for (const i in myBlacklist) {
|
|
476
730
|
this.blacklistArr.push(myBlacklist[i].device);
|
|
477
|
-
this.log.debug(`Found items on the blacklist: ${this.blacklistArr}`);
|
|
478
731
|
}
|
|
732
|
+
this.log.info(`Found items on the blacklist: ${this.blacklistArr}`);
|
|
733
|
+
this.log.debug(`Function finished: ${this.createBlacklist.name}`);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* @param {object} i - Device Object
|
|
738
|
+
**/
|
|
739
|
+
async createData(i) {
|
|
740
|
+
const devices = await this.getForeignStatesAsync(this.arrDev[i].Selektor);
|
|
741
|
+
const deviceAdapterName = await this.capitalize(this.arrDev[i].adapter);
|
|
479
742
|
|
|
480
743
|
/*---------- Start of second main loop ----------*/
|
|
481
|
-
for(const [id] of Object.entries(devices)) {
|
|
744
|
+
for (const [id] of Object.entries(devices)) {
|
|
482
745
|
if (!this.blacklistArr.includes(id)) {
|
|
483
746
|
|
|
484
|
-
const currDeviceString
|
|
747
|
+
const currDeviceString = id.slice(0, (id.lastIndexOf('.') + 1) - 1);
|
|
485
748
|
const shortCurrDeviceString = currDeviceString.slice(0, (currDeviceString.lastIndexOf('.') + 1) - 1);
|
|
486
749
|
|
|
487
|
-
//Get device name
|
|
750
|
+
// Get device name
|
|
488
751
|
const deviceObject = await this.getForeignObjectAsync(currDeviceString);
|
|
489
752
|
const shortDeviceObject = await this.getForeignObjectAsync(shortCurrDeviceString);
|
|
490
753
|
let deviceName;
|
|
491
754
|
|
|
492
755
|
switch (this.arrDev[i].adapter) {
|
|
493
|
-
case 'switchbotBle': //Get ID for Switchbot and ESPHome Devices
|
|
756
|
+
case 'switchbotBle': // Get ID for Switchbot and ESPHome Devices
|
|
494
757
|
case 'esphome':
|
|
495
758
|
deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
|
|
496
759
|
break;
|
|
497
760
|
|
|
498
761
|
case 'hue-extended':
|
|
499
|
-
|
|
762
|
+
case 'homematic':
|
|
763
|
+
case 'nuki-extended':
|
|
764
|
+
if (shortDeviceObject && typeof shortDeviceObject === 'object') {
|
|
500
765
|
deviceName = shortDeviceObject.common.name;
|
|
501
766
|
}
|
|
502
767
|
break;
|
|
503
768
|
|
|
769
|
+
case 'mihomeVacuum':
|
|
770
|
+
deviceName = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].id);
|
|
771
|
+
break;
|
|
772
|
+
|
|
504
773
|
default:
|
|
505
774
|
if (deviceObject && typeof deviceObject === 'object') {
|
|
506
775
|
deviceName = deviceObject.common.name;
|
|
@@ -508,48 +777,71 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
508
777
|
break;
|
|
509
778
|
}
|
|
510
779
|
|
|
511
|
-
|
|
780
|
+
const deviceMainSelector = await this.getForeignStateAsync(id);
|
|
781
|
+
|
|
782
|
+
// Get battery states
|
|
783
|
+
const deviceBatteryState = await this.getInitValue(currDeviceString + this.arrDev[i].battery);
|
|
784
|
+
const shortDeviceBatteryState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery);
|
|
785
|
+
const shortDeviceBatteryState2 = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery2);
|
|
786
|
+
|
|
787
|
+
// Get link quality
|
|
512
788
|
let deviceQualityState;
|
|
513
789
|
let linkQuality;
|
|
514
790
|
|
|
515
791
|
switch (this.arrDev[i].adapter) {
|
|
516
|
-
case 'homematic':
|
|
517
792
|
case 'sonoff':
|
|
793
|
+
case 'homematic':
|
|
518
794
|
deviceQualityState = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rssiState);
|
|
519
795
|
break;
|
|
796
|
+
|
|
797
|
+
case 'mihomeVacuum':
|
|
798
|
+
deviceQualityState = await this.getForeignStateAsync(shortCurrDeviceString + this.arrDev[i].rssiState);
|
|
799
|
+
break;
|
|
800
|
+
|
|
520
801
|
default:
|
|
521
802
|
deviceQualityState = await this.getForeignStateAsync(id);
|
|
803
|
+
break;
|
|
522
804
|
}
|
|
523
805
|
|
|
524
|
-
if ((deviceQualityState) && (typeof deviceQualityState.val === 'number')){
|
|
806
|
+
if ((deviceQualityState) && (typeof deviceQualityState.val === 'number')) {
|
|
525
807
|
if (this.config.trueState) {
|
|
526
808
|
linkQuality = deviceQualityState.val;
|
|
527
809
|
} else {
|
|
528
810
|
if (deviceQualityState.val < 0) {
|
|
529
811
|
linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
|
|
530
812
|
} else if ((deviceQualityState.val) >= 0) {
|
|
531
|
-
linkQuality = parseFloat((100/255 * deviceQualityState.val).toFixed(0)) + '%';
|
|
813
|
+
linkQuality = parseFloat((100 / 255 * deviceQualityState.val).toFixed(0)) + '%';
|
|
532
814
|
}
|
|
533
815
|
}
|
|
534
|
-
this.
|
|
535
|
-
{
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
816
|
+
if (this.config.listOnlyBattery) {
|
|
817
|
+
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
818
|
+
this.linkQualityDevices.push(
|
|
819
|
+
{
|
|
820
|
+
'Device': deviceName,
|
|
821
|
+
'Adapter': deviceAdapterName,
|
|
822
|
+
'Signal strength': linkQuality
|
|
823
|
+
}
|
|
824
|
+
);
|
|
539
825
|
}
|
|
540
|
-
|
|
826
|
+
} else {
|
|
827
|
+
this.linkQualityDevices.push(
|
|
828
|
+
{
|
|
829
|
+
'Device': deviceName,
|
|
830
|
+
'Adapter': deviceAdapterName,
|
|
831
|
+
'Signal strength': linkQuality
|
|
832
|
+
}
|
|
833
|
+
);
|
|
834
|
+
}
|
|
541
835
|
} else {
|
|
542
|
-
|
|
543
|
-
linkQuality = ' - ';
|
|
836
|
+
linkQuality = ' - '; // no linkQuality available for powered devices
|
|
544
837
|
}
|
|
545
838
|
|
|
546
|
-
//
|
|
839
|
+
// Count how many devices with link Quality
|
|
547
840
|
this.linkQualityCount = this.linkQualityDevices.length;
|
|
548
841
|
|
|
549
|
-
//
|
|
842
|
+
// When was the last contact to the device?
|
|
550
843
|
let lastContactString;
|
|
551
844
|
|
|
552
|
-
const deviceMainSelector = await this.getForeignStateAsync(id);
|
|
553
845
|
let deviceState = 'Online';
|
|
554
846
|
if (deviceMainSelector) {
|
|
555
847
|
try {
|
|
@@ -557,15 +849,15 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
557
849
|
const lastContact = Math.round((time.getTime() - deviceMainSelector.ts) / 1000 / 60);
|
|
558
850
|
const lastStateChange = Math.round((time.getTime() - deviceMainSelector.lc) / 1000 / 60);
|
|
559
851
|
const deviceUnreachState = await this.getInitValue(currDeviceString + this.arrDev[i].reach);
|
|
560
|
-
|
|
852
|
+
const shortDeviceUnreachState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].reach);
|
|
561
853
|
|
|
562
854
|
const getLastContact = async () => {
|
|
563
855
|
lastContactString = this.formatDate(new Date((deviceMainSelector.ts)), 'hh:mm') + ' Uhr';
|
|
564
856
|
if (Math.round(lastContact) > 100) {
|
|
565
|
-
lastContactString = Math.round(lastContact/60) + ' Stunden';
|
|
857
|
+
lastContactString = Math.round(lastContact / 60) + ' Stunden';
|
|
566
858
|
}
|
|
567
|
-
if (Math.round(lastContact/60) > 48) {
|
|
568
|
-
lastContactString = Math.round(lastContact/60/24) + ' Tagen';
|
|
859
|
+
if (Math.round(lastContact / 60) > 48) {
|
|
860
|
+
lastContactString = Math.round(lastContact / 60 / 24) + ' Tagen';
|
|
569
861
|
}
|
|
570
862
|
return lastContactString;
|
|
571
863
|
};
|
|
@@ -573,47 +865,42 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
573
865
|
const getLastStateChange = async () => {
|
|
574
866
|
lastContactString = this.formatDate(new Date((deviceMainSelector.lc)), 'hh:mm') + ' Uhr';
|
|
575
867
|
if (Math.round(lastStateChange) > 100) {
|
|
576
|
-
lastContactString = Math.round(lastStateChange/60) + ' Stunden';
|
|
868
|
+
lastContactString = Math.round(lastStateChange / 60) + ' Stunden';
|
|
577
869
|
}
|
|
578
|
-
if (Math.round(lastStateChange/60) > 48) {
|
|
579
|
-
lastContactString = Math.round(lastStateChange/60/24) + ' Tagen';
|
|
870
|
+
if (Math.round(lastStateChange / 60) > 48) {
|
|
871
|
+
lastContactString = Math.round(lastStateChange / 60 / 24) + ' Tagen';
|
|
580
872
|
}
|
|
581
873
|
return lastContactString;
|
|
582
874
|
};
|
|
583
875
|
|
|
584
|
-
//
|
|
585
|
-
//
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
//State changed
|
|
590
|
-
if (!deviceUnreachState) {
|
|
591
|
-
await getLastStateChange();
|
|
592
|
-
} else {
|
|
593
|
-
await getLastContact();
|
|
594
|
-
}
|
|
876
|
+
// If there is no contact since user sets minutes add device in offline list
|
|
877
|
+
// calculate to days after 48 hours
|
|
878
|
+
switch (this.arrDev[i].reach) {
|
|
879
|
+
case 'none':
|
|
880
|
+
await getLastContact();
|
|
595
881
|
break;
|
|
596
882
|
|
|
597
883
|
default:
|
|
598
|
-
|
|
599
|
-
|
|
884
|
+
//State changed
|
|
885
|
+
if (this.arrDev[i].adapter == 'homematic') {
|
|
886
|
+
if (deviceUnreachState) {
|
|
887
|
+
await getLastStateChange();
|
|
888
|
+
} else {
|
|
889
|
+
await getLastContact();
|
|
890
|
+
}
|
|
891
|
+
} else {
|
|
892
|
+
if ((!deviceUnreachState)) {
|
|
893
|
+
await getLastStateChange();
|
|
894
|
+
} else {
|
|
895
|
+
await getLastContact();
|
|
896
|
+
}
|
|
897
|
+
break;
|
|
898
|
+
}
|
|
600
899
|
}
|
|
601
900
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
if (
|
|
605
|
-
if (!deviceUnreachState) {
|
|
606
|
-
deviceState = 'Offline'; //set online state to offline
|
|
607
|
-
this.offlineDevices.push(
|
|
608
|
-
{
|
|
609
|
-
'Device': deviceName,
|
|
610
|
-
'Adapter': deviceAdapterName,
|
|
611
|
-
'Last contact': lastContactString
|
|
612
|
-
}
|
|
613
|
-
);
|
|
614
|
-
}
|
|
615
|
-
} else if (lastContact > this.config.alexa2MaxMinutes) {
|
|
616
|
-
deviceState = 'Offline'; //set online state to offline
|
|
901
|
+
const pushOfflineDevice = async () => {
|
|
902
|
+
if (this.config.listOnlyBattery) { //if checked, list only battery devices
|
|
903
|
+
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
617
904
|
this.offlineDevices.push(
|
|
618
905
|
{
|
|
619
906
|
'Device': deviceName,
|
|
@@ -622,395 +909,304 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
622
909
|
}
|
|
623
910
|
);
|
|
624
911
|
}
|
|
912
|
+
} else {
|
|
913
|
+
this.offlineDevices.push( //else push all devices
|
|
914
|
+
{
|
|
915
|
+
'Device': deviceName,
|
|
916
|
+
'Adapter': deviceAdapterName,
|
|
917
|
+
'Last contact': lastContactString
|
|
918
|
+
}
|
|
919
|
+
);
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
|
|
923
|
+
// await this.subscribeForeignStatesAsync(currDeviceString + this.arrDev[i].reach);
|
|
924
|
+
|
|
925
|
+
switch (this.arrDev[i].adapter) {
|
|
926
|
+
case 'alexa2':
|
|
927
|
+
if (this.config.alexa2MaxMinutes === -1) {
|
|
928
|
+
if (!deviceUnreachState) {
|
|
929
|
+
deviceState = 'Offline'; //set online state to offline
|
|
930
|
+
await pushOfflineDevice();
|
|
931
|
+
}
|
|
932
|
+
} else if ((lastStateChange > this.config.alexa2MaxMinutes) && (!deviceUnreachState)) {
|
|
933
|
+
deviceState = 'Offline'; //set online state to offline
|
|
934
|
+
await pushOfflineDevice();
|
|
935
|
+
}
|
|
625
936
|
break;
|
|
626
937
|
case 'ble':
|
|
627
938
|
if (this.config.bleMaxMinutes === -1) {
|
|
628
939
|
if (!deviceUnreachState) {
|
|
629
940
|
deviceState = 'Offline'; //set online state to offline
|
|
630
|
-
|
|
631
|
-
{
|
|
632
|
-
'Device': deviceName,
|
|
633
|
-
'Adapter': deviceAdapterName,
|
|
634
|
-
'Last contact': lastContactString
|
|
635
|
-
}
|
|
636
|
-
);
|
|
941
|
+
await pushOfflineDevice();
|
|
637
942
|
}
|
|
638
943
|
} else if (lastContact > this.config.bleMaxMinutes) {
|
|
639
944
|
deviceState = 'Offline'; //set online state to offline
|
|
640
|
-
|
|
641
|
-
{
|
|
642
|
-
'Device': deviceName,
|
|
643
|
-
'Adapter': deviceAdapterName,
|
|
644
|
-
'Last contact': lastContactString
|
|
645
|
-
}
|
|
646
|
-
);
|
|
945
|
+
await pushOfflineDevice();
|
|
647
946
|
}
|
|
648
947
|
break;
|
|
649
948
|
case 'deconz':
|
|
650
949
|
if (this.config.deconzMaxMinutes === -1) {
|
|
651
950
|
if (!deviceUnreachState) {
|
|
652
951
|
deviceState = 'Offline'; //set online state to offline
|
|
653
|
-
|
|
654
|
-
{
|
|
655
|
-
'Device': deviceName,
|
|
656
|
-
'Adapter': deviceAdapterName,
|
|
657
|
-
'Last contact': lastContactString
|
|
658
|
-
}
|
|
659
|
-
);
|
|
952
|
+
await pushOfflineDevice();
|
|
660
953
|
}
|
|
661
|
-
} else if (
|
|
954
|
+
} else if ((lastStateChange > this.config.deconzMaxMinutes) && (!deviceUnreachState)) {
|
|
662
955
|
deviceState = 'Offline'; //set online state to offline
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
956
|
+
await pushOfflineDevice();
|
|
957
|
+
}
|
|
958
|
+
break;
|
|
959
|
+
case 'enocean':
|
|
960
|
+
if (this.config.enoceanMaxMinutes === -1) {
|
|
961
|
+
if (!deviceUnreachState) {
|
|
962
|
+
deviceState = 'Offline'; //set online state to offline
|
|
963
|
+
await pushOfflineDevice();
|
|
964
|
+
}
|
|
965
|
+
} else if (lastContact > this.config.enoceanMaxMinutes) {
|
|
966
|
+
deviceState = 'Offline'; //set online state to offline
|
|
967
|
+
await pushOfflineDevice();
|
|
670
968
|
}
|
|
671
969
|
break;
|
|
672
970
|
case 'esphome':
|
|
673
971
|
if (this.config.esphomeMaxMinutes === -1) {
|
|
674
972
|
if (!deviceUnreachState) {
|
|
675
973
|
deviceState = 'Offline'; //set online state to offline
|
|
676
|
-
|
|
677
|
-
{
|
|
678
|
-
'Device': deviceName,
|
|
679
|
-
'Adapter': deviceAdapterName,
|
|
680
|
-
'Last contact': lastContactString
|
|
681
|
-
}
|
|
682
|
-
);
|
|
974
|
+
await pushOfflineDevice();
|
|
683
975
|
}
|
|
684
|
-
} else if (
|
|
976
|
+
} else if ((lastStateChange > this.config.esphomeMaxMinutes) && (!deviceUnreachState)) {
|
|
685
977
|
deviceState = 'Offline'; //set online state to offline
|
|
686
|
-
|
|
687
|
-
{
|
|
688
|
-
'Device': deviceName,
|
|
689
|
-
'Adapter': deviceAdapterName,
|
|
690
|
-
'Last contact': lastContactString
|
|
691
|
-
}
|
|
692
|
-
);
|
|
978
|
+
await pushOfflineDevice();
|
|
693
979
|
}
|
|
694
980
|
break;
|
|
695
981
|
case 'fritzDect':
|
|
696
982
|
if (this.config.fritzdectMaxMinutes === -1) {
|
|
697
983
|
if (!deviceUnreachState) {
|
|
698
984
|
deviceState = 'Offline'; //set online state to offline
|
|
699
|
-
|
|
700
|
-
{
|
|
701
|
-
'Device': deviceName,
|
|
702
|
-
'Adapter': deviceAdapterName,
|
|
703
|
-
'Last contact': lastContactString
|
|
704
|
-
}
|
|
705
|
-
);
|
|
985
|
+
await pushOfflineDevice();
|
|
706
986
|
}
|
|
707
|
-
} else if (
|
|
987
|
+
} else if ((lastStateChange > this.config.fritzdectMaxMinutes) && (!deviceUnreachState)) {
|
|
708
988
|
deviceState = 'Offline'; //set online state to offline
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
989
|
+
await pushOfflineDevice();
|
|
990
|
+
}
|
|
991
|
+
break;
|
|
992
|
+
case 'harmony':
|
|
993
|
+
if (this.config.harmonyMaxMinutes === -1) {
|
|
994
|
+
if (!deviceUnreachState) {
|
|
995
|
+
deviceState = 'Offline'; //set online state to offline
|
|
996
|
+
await pushOfflineDevice();
|
|
997
|
+
}
|
|
998
|
+
} else if ((lastStateChange > this.config.harmonyMaxMinutes) && (!deviceUnreachState)) {
|
|
999
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1000
|
+
await pushOfflineDevice();
|
|
716
1001
|
}
|
|
717
1002
|
break;
|
|
718
1003
|
case 'homematic':
|
|
719
1004
|
if (this.config.homematicMaxMinutes === -1) {
|
|
720
1005
|
if (deviceUnreachState) {
|
|
721
1006
|
deviceState = 'Offline'; //set online state to offline
|
|
722
|
-
|
|
723
|
-
{
|
|
724
|
-
'Device': deviceName,
|
|
725
|
-
'Adapter': deviceAdapterName,
|
|
726
|
-
'Last contact': lastContactString
|
|
727
|
-
}
|
|
728
|
-
);
|
|
1007
|
+
await pushOfflineDevice();
|
|
729
1008
|
}
|
|
730
|
-
} else if (
|
|
1009
|
+
} else if ((lastStateChange > this.config.homematicMaxMinutes) && (deviceUnreachState)) {
|
|
731
1010
|
deviceState = 'Offline'; //set online state to offline
|
|
732
|
-
|
|
733
|
-
{
|
|
734
|
-
'Device': deviceName,
|
|
735
|
-
'Adapter': deviceAdapterName,
|
|
736
|
-
'Last contact': lastContactString
|
|
737
|
-
}
|
|
738
|
-
);
|
|
1011
|
+
await pushOfflineDevice();
|
|
739
1012
|
}
|
|
740
1013
|
break;
|
|
741
1014
|
case 'hue':
|
|
742
1015
|
if (this.config.hueMaxMinutes === -1) {
|
|
743
1016
|
if (!deviceUnreachState) {
|
|
744
1017
|
deviceState = 'Offline'; //set online state to offline
|
|
745
|
-
|
|
746
|
-
{
|
|
747
|
-
'Device': deviceName,
|
|
748
|
-
'Adapter': deviceAdapterName,
|
|
749
|
-
'Last contact': lastContactString
|
|
750
|
-
}
|
|
751
|
-
);
|
|
1018
|
+
await pushOfflineDevice();
|
|
752
1019
|
}
|
|
753
|
-
} else if (
|
|
1020
|
+
} else if ((lastStateChange > this.config.hueMaxMinutes) && (!deviceUnreachState)) {
|
|
754
1021
|
deviceState = 'Offline'; //set online state to offline
|
|
755
|
-
|
|
756
|
-
{
|
|
757
|
-
'Device': deviceName,
|
|
758
|
-
'Adapter': deviceAdapterName,
|
|
759
|
-
'Last contact': lastContactString
|
|
760
|
-
}
|
|
761
|
-
);
|
|
1022
|
+
await pushOfflineDevice();
|
|
762
1023
|
}
|
|
763
1024
|
break;
|
|
764
1025
|
case 'hue-extended':
|
|
765
1026
|
if (this.config.hueextMaxMinutes === -1) {
|
|
766
1027
|
if (!deviceUnreachState) {
|
|
767
1028
|
deviceState = 'Offline'; //set online state to offline
|
|
768
|
-
|
|
769
|
-
{
|
|
770
|
-
'Device': deviceName,
|
|
771
|
-
'Adapter': deviceAdapterName,
|
|
772
|
-
'Last contact': lastContactString
|
|
773
|
-
}
|
|
774
|
-
);
|
|
1029
|
+
await pushOfflineDevice();
|
|
775
1030
|
}
|
|
776
|
-
} else if (
|
|
1031
|
+
} else if ((lastStateChange > this.config.hueextMaxMinutes) && (!deviceUnreachState)) {
|
|
777
1032
|
deviceState = 'Offline'; //set online state to offline
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
1033
|
+
await pushOfflineDevice();
|
|
1034
|
+
}
|
|
1035
|
+
break;
|
|
1036
|
+
case 'jeelink':
|
|
1037
|
+
if (this.config.jeelinkMaxMinutes === -1) {
|
|
1038
|
+
if (!deviceUnreachState) {
|
|
1039
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1040
|
+
await pushOfflineDevice();
|
|
1041
|
+
}
|
|
1042
|
+
} else if (lastContact > this.config.jeelinkMaxMinutes) {
|
|
1043
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1044
|
+
await pushOfflineDevice();
|
|
785
1045
|
}
|
|
786
1046
|
break;
|
|
787
1047
|
case 'miHome':
|
|
788
1048
|
if (this.config.mihomeMaxMinutes === -1) {
|
|
789
1049
|
if (!deviceUnreachState) {
|
|
790
1050
|
deviceState = 'Offline'; //set online state to offline
|
|
791
|
-
|
|
792
|
-
{
|
|
793
|
-
'Device': deviceName,
|
|
794
|
-
'Adapter': deviceAdapterName,
|
|
795
|
-
'Last contact': lastContactString
|
|
796
|
-
}
|
|
797
|
-
);
|
|
1051
|
+
await pushOfflineDevice();
|
|
798
1052
|
}
|
|
799
|
-
} else if (
|
|
1053
|
+
} else if ((lastStateChange > this.config.mihomeMaxMinutes) && (!deviceUnreachState)) {
|
|
800
1054
|
deviceState = 'Offline'; //set online state to offline
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
1055
|
+
await pushOfflineDevice();
|
|
1056
|
+
}
|
|
1057
|
+
break;
|
|
1058
|
+
case 'mihomeVacuum':
|
|
1059
|
+
if (this.config.mihomeVacuumMaxMinutes === -1) {
|
|
1060
|
+
if (!shortDeviceUnreachState) {
|
|
1061
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1062
|
+
await pushOfflineDevice();
|
|
1063
|
+
}
|
|
1064
|
+
} else if ((lastStateChange > this.config.mihomeVacuumMaxMinutes) && (!shortDeviceUnreachState)) {
|
|
1065
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1066
|
+
await pushOfflineDevice();
|
|
808
1067
|
}
|
|
809
1068
|
break;
|
|
810
1069
|
case 'nuki-extended':
|
|
811
1070
|
if (this.config.nukiextendMaxMinutes === -1) {
|
|
812
1071
|
if (!deviceUnreachState) {
|
|
813
1072
|
deviceState = 'Offline'; //set online state to offline
|
|
814
|
-
|
|
815
|
-
{
|
|
816
|
-
'Device': deviceName,
|
|
817
|
-
'Adapter': deviceAdapterName,
|
|
818
|
-
'Last contact': lastContactString
|
|
819
|
-
}
|
|
820
|
-
);
|
|
1073
|
+
await pushOfflineDevice();
|
|
821
1074
|
}
|
|
822
1075
|
} else if (lastContact > this.config.nukiextendMaxMinutes) {
|
|
823
1076
|
deviceState = 'Offline'; //set online state to offline
|
|
824
|
-
|
|
825
|
-
{
|
|
826
|
-
'Device': deviceName,
|
|
827
|
-
'Adapter': deviceAdapterName,
|
|
828
|
-
'Last contact': lastContactString
|
|
829
|
-
}
|
|
830
|
-
);
|
|
1077
|
+
await pushOfflineDevice();
|
|
831
1078
|
}
|
|
832
1079
|
break;
|
|
833
1080
|
case 'ping':
|
|
834
1081
|
if (this.config.pingMaxMinutes === -1) {
|
|
835
1082
|
if (!deviceUnreachState) {
|
|
836
1083
|
deviceState = 'Offline'; //set online state to offline
|
|
837
|
-
|
|
838
|
-
{
|
|
839
|
-
'Device': deviceName,
|
|
840
|
-
'Adapter': deviceAdapterName,
|
|
841
|
-
'Last contact': lastContactString
|
|
842
|
-
}
|
|
843
|
-
);
|
|
1084
|
+
await pushOfflineDevice();
|
|
844
1085
|
}
|
|
845
1086
|
} else if ((lastStateChange > this.config.pingMaxMinutes) && (!deviceUnreachState)) {
|
|
846
1087
|
deviceState = 'Offline'; //set online state to offline
|
|
847
|
-
|
|
848
|
-
{
|
|
849
|
-
'Device': deviceName,
|
|
850
|
-
'Adapter': deviceAdapterName,
|
|
851
|
-
'Last contact': lastContactString
|
|
852
|
-
}
|
|
853
|
-
);
|
|
1088
|
+
await pushOfflineDevice();
|
|
854
1089
|
}
|
|
855
1090
|
break;
|
|
856
1091
|
case 'shelly':
|
|
857
1092
|
if (this.config.shellyMaxMinutes === -1) {
|
|
858
1093
|
if (!deviceUnreachState) {
|
|
859
1094
|
deviceState = 'Offline'; //set online state to offline
|
|
860
|
-
|
|
861
|
-
{
|
|
862
|
-
'Device': deviceName,
|
|
863
|
-
'Adapter': deviceAdapterName,
|
|
864
|
-
'Last contact': lastContactString
|
|
865
|
-
}
|
|
866
|
-
);
|
|
1095
|
+
await pushOfflineDevice();
|
|
867
1096
|
}
|
|
868
|
-
} else if (
|
|
1097
|
+
} else if ((lastStateChange > this.config.shellyMaxMinutes) && (!deviceUnreachState)) {
|
|
869
1098
|
deviceState = 'Offline'; //set online state to offline
|
|
870
|
-
|
|
871
|
-
{
|
|
872
|
-
'Device': deviceName,
|
|
873
|
-
'Adapter': deviceAdapterName,
|
|
874
|
-
'Last contact': lastContactString
|
|
875
|
-
}
|
|
876
|
-
);
|
|
1099
|
+
await pushOfflineDevice();
|
|
877
1100
|
}
|
|
878
1101
|
break;
|
|
879
1102
|
case 'sonoff':
|
|
880
1103
|
if (this.config.sonoffMaxMinutes === -1) {
|
|
881
1104
|
if (!deviceUnreachState) {
|
|
882
1105
|
deviceState = 'Offline'; //set online state to offline
|
|
883
|
-
|
|
884
|
-
{
|
|
885
|
-
'Device': deviceName,
|
|
886
|
-
'Adapter': deviceAdapterName,
|
|
887
|
-
'Last contact': lastContactString
|
|
888
|
-
}
|
|
889
|
-
);
|
|
1106
|
+
await pushOfflineDevice();
|
|
890
1107
|
}
|
|
891
|
-
} else if (
|
|
1108
|
+
} else if ((lastStateChange > this.config.sonoffMaxMinutes) && (!deviceUnreachState)) {
|
|
892
1109
|
deviceState = 'Offline'; //set online state to offline
|
|
893
|
-
|
|
894
|
-
{
|
|
895
|
-
'Device': deviceName,
|
|
896
|
-
'Adapter': deviceAdapterName,
|
|
897
|
-
'Last contact': lastContactString
|
|
898
|
-
}
|
|
899
|
-
);
|
|
1110
|
+
await pushOfflineDevice();
|
|
900
1111
|
}
|
|
901
1112
|
break;
|
|
902
1113
|
case 'sonos':
|
|
903
1114
|
if (this.config.sonosMaxMinutes === -1) {
|
|
904
1115
|
if (!deviceUnreachState) {
|
|
905
1116
|
deviceState = 'Offline'; //set online state to offline
|
|
906
|
-
|
|
907
|
-
{
|
|
908
|
-
'Device': deviceName,
|
|
909
|
-
'Adapter': deviceAdapterName,
|
|
910
|
-
'Last contact': lastContactString
|
|
911
|
-
}
|
|
912
|
-
);
|
|
1117
|
+
await pushOfflineDevice();
|
|
913
1118
|
}
|
|
914
|
-
} else if (
|
|
1119
|
+
} else if ((lastStateChange > this.config.sonosMaxMinutes) && (!deviceUnreachState)) {
|
|
915
1120
|
deviceState = 'Offline'; //set online state to offline
|
|
916
|
-
|
|
917
|
-
{
|
|
918
|
-
'Device': deviceName,
|
|
919
|
-
'Adapter': deviceAdapterName,
|
|
920
|
-
'Last contact': lastContactString
|
|
921
|
-
}
|
|
922
|
-
);
|
|
1121
|
+
await pushOfflineDevice();
|
|
923
1122
|
}
|
|
924
1123
|
break;
|
|
925
1124
|
case 'switchbotBle':
|
|
926
1125
|
if (this.config.switchbotMaxMinutes === -1) {
|
|
927
1126
|
if (!deviceUnreachState) {
|
|
928
1127
|
deviceState = 'Offline'; //set online state to offline
|
|
929
|
-
|
|
930
|
-
{
|
|
931
|
-
'Device': deviceName,
|
|
932
|
-
'Adapter': deviceAdapterName,
|
|
933
|
-
'Last contact': lastContactString
|
|
934
|
-
}
|
|
935
|
-
);
|
|
1128
|
+
await pushOfflineDevice();
|
|
936
1129
|
}
|
|
937
1130
|
} else if (lastContact > this.config.switchbotMaxMinutes) {
|
|
938
1131
|
deviceState = 'Offline'; //set online state to offline
|
|
939
|
-
|
|
940
|
-
{
|
|
941
|
-
'Device': deviceName,
|
|
942
|
-
'Adapter': deviceAdapterName,
|
|
943
|
-
'Last contact': lastContactString
|
|
944
|
-
}
|
|
945
|
-
);
|
|
1132
|
+
await pushOfflineDevice();
|
|
946
1133
|
}
|
|
947
1134
|
break;
|
|
948
1135
|
case 'zigbee':
|
|
949
1136
|
if (this.config.zigbeeMaxMinutes === -1) {
|
|
950
1137
|
if (!deviceUnreachState) {
|
|
951
1138
|
deviceState = 'Offline'; //set online state to offline
|
|
952
|
-
|
|
953
|
-
{
|
|
954
|
-
'Device': deviceName,
|
|
955
|
-
'Adapter': deviceAdapterName,
|
|
956
|
-
'Last contact': lastContactString
|
|
957
|
-
}
|
|
958
|
-
);
|
|
1139
|
+
await pushOfflineDevice();
|
|
959
1140
|
}
|
|
960
|
-
} else if (
|
|
1141
|
+
} else if ((lastStateChange > this.config.zigbeeMaxMinutes) && (!deviceUnreachState)) {
|
|
961
1142
|
deviceState = 'Offline'; //set online state to offline
|
|
962
|
-
|
|
963
|
-
{
|
|
964
|
-
'Device': deviceName,
|
|
965
|
-
'Adapter': deviceAdapterName,
|
|
966
|
-
'Last contact': lastContactString
|
|
967
|
-
}
|
|
968
|
-
);
|
|
1143
|
+
await pushOfflineDevice();
|
|
969
1144
|
}
|
|
970
1145
|
break;
|
|
971
1146
|
case 'zwave':
|
|
972
1147
|
if (this.config.zwaveMaxMinutes === -1) {
|
|
973
1148
|
if (!deviceUnreachState) {
|
|
974
1149
|
deviceState = 'Offline'; //set online state to offline
|
|
975
|
-
|
|
976
|
-
{
|
|
977
|
-
'Device': deviceName,
|
|
978
|
-
'Adapter': deviceAdapterName,
|
|
979
|
-
'Last contact': lastContactString
|
|
980
|
-
}
|
|
981
|
-
);
|
|
1150
|
+
await pushOfflineDevice();
|
|
982
1151
|
}
|
|
983
|
-
} else if (
|
|
1152
|
+
} else if ((lastStateChange > this.config.zwaveMaxMinutes) && (!deviceUnreachState)) {
|
|
984
1153
|
deviceState = 'Offline'; //set online state to offline
|
|
985
|
-
|
|
986
|
-
{
|
|
987
|
-
'Device': deviceName,
|
|
988
|
-
'Adapter': deviceAdapterName,
|
|
989
|
-
'Last contact': lastContactString
|
|
990
|
-
}
|
|
991
|
-
);
|
|
1154
|
+
await pushOfflineDevice();
|
|
992
1155
|
}
|
|
993
1156
|
break;
|
|
994
1157
|
}
|
|
995
|
-
} catch (
|
|
996
|
-
this.
|
|
1158
|
+
} catch (error) {
|
|
1159
|
+
this.errorReporting('[getLastContact]', error);
|
|
997
1160
|
}
|
|
998
1161
|
}
|
|
999
1162
|
|
|
1000
1163
|
|
|
1001
1164
|
|
|
1002
|
-
//
|
|
1165
|
+
// Count how many devcies are offline
|
|
1003
1166
|
this.offlineDevicesCount = this.offlineDevices.length;
|
|
1004
1167
|
|
|
1005
|
-
//
|
|
1006
|
-
const deviceBatteryState = await this.getInitValue(currDeviceString + this.arrDev[i].battery);
|
|
1007
|
-
const shortDeviceBatteryState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery);
|
|
1168
|
+
// Get battery states
|
|
1008
1169
|
let batteryHealth;
|
|
1170
|
+
const deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat);
|
|
1171
|
+
const deviceLowBatStateHM = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat2);
|
|
1009
1172
|
|
|
1010
|
-
if ((!deviceBatteryState) && (!shortDeviceBatteryState)) {
|
|
1011
|
-
|
|
1173
|
+
if ((!deviceBatteryState) && (!shortDeviceBatteryState) && (!shortDeviceBatteryState2)) {
|
|
1174
|
+
if ((deviceLowBatState !== undefined) || (deviceLowBatState !== undefined) || (deviceLowBatStateHM !== undefined)) {
|
|
1175
|
+
switch (this.arrDev[i].isLowBat) {
|
|
1176
|
+
case 'none':
|
|
1177
|
+
batteryHealth = ' - ';
|
|
1178
|
+
break;
|
|
1179
|
+
default:
|
|
1180
|
+
if (!deviceLowBatState) {
|
|
1181
|
+
batteryHealth = 'ok';
|
|
1182
|
+
} else {
|
|
1183
|
+
batteryHealth = 'low';
|
|
1184
|
+
}
|
|
1185
|
+
break;
|
|
1186
|
+
}
|
|
1187
|
+
switch (this.arrDev[i].isLowBat2) {
|
|
1188
|
+
case 'none':
|
|
1189
|
+
batteryHealth = ' - ';
|
|
1190
|
+
break;
|
|
1191
|
+
default:
|
|
1192
|
+
if (!deviceLowBatState) {
|
|
1193
|
+
batteryHealth = 'ok';
|
|
1194
|
+
} else {
|
|
1195
|
+
batteryHealth = 'low';
|
|
1196
|
+
}
|
|
1197
|
+
break;
|
|
1198
|
+
}
|
|
1199
|
+
this.batteryPowered.push(
|
|
1200
|
+
{
|
|
1201
|
+
'Device': deviceName,
|
|
1202
|
+
'Adapter': deviceAdapterName,
|
|
1203
|
+
'Battery': batteryHealth
|
|
1204
|
+
}
|
|
1205
|
+
);
|
|
1206
|
+
} else {
|
|
1207
|
+
batteryHealth = ' - ';
|
|
1208
|
+
}
|
|
1012
1209
|
} else {
|
|
1013
|
-
|
|
1014
1210
|
switch (this.arrDev[i].adapter) {
|
|
1015
1211
|
case 'homematic':
|
|
1016
1212
|
if (deviceBatteryState === 0) {
|
|
@@ -1039,6 +1235,27 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1039
1235
|
);
|
|
1040
1236
|
}
|
|
1041
1237
|
break;
|
|
1238
|
+
case 'mihomeVacuum':
|
|
1239
|
+
if (shortDeviceBatteryState) {
|
|
1240
|
+
batteryHealth = shortDeviceBatteryState + '%';
|
|
1241
|
+
this.batteryPowered.push(
|
|
1242
|
+
{
|
|
1243
|
+
'Device': deviceName,
|
|
1244
|
+
'Adapter': deviceAdapterName,
|
|
1245
|
+
'Battery': batteryHealth
|
|
1246
|
+
}
|
|
1247
|
+
);
|
|
1248
|
+
} else if (shortDeviceBatteryState2) {
|
|
1249
|
+
batteryHealth = shortDeviceBatteryState2 + '%';
|
|
1250
|
+
this.batteryPowered.push(
|
|
1251
|
+
{
|
|
1252
|
+
'Device': deviceName,
|
|
1253
|
+
'Adapter': deviceAdapterName,
|
|
1254
|
+
'Battery': batteryHealth
|
|
1255
|
+
}
|
|
1256
|
+
);
|
|
1257
|
+
}
|
|
1258
|
+
break;
|
|
1042
1259
|
default:
|
|
1043
1260
|
batteryHealth = (deviceBatteryState) + '%';
|
|
1044
1261
|
this.batteryPowered.push(
|
|
@@ -1051,43 +1268,51 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1051
1268
|
}
|
|
1052
1269
|
}
|
|
1053
1270
|
|
|
1054
|
-
//
|
|
1271
|
+
// Count how many devices are with battery
|
|
1055
1272
|
this.batteryPoweredCount = this.batteryPowered.length;
|
|
1056
1273
|
|
|
1057
|
-
//
|
|
1058
|
-
const batteryWarningMin
|
|
1059
|
-
const deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat);
|
|
1060
|
-
const deviceLowBatStateHM = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat2);
|
|
1274
|
+
// Count how many devices are with low battery
|
|
1275
|
+
const batteryWarningMin = this.config.minWarnBatterie;
|
|
1061
1276
|
|
|
1277
|
+
// fill list with low battery devices
|
|
1278
|
+
switch (this.arrDev[i].adapter) {
|
|
1279
|
+
case 'homematic': // there are differnt low bat states between hm and hmIp devices
|
|
1280
|
+
if (deviceLowBatState || deviceLowBatStateHM) {
|
|
1281
|
+
this.batteryLowPowered.push(
|
|
1282
|
+
{
|
|
1283
|
+
'Device': deviceName,
|
|
1284
|
+
'Adapter': deviceAdapterName,
|
|
1285
|
+
'Battery': batteryHealth
|
|
1286
|
+
}
|
|
1287
|
+
);
|
|
1288
|
+
}
|
|
1289
|
+
break;
|
|
1062
1290
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
);
|
|
1082
|
-
}
|
|
1291
|
+
default: // for all other devices with low bat states
|
|
1292
|
+
if (deviceLowBatState) {
|
|
1293
|
+
this.batteryLowPowered.push(
|
|
1294
|
+
{
|
|
1295
|
+
'Device': deviceName,
|
|
1296
|
+
'Adapter': deviceAdapterName,
|
|
1297
|
+
'Battery': batteryHealth
|
|
1298
|
+
}
|
|
1299
|
+
);
|
|
1300
|
+
} else if (deviceBatteryState && (deviceBatteryState < batteryWarningMin)) { // if the battery state is under the set limit
|
|
1301
|
+
this.batteryLowPowered.push(
|
|
1302
|
+
{
|
|
1303
|
+
'Device': deviceName,
|
|
1304
|
+
'Adapter': deviceAdapterName,
|
|
1305
|
+
'Battery': batteryHealth
|
|
1306
|
+
}
|
|
1307
|
+
);
|
|
1308
|
+
}
|
|
1083
1309
|
}
|
|
1084
1310
|
|
|
1085
1311
|
// 3d. Count how many devices are with low battery
|
|
1086
1312
|
this.lowBatteryPoweredCount = this.batteryLowPowered.length;
|
|
1087
1313
|
|
|
1088
|
-
// 4. Add
|
|
1089
|
-
|
|
1090
|
-
if (deviceBatteryState !== null || shortDeviceBatteryState !== null) {
|
|
1314
|
+
if (this.config.listOnlyBattery) { // 4. Add only devices with battery in the list
|
|
1315
|
+
if (deviceBatteryState || shortDeviceBatteryState) {
|
|
1091
1316
|
this.listAllDevices.push(
|
|
1092
1317
|
{
|
|
1093
1318
|
'Device': deviceName,
|
|
@@ -1099,7 +1324,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1099
1324
|
}
|
|
1100
1325
|
);
|
|
1101
1326
|
}
|
|
1102
|
-
} else if (!this.config.listOnlyBattery) {
|
|
1327
|
+
} else if (!this.config.listOnlyBattery) { // 4. Add all devices
|
|
1103
1328
|
this.listAllDevices.push(
|
|
1104
1329
|
{
|
|
1105
1330
|
'Device': deviceName,
|
|
@@ -1116,129 +1341,183 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1116
1341
|
// 4a. Count how many devices are exists
|
|
1117
1342
|
this.deviceCounter = this.listAllDevices.length;
|
|
1118
1343
|
}
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1344
|
+
} // <-- end of loop
|
|
1345
|
+
} // <-- end of createData
|
|
1121
1346
|
|
|
1122
|
-
async createDataForEachAdpt(adptName) {
|
|
1123
|
-
this.log.debug(`Function started: ${this.createDataForEachAdpt.name}`);
|
|
1124
|
-
await this.resetVars();
|
|
1125
1347
|
|
|
1126
|
-
|
|
1348
|
+
/**
|
|
1349
|
+
* @param {string} adptName - Adapter name
|
|
1350
|
+
*/
|
|
1351
|
+
async createDataForEachAdapter(adptName) {
|
|
1352
|
+
// create Data for each Adapter in own lists
|
|
1353
|
+
this.log.debug(`Function started: ${this.createDataForEachAdapter.name}`);
|
|
1127
1354
|
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
}
|
|
1355
|
+
try {
|
|
1356
|
+
await this.resetVars(); // reset the arrays and counts
|
|
1131
1357
|
|
|
1358
|
+
for (let i = 0; i < this.arrDev.length; i++) {
|
|
1359
|
+
|
|
1360
|
+
if (this.arrDev[i].adapter.includes(adptName)) { // list device only if selected adapter matched with device
|
|
1361
|
+
await this.createData(i);
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
await this.writeDatapoints(adptName); // fill the datapoints
|
|
1365
|
+
} catch (error) {
|
|
1366
|
+
this.errorReporting('[createDataForEachAdapter]', error);
|
|
1132
1367
|
}
|
|
1133
|
-
await this.writeDatapoints(adptName);
|
|
1134
1368
|
|
|
1135
|
-
this.log.debug(`Function finished: ${this.
|
|
1136
|
-
}
|
|
1369
|
+
this.log.debug(`Function finished: ${this.createDataForEachAdapter.name}`);
|
|
1370
|
+
} // <-- end of createDataForEachAdapter
|
|
1371
|
+
|
|
1372
|
+
async createDataOfAllAdapter() {
|
|
1373
|
+
// create Data of all selected adapter in one list
|
|
1374
|
+
this.log.debug(`Function started: ${this.createDataOfAllAdapter.name}`);
|
|
1375
|
+
|
|
1376
|
+
try {
|
|
1377
|
+
await this.resetVars(); // reset the arrays and counts
|
|
1137
1378
|
|
|
1138
|
-
|
|
1139
|
-
this.log.debug(`Function started: ${this.createDataOfAll.name}`);
|
|
1140
|
-
await this.resetVars();
|
|
1379
|
+
for (let i = 0; i < this.arrDev.length; i++) {
|
|
1141
1380
|
|
|
1142
|
-
|
|
1381
|
+
await this.createData(i);
|
|
1143
1382
|
|
|
1144
|
-
|
|
1383
|
+
}
|
|
1145
1384
|
|
|
1385
|
+
if (this.config.checkSendOfflineMsg) await this.sendOfflineNotifications(); // send message if new devices are offline
|
|
1386
|
+
if (this.config.checkSendOfflineMsgDaily) await this.sendDailyOfflineNotifications(); // send daily overview of offline devices
|
|
1387
|
+
if (this.config.checkSendBatteryMsg) await this.sendBatteryNotifications(); // send message for low battery devices
|
|
1388
|
+
await this.writeDatapoints(); // fill the datapoints
|
|
1389
|
+
} catch (error) {
|
|
1390
|
+
this.errorReporting('[createDataOfAllAdapter]', error);
|
|
1146
1391
|
}
|
|
1147
|
-
await this.writeDatapoints();
|
|
1148
1392
|
|
|
1149
|
-
this.log.debug(`Function finished: ${this.
|
|
1150
|
-
}
|
|
1393
|
+
this.log.debug(`Function finished: ${this.createDataOfAllAdapter.name}`);
|
|
1394
|
+
} // <-- end of createDataOfAllAdapter
|
|
1151
1395
|
|
|
1152
|
-
async resetVars() {
|
|
1153
|
-
// arrays
|
|
1154
|
-
this.offlineDevices = [],
|
|
1155
|
-
this.linkQualityDevices = [];
|
|
1156
|
-
this.batteryPowered = [];
|
|
1157
|
-
this.batteryLowPowered = [];
|
|
1158
|
-
this.listAllDevices = [];
|
|
1159
1396
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
this.lowBatteryPoweredCount = 0;
|
|
1397
|
+
/**
|
|
1398
|
+
* Notification service
|
|
1399
|
+
* @param {string} text - Text which should be send
|
|
1400
|
+
**/
|
|
1401
|
+
async sendNotification(text) {
|
|
1166
1402
|
|
|
1167
|
-
|
|
1168
|
-
|
|
1403
|
+
// Pushover
|
|
1404
|
+
try {
|
|
1405
|
+
if (this.config.instancePushover) {
|
|
1406
|
+
//first check if instance is living
|
|
1407
|
+
const pushoverAliveState = await this.getInitValue('system.adapter.' + this.config.instancePushover + '.alive');
|
|
1169
1408
|
|
|
1170
|
-
|
|
1171
|
-
|
|
1409
|
+
if (!pushoverAliveState) {
|
|
1410
|
+
this.log.warn('Pushover instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1411
|
+
} else {
|
|
1412
|
+
await this.sendToAsync(this.config.instancePushover, 'send', {
|
|
1413
|
+
message: text,
|
|
1414
|
+
title: this.config.titlePushover,
|
|
1415
|
+
device: this.config.devicePushover,
|
|
1416
|
+
priority: this.config.prioPushover
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
} catch (error) {
|
|
1421
|
+
this.errorReporting('[sendNotification Pushover]', error);
|
|
1422
|
+
}
|
|
1172
1423
|
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
sonoff: this.config.sonoffDevices,
|
|
1179
|
-
shelly: this.config.shellyDevices,
|
|
1180
|
-
homematic: this.config.homematicDevices,
|
|
1181
|
-
deconz: this.config.deconzDevices,
|
|
1182
|
-
zwave: this.config.zwaveDevices,
|
|
1183
|
-
dect: this.config.dectDevices,
|
|
1184
|
-
hue: this.config.hueDevices,
|
|
1185
|
-
hueExt: this.config.hueExtDevices,
|
|
1186
|
-
nukiExt: this.config.nukiExtDevices,
|
|
1187
|
-
ping: this.config.pingDevices,
|
|
1188
|
-
switchbotBle: this.config.switchbotBleDevices,
|
|
1189
|
-
sonos: this.config.sonosDevices,
|
|
1190
|
-
mihome: this.config.mihomeDevices,
|
|
1191
|
-
mihomeGW: this.config.mihomeDevices,
|
|
1192
|
-
};
|
|
1424
|
+
// Telegram
|
|
1425
|
+
try {
|
|
1426
|
+
if (this.config.instanceTelegram) {
|
|
1427
|
+
//first check if instance is living
|
|
1428
|
+
const telegramAliveState = await this.getInitValue('system.adapter.' + this.config.instanceTelegram + '.alive');
|
|
1193
1429
|
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1430
|
+
if (!telegramAliveState) {
|
|
1431
|
+
this.log.warn('Telegram instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1432
|
+
} else {
|
|
1433
|
+
await this.sendToAsync(this.config.instanceTelegram, 'send', {
|
|
1434
|
+
text: text,
|
|
1435
|
+
user: this.config.deviceTelegram,
|
|
1436
|
+
chatId: this.config.chatIdTelegram
|
|
1437
|
+
});
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
} catch (error) {
|
|
1441
|
+
this.errorReporting('[sendNotification Telegram]', error);
|
|
1442
|
+
}
|
|
1199
1443
|
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1444
|
+
// Whatsapp
|
|
1445
|
+
try {
|
|
1446
|
+
if (this.config.instanceWhatsapp) {
|
|
1447
|
+
//first check if instance is living
|
|
1448
|
+
const whatsappAliveState = await this.getInitValue('system.adapter.' + this.config.instanceWhatsapp + '.alive');
|
|
1449
|
+
|
|
1450
|
+
if (!whatsappAliveState) {
|
|
1451
|
+
this.log.warn('Whatsapp instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1452
|
+
} else {
|
|
1453
|
+
await this.sendToAsync(this.config.instanceWhatsapp, 'send', {
|
|
1454
|
+
text: text,
|
|
1455
|
+
phone: this.config.phoneWhatsapp
|
|
1456
|
+
});
|
|
1211
1457
|
}
|
|
1212
1458
|
}
|
|
1459
|
+
} catch (error) {
|
|
1460
|
+
this.errorReporting('[sendNotification Whatsapp]', error);
|
|
1213
1461
|
}
|
|
1214
1462
|
|
|
1215
|
-
//
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1463
|
+
// Email
|
|
1464
|
+
try {
|
|
1465
|
+
if (this.config.instanceEmail) {
|
|
1466
|
+
//first check if instance is living
|
|
1467
|
+
const eMailAliveState = await this.getInitValue('system.adapter.' + this.config.instanceEmail + '.alive');
|
|
1468
|
+
|
|
1469
|
+
if (!eMailAliveState) {
|
|
1470
|
+
this.log.warn('eMail instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1471
|
+
} else {
|
|
1472
|
+
await this.sendToAsync(this.config.instanceEmail, 'send', {
|
|
1473
|
+
sendTo: this.config.sendToEmail,
|
|
1474
|
+
text: text,
|
|
1475
|
+
subject: this.config.subjectEmail
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
} catch (error) {
|
|
1480
|
+
this.errorReporting('[sendNotification eMail]', error);
|
|
1221
1481
|
}
|
|
1222
1482
|
|
|
1223
|
-
|
|
1224
|
-
= Start of main loop =
|
|
1225
|
-
=============================================*/
|
|
1483
|
+
// Jarvis Notification
|
|
1226
1484
|
try {
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1485
|
+
if (this.config.instanceJarvis) {
|
|
1486
|
+
//first check if instance is living
|
|
1487
|
+
const jarvisAliveState = await this.getInitValue('system.adapter.' + this.config.instanceJarvis + '.alive');
|
|
1488
|
+
|
|
1489
|
+
if (!jarvisAliveState) {
|
|
1490
|
+
this.log.warn('Jarvis instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1491
|
+
} else {
|
|
1492
|
+
const jsonText = JSON.stringify(text);
|
|
1493
|
+
await this.setForeignStateAsync(`${this.config.instanceJarvis}.addNotification`, '{"title":"' + this.config.titleJarvis + ' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message": ' + jsonText + ',"display": "drawer"}');
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
} catch (error) {
|
|
1497
|
+
this.errorReporting('[sendNotification Jarvis]', error);
|
|
1232
1498
|
}
|
|
1233
1499
|
|
|
1234
|
-
|
|
1235
|
-
|
|
1500
|
+
// Lovelace Notification
|
|
1501
|
+
try {
|
|
1502
|
+
if (this.config.instanceLovelace) {
|
|
1503
|
+
//first check if instance is living
|
|
1504
|
+
const lovelaceAliveState = await this.getInitValue('system.adapter.' + this.config.instanceLovelace + '.alive');
|
|
1505
|
+
|
|
1506
|
+
if (!lovelaceAliveState) {
|
|
1507
|
+
this.log.warn('Lovelace instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
1508
|
+
} else {
|
|
1509
|
+
const jsonText = JSON.stringify(text);
|
|
1510
|
+
await this.setForeignStateAsync(`${this.config.instanceLovelace}.notifications.add`, '{"message":' + jsonText + ', "title":"' + this.config.titleLovelace + ' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')"}');
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
} catch (error) {
|
|
1514
|
+
this.errorReporting('[sendNotification Lovelace]', error);
|
|
1515
|
+
}
|
|
1516
|
+
} // <-- End of sendNotification function
|
|
1236
1517
|
|
|
1237
1518
|
|
|
1238
1519
|
async sendOfflineNotifications() {
|
|
1239
|
-
|
|
1240
|
-
= send offline notification =
|
|
1241
|
-
=============================================*/
|
|
1520
|
+
// send message if an device is offline
|
|
1242
1521
|
|
|
1243
1522
|
this.log.debug(`Start the function: ${this.sendOfflineNotifications.name}`);
|
|
1244
1523
|
|
|
@@ -1246,8 +1525,10 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1246
1525
|
let msg = '';
|
|
1247
1526
|
const offlineDevicesCountOld = await this.getOwnInitValue('offlineCount');
|
|
1248
1527
|
|
|
1249
|
-
if ((this.offlineDevicesCount
|
|
1250
|
-
if (this.offlineDevicesCount ==
|
|
1528
|
+
if ((this.offlineDevicesCount !== offlineDevicesCountOld)) {
|
|
1529
|
+
if (this.offlineDevicesCount == 0) {
|
|
1530
|
+
msg = 'Alle Geräte sind Online.';
|
|
1531
|
+
} else if (this.offlineDevicesCount == 1) { // make singular if it is only one device
|
|
1251
1532
|
msg = 'Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n';
|
|
1252
1533
|
} else if (this.offlineDevicesCount >= 2) { //make plural if it is more than one device
|
|
1253
1534
|
msg = `Folgende ${this.offlineDevicesCount} Geräte sind seit einiger Zeit nicht erreichbar: \n`;
|
|
@@ -1256,246 +1537,385 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1256
1537
|
for (const id of this.offlineDevices) {
|
|
1257
1538
|
msg = `${msg} \n ${id['Device']} (${id['Last contact']})`;
|
|
1258
1539
|
}
|
|
1540
|
+
|
|
1259
1541
|
this.log.info(msg);
|
|
1260
1542
|
await this.setStateAsync('lastNotification', msg, true);
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
if (this.
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
try {
|
|
1284
|
-
await this.sendEmail(msg);
|
|
1285
|
-
} catch (e) {
|
|
1286
|
-
this.log.warn (`Getting error at sending email notification ${e}`);
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
if (this.config.instanceJarvis) {
|
|
1290
|
-
try {
|
|
1291
|
-
await this.sendJarvis('{"title":"'+ this.config.titleJarvis +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message":" ' + this.offlineDevicesCount + ' Geräte sind nicht erreichbar","display": "drawer"}');
|
|
1292
|
-
} catch (e) {
|
|
1293
|
-
this.log.warn (`Getting error at sending jarvis notification ${e}`);
|
|
1543
|
+
await this.sendNotification(msg);
|
|
1544
|
+
}
|
|
1545
|
+
} catch (error) {
|
|
1546
|
+
this.errorReporting('[sendOfflineMessage]', error);
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
try {
|
|
1550
|
+
// send daily an overview with offline devices
|
|
1551
|
+
if (this.config.checkSendOfflineMsgDaily) {
|
|
1552
|
+
// Check if the daily message for offline devices was already sent today
|
|
1553
|
+
const lastOfflineNotifyIndicator = await this.getOwnInitValue('info.lastOfflineNotification');
|
|
1554
|
+
const now = new Date(); // get date
|
|
1555
|
+
|
|
1556
|
+
// set indicator for send message first to 'false', after sending to 'true'
|
|
1557
|
+
if (now.getHours() < 11) await this.setStateAsync('info.lastOfflineNotification', false, true);
|
|
1558
|
+
|
|
1559
|
+
// if time is > 11 (12:00 pm create message for offline devices devices)
|
|
1560
|
+
if ((now.getHours() > 11) && (!lastOfflineNotifyIndicator)) {
|
|
1561
|
+
let msg = '';
|
|
1562
|
+
|
|
1563
|
+
for (const id of this.offlineDevices) {
|
|
1564
|
+
msg = `${msg} \n ${id['Device']} (${id['Last contact']})`;
|
|
1294
1565
|
}
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
await this.
|
|
1299
|
-
|
|
1300
|
-
this.
|
|
1566
|
+
|
|
1567
|
+
if (this.offlineDevicesCount > 0) {
|
|
1568
|
+
this.log.info(`Geräte Offline: ${msg}`);
|
|
1569
|
+
await this.setStateAsync('lastNotification', `Geräte Offline: ${msg}`, true);
|
|
1570
|
+
|
|
1571
|
+
await this.sendNotification(`Geräte Offline: ${msg}`);
|
|
1572
|
+
|
|
1573
|
+
await this.setStateAsync('info.lastOfflineNotification', true, true);
|
|
1301
1574
|
}
|
|
1302
1575
|
}
|
|
1303
1576
|
}
|
|
1304
|
-
} catch (
|
|
1305
|
-
this.
|
|
1577
|
+
} catch (error) {
|
|
1578
|
+
this.errorReporting('[sendOfflineMessage - daily message]', error);
|
|
1306
1579
|
}
|
|
1307
1580
|
this.log.debug(`Finished the function: ${this.sendOfflineNotifications.name}`);
|
|
1308
1581
|
}//<--End of offline notification
|
|
1309
1582
|
|
|
1583
|
+
async sendDailyOfflineNotifications() {
|
|
1584
|
+
// send daily an overview with offline devices
|
|
1310
1585
|
|
|
1311
|
-
|
|
1312
|
-
/*=============================================
|
|
1313
|
-
= send low battery notification =
|
|
1314
|
-
=============================================*/
|
|
1586
|
+
this.log.debug(`Start the function: ${this.sendDailyOfflineNotifications.name}`);
|
|
1315
1587
|
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
let checkToday;
|
|
1321
|
-
|
|
1322
|
-
const choosedDays = {
|
|
1323
|
-
monday: this.config.checkMonday,
|
|
1324
|
-
tuesday: this.config.checkTuesday,
|
|
1325
|
-
wednesday: this.config.checkWednesday,
|
|
1326
|
-
thursday: this.config.checkThursday,
|
|
1327
|
-
friday: this.config.checkFriday,
|
|
1328
|
-
saturday: this.config.checkSaturday,
|
|
1329
|
-
sunday: this.config.checkSunday,
|
|
1330
|
-
};
|
|
1588
|
+
try {
|
|
1589
|
+
// Check if the daily message for offline devices was already sent today
|
|
1590
|
+
const lastOfflineNotifyIndicator = await this.getOwnInitValue('info.lastOfflineNotification');
|
|
1591
|
+
const now = new Date(); // get date
|
|
1331
1592
|
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
if (choosedDays.wednesday) checkDays.push(3);
|
|
1335
|
-
if (choosedDays.thursday) checkDays.push(4);
|
|
1336
|
-
if (choosedDays.friday) checkDays.push(5);
|
|
1337
|
-
if (choosedDays.saturday) checkDays.push(6);
|
|
1338
|
-
if (choosedDays.sunday) checkDays.push(0);
|
|
1339
|
-
|
|
1340
|
-
//Check if the message should be send today
|
|
1341
|
-
checkDays.forEach(object => {
|
|
1342
|
-
if((object >= 0) && today == object){
|
|
1343
|
-
checkToday = true;
|
|
1344
|
-
}
|
|
1345
|
-
});
|
|
1593
|
+
// set indicator for send message first to 'false', after sending to 'true'
|
|
1594
|
+
if (now.getHours() < 11) await this.setStateAsync('info.lastOfflineNotification', false, true);
|
|
1346
1595
|
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1596
|
+
// if time is > 11 (12:00 pm create message for offline devices devices)
|
|
1597
|
+
if ((now.getHours() > 11) && (!lastOfflineNotifyIndicator)) {
|
|
1598
|
+
let msg = '';
|
|
1599
|
+
|
|
1600
|
+
for (const id of this.offlineDevices) {
|
|
1601
|
+
msg = `${msg} \n ${id['Device']} (${id['Last contact']})`;
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
if (this.offlineDevicesCount > 0) {
|
|
1605
|
+
this.log.info(`Geräte Offline: ${msg}`);
|
|
1606
|
+
await this.setStateAsync('lastNotification', `Geräte Offline: ${msg}`, true);
|
|
1607
|
+
|
|
1608
|
+
await this.sendNotification(`Geräte Offline: ${msg}`);
|
|
1609
|
+
|
|
1610
|
+
await this.setStateAsync('info.lastOfflineNotification', true, true);
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
} catch (error) {
|
|
1614
|
+
this.errorReporting('[sendDailyOfflineNotifications]', error);
|
|
1353
1615
|
}
|
|
1616
|
+
this.log.debug(`Finished the function: ${this.sendDailyOfflineNotifications.name}`);
|
|
1617
|
+
}//<--End of daily offline notification
|
|
1618
|
+
|
|
1619
|
+
async sendBatteryNotifications() {
|
|
1620
|
+
// send message for low battery devices
|
|
1621
|
+
|
|
1622
|
+
this.log.debug(`Start the function: ${this.sendBatteryNotifications.name}`);
|
|
1354
1623
|
|
|
1355
1624
|
try {
|
|
1356
|
-
|
|
1625
|
+
|
|
1626
|
+
const now = new Date(); // get date
|
|
1627
|
+
const today = now.getDay();
|
|
1628
|
+
const checkDays = []; // list of selected days
|
|
1629
|
+
let checkToday; // indicator if selected day is today
|
|
1630
|
+
|
|
1631
|
+
// push the selected days in list
|
|
1632
|
+
if (this.config.checkMonday) checkDays.push(1);
|
|
1633
|
+
if (this.config.checkTuesday) checkDays.push(2);
|
|
1634
|
+
if (this.config.checkWednesday) checkDays.push(3);
|
|
1635
|
+
if (this.config.checkThursday) checkDays.push(4);
|
|
1636
|
+
if (this.config.checkFriday) checkDays.push(5);
|
|
1637
|
+
if (this.config.checkSaturday) checkDays.push(6);
|
|
1638
|
+
if (this.config.checkSunday) checkDays.push(0);
|
|
1639
|
+
|
|
1640
|
+
//Check if the message should be send today
|
|
1641
|
+
checkDays.forEach(object => {
|
|
1642
|
+
if ((object >= 0) && today == object) {
|
|
1643
|
+
checkToday = true;
|
|
1644
|
+
}
|
|
1645
|
+
});
|
|
1646
|
+
|
|
1647
|
+
if (checkDays.length >= 1) { // check if an day is selected
|
|
1648
|
+
this.log.debug(`Number of selected days: ${checkDays.length}. Send Message on: ${(checkDays).join(', ')} ...`);
|
|
1649
|
+
} else {
|
|
1650
|
+
this.log.warn(`No days selected. Please check the instance configuration!`);
|
|
1651
|
+
return; // break off function if no day is selected
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
// Check if the message for low battery was already sent today
|
|
1357
1655
|
const lastBatteryNotifyIndicator = await this.getOwnInitValue('info.lastBatteryNotification');
|
|
1358
1656
|
|
|
1359
|
-
|
|
1360
|
-
if (
|
|
1361
|
-
|
|
1657
|
+
// set indicator for send message first to 'false', after sending to 'true'
|
|
1658
|
+
if (now.getHours() < 11) await this.setStateAsync('info.lastBatteryNotification', false, true);
|
|
1659
|
+
|
|
1660
|
+
// if time is > 11 (12:00 pm create message for low battery devices)
|
|
1661
|
+
if ((now.getHours() > 11) && (!lastBatteryNotifyIndicator) && (checkToday != undefined)) {
|
|
1662
|
+
let msg = '';
|
|
1362
1663
|
|
|
1363
1664
|
for (const id of this.batteryLowPowered) {
|
|
1364
|
-
|
|
1665
|
+
msg = '\n' + id['Device'] + ' (' + id['Battery'] + ')'.split(', ');
|
|
1365
1666
|
}
|
|
1366
1667
|
|
|
1367
1668
|
if (this.lowBatteryPoweredCount > 0) {
|
|
1368
|
-
this.log.info(`Niedrige Batteriezustände: ${
|
|
1369
|
-
await this.setStateAsync('lastNotification', `Niedrige Batteriezustände: ${
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
try {
|
|
1373
|
-
await this.sendPushover(`Niedrige Batteriezustände: ${infotext}`);
|
|
1374
|
-
} catch (e) {
|
|
1375
|
-
this.log.warn (`Getting error at sending pushover notification ${e}`);
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
if (this.config.instanceTelegram) {
|
|
1379
|
-
try {
|
|
1380
|
-
await this.sendTelegram(`Niedrige Batteriezustände: ${infotext}`);
|
|
1381
|
-
} catch (e) {
|
|
1382
|
-
this.log.warn (`Getting error at sending telegram notification ${e}`);
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
if (this.config.instanceWhatsapp) {
|
|
1386
|
-
try {
|
|
1387
|
-
await this.sendWhatsapp(`Niedrige Batteriezustände: ${infotext}`);
|
|
1388
|
-
} catch (e) {
|
|
1389
|
-
this.log.warn (`Getting error at sending whatsapp notification ${e}`);
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
if (this.config.instanceEmail) {
|
|
1393
|
-
try {
|
|
1394
|
-
await this.sendEmail(`Niedrige Batteriezustände: ${infotext}`);
|
|
1395
|
-
} catch (e) {
|
|
1396
|
-
this.log.warn (`Getting error at sending email notification ${e}`);
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
if (this.config.instanceJarvis) {
|
|
1400
|
-
try {
|
|
1401
|
-
await this.sendJarvis('{"title":"'+ this.config.titleJarvis +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message":" ' + this.lowBatteryPoweredCount + ' Geräte mit schwacher Batterie","display": "drawer"}');
|
|
1402
|
-
} catch (e) {
|
|
1403
|
-
this.log.warn (`Getting error at sending jarvis notification ${e}`);
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
if (this.config.instanceLovelace) {
|
|
1407
|
-
try {
|
|
1408
|
-
await this.sendLovelace('{"message":" ' + this.lowBatteryPoweredCount + ' Geräte mit schwacher Batterie", "title":"'+ this.config.titleLovelace +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')"}');
|
|
1409
|
-
} catch (e) {
|
|
1410
|
-
this.log.warn (`Getting error at sending lovelace notification ${e}`);
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1669
|
+
this.log.info(`Niedrige Batteriezustände: ${msg}`);
|
|
1670
|
+
await this.setStateAsync('lastNotification', `Niedrige Batteriezustände: ${msg}`, true);
|
|
1671
|
+
|
|
1672
|
+
await this.sendNotification(`Niedriege Batteriezustände: ${msg}`);
|
|
1413
1673
|
|
|
1414
1674
|
await this.setStateAsync('info.lastBatteryNotification', true, true);
|
|
1415
1675
|
}
|
|
1416
1676
|
}
|
|
1417
|
-
} catch (
|
|
1418
|
-
this.
|
|
1677
|
+
} catch (error) {
|
|
1678
|
+
this.errorReporting('[sendOfflineMessage]', error);
|
|
1419
1679
|
}
|
|
1680
|
+
|
|
1420
1681
|
this.log.debug(`Finished the function: ${this.sendBatteryNotifications.name}`);
|
|
1421
1682
|
}//<--End of battery notification
|
|
1422
1683
|
|
|
1684
|
+
|
|
1685
|
+
async resetVars() {
|
|
1686
|
+
//Reset all arrays and counts
|
|
1687
|
+
this.log.debug(`Function started: ${this.resetVars.name}`);
|
|
1688
|
+
|
|
1689
|
+
// arrays
|
|
1690
|
+
this.offlineDevices = [];
|
|
1691
|
+
this.linkQualityDevices = [];
|
|
1692
|
+
this.batteryPowered = [];
|
|
1693
|
+
this.batteryLowPowered = [];
|
|
1694
|
+
this.listAllDevices = [];
|
|
1695
|
+
|
|
1696
|
+
// counts
|
|
1697
|
+
this.offlineDevicesCount = 0;
|
|
1698
|
+
this.deviceCounter = 0;
|
|
1699
|
+
this.linkQualityCount = 0;
|
|
1700
|
+
this.batteryPoweredCount = 0;
|
|
1701
|
+
this.lowBatteryPoweredCount = 0;
|
|
1702
|
+
|
|
1703
|
+
this.deviceReachable = '';
|
|
1704
|
+
|
|
1705
|
+
this.log.debug(`Function finished: ${this.resetVars.name}`);
|
|
1706
|
+
} // <-- end of resetVars
|
|
1707
|
+
|
|
1708
|
+
|
|
1709
|
+
/**
|
|
1710
|
+
* @param {string} [adptName] - Adaptername
|
|
1711
|
+
*/
|
|
1423
1712
|
async writeDatapoints(adptName) {
|
|
1424
|
-
|
|
1425
|
-
= Write Datapoints =
|
|
1426
|
-
=============================================*/
|
|
1713
|
+
// fill the datapoints
|
|
1427
1714
|
|
|
1428
1715
|
this.log.debug(`Start the function: ${this.writeDatapoints.name}`);
|
|
1429
1716
|
|
|
1430
1717
|
try {
|
|
1431
1718
|
|
|
1432
1719
|
let dpSubFolder;
|
|
1433
|
-
|
|
1720
|
+
//write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
|
|
1721
|
+
if (adptName) {
|
|
1434
1722
|
dpSubFolder = adptName + '.';
|
|
1435
1723
|
} else {
|
|
1436
|
-
dpSubFolder = '';
|
|
1724
|
+
dpSubFolder = '';
|
|
1725
|
+
}
|
|
1437
1726
|
|
|
1438
|
-
await this.setStateAsync(`${dpSubFolder}offlineCount`, {val: this.offlineDevicesCount, ack: true});
|
|
1439
|
-
await this.setStateAsync(`${dpSubFolder}countAll`, {val: this.deviceCounter, ack: true});
|
|
1440
|
-
await this.setStateAsync(`${dpSubFolder}batteryCount`, {val: this.batteryPoweredCount, ack: true});
|
|
1441
|
-
await this.setStateAsync(`${dpSubFolder}lowBatteryCount`, {val: this.lowBatteryPoweredCount, ack: true});
|
|
1727
|
+
await this.setStateAsync(`${dpSubFolder}offlineCount`, { val: this.offlineDevicesCount, ack: true });
|
|
1728
|
+
await this.setStateAsync(`${dpSubFolder}countAll`, { val: this.deviceCounter, ack: true });
|
|
1729
|
+
await this.setStateAsync(`${dpSubFolder}batteryCount`, { val: this.batteryPoweredCount, ack: true });
|
|
1730
|
+
await this.setStateAsync(`${dpSubFolder}lowBatteryCount`, { val: this.lowBatteryPoweredCount, ack: true });
|
|
1442
1731
|
|
|
1443
1732
|
if (this.deviceCounter == 0) {
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
await this.setStateAsync(`${dpSubFolder}listAll`, {val: JSON.stringify(this.listAllDevices), ack: true});
|
|
1447
|
-
} else {
|
|
1448
|
-
await this.setStateAsync(`${dpSubFolder}listAll`, {val: JSON.stringify(this.listAllDevices), ack: true});
|
|
1733
|
+
// if no device is count, write the JSON List with default value
|
|
1734
|
+
this.listAllDevices = [{ 'Device': '--none--', 'Adapter': '', 'Battery': '', 'Last contact': '', 'Signal strength': '' }];
|
|
1449
1735
|
}
|
|
1736
|
+
await this.setStateAsync(`${dpSubFolder}listAll`, { val: JSON.stringify(this.listAllDevices), ack: true });
|
|
1450
1737
|
|
|
1451
1738
|
if (this.linkQualityCount == 0) {
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
await this.setStateAsync(`${dpSubFolder}linkQualityList`, {val: JSON.stringify(this.linkQualityDevices), ack: true});
|
|
1455
|
-
} else {
|
|
1456
|
-
await this.setStateAsync(`${dpSubFolder}linkQualityList`, {val: JSON.stringify(this.linkQualityDevices), ack: true});
|
|
1739
|
+
// if no device is count, write the JSON List with default value
|
|
1740
|
+
this.linkQualityDevices = [{ 'Device': '--none--', 'Adapter': '', 'Signal strength': '' }];
|
|
1457
1741
|
}
|
|
1458
|
-
|
|
1742
|
+
//write JSON list
|
|
1743
|
+
await this.setStateAsync(`${dpSubFolder}linkQualityList`, { val: JSON.stringify(this.linkQualityDevices), ack: true });
|
|
1744
|
+
//write HTML list
|
|
1745
|
+
if (this.config.createHtmlList) await this.setStateAsync(`${dpSubFolder}linkQualityListHTML`, { val: await this.creatLinkQualityListHTML(this.linkQualityDevices, this.linkQualityCount), ack: true });
|
|
1459
1746
|
|
|
1460
1747
|
if (this.offlineDevicesCount == 0) {
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
await this.setStateAsync(`${dpSubFolder}offlineList`, {val: JSON.stringify(this.offlineDevices), ack: true});
|
|
1464
|
-
} else {
|
|
1465
|
-
await this.setStateAsync(`${dpSubFolder}offlineList`, {val: JSON.stringify(this.offlineDevices), ack: true});
|
|
1748
|
+
// if no device is count, write the JSON List with default value
|
|
1749
|
+
this.offlineDevices = [{ 'Device': '--none--', 'Adapter': '', 'Last contact': '' }];
|
|
1466
1750
|
}
|
|
1751
|
+
//write JSON list
|
|
1752
|
+
await this.setStateAsync(`${dpSubFolder}offlineList`, { val: JSON.stringify(this.offlineDevices), ack: true });
|
|
1753
|
+
//write HTML list
|
|
1754
|
+
if (this.config.createHtmlList) await this.setStateAsync(`${dpSubFolder}offlineListHTML`, { val: await this.createOfflineListHTML(this.offlineDevices, this.offlineDevicesCount), ack: true });
|
|
1467
1755
|
|
|
1468
1756
|
if (this.batteryPoweredCount == 0) {
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
await this.setStateAsync(`${dpSubFolder}batteryList`, {val: JSON.stringify(this.batteryPowered), ack: true});
|
|
1472
|
-
} else {
|
|
1473
|
-
await this.setStateAsync(`${dpSubFolder}batteryList`, {val: JSON.stringify(this.batteryPowered), ack: true});
|
|
1757
|
+
// if no device is count, write the JSON List with default value
|
|
1758
|
+
this.batteryPowered = [{ 'Device': '--none--', 'Adapter': '', 'Battery': '' }];
|
|
1474
1759
|
}
|
|
1760
|
+
//write JSON list
|
|
1761
|
+
await this.setStateAsync(`${dpSubFolder}batteryList`, { val: JSON.stringify(this.batteryPowered), ack: true });
|
|
1762
|
+
//write HTML list
|
|
1763
|
+
if (this.config.createHtmlList) await this.setStateAsync(`${dpSubFolder}batteryListHTML`, { val: await this.createBatteryListHTML(this.batteryPowered, this.batteryPoweredCount, false), ack: true });
|
|
1475
1764
|
|
|
1476
1765
|
if (this.lowBatteryPoweredCount == 0) {
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {val: JSON.stringify(this.batteryLowPowered), ack: true});
|
|
1480
|
-
} else {
|
|
1481
|
-
await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {val: JSON.stringify(this.batteryLowPowered), ack: true});
|
|
1766
|
+
// if no device is count, write the JSON List with default value
|
|
1767
|
+
this.batteryLowPowered = [{ 'Device': '--none--', 'Adapter': '', 'Battery': '' }];
|
|
1482
1768
|
}
|
|
1769
|
+
//write JSON list
|
|
1770
|
+
await this.setStateAsync(`${dpSubFolder}lowBatteryList`, { val: JSON.stringify(this.batteryLowPowered), ack: true });
|
|
1771
|
+
//write HTML list
|
|
1772
|
+
if (this.config.createHtmlList) await this.setStateAsync(`${dpSubFolder}lowBatteryListHTML`, { val: await this.createBatteryListHTML(this.batteryLowPowered, this.lowBatteryPoweredCount, true), ack: true });
|
|
1483
1773
|
|
|
1484
|
-
//
|
|
1774
|
+
// create timestamp of last run
|
|
1485
1775
|
const lastCheck = this.formatDate(new Date(), 'DD.MM.YYYY') + ' - ' + this.formatDate(new Date(), 'hh:mm:ss');
|
|
1486
1776
|
await this.setStateAsync('lastCheck', lastCheck, true);
|
|
1487
1777
|
}
|
|
1488
|
-
catch (
|
|
1489
|
-
this.
|
|
1778
|
+
catch (error) {
|
|
1779
|
+
this.errorReporting('[writeDatapoints]', error);
|
|
1490
1780
|
}
|
|
1491
1781
|
this.log.debug(`Function finished: ${this.writeDatapoints.name}`);
|
|
1492
1782
|
}//<--End of writing Datapoints
|
|
1493
1783
|
|
|
1784
|
+
/**
|
|
1785
|
+
* @param {object} devices - Device
|
|
1786
|
+
* @param {number} deviceCount - Counted devices
|
|
1787
|
+
*/
|
|
1788
|
+
async creatLinkQualityListHTML(devices, deviceCount) {
|
|
1789
|
+
devices = devices.sort((a, b) => { return a.Device.localeCompare(b.Device); });
|
|
1790
|
+
let html = `<center>
|
|
1791
|
+
<b>Link Quality Devices:<font> ${deviceCount}</b><small></small></font>
|
|
1792
|
+
<p></p>
|
|
1793
|
+
</center>
|
|
1794
|
+
<table width=100%>
|
|
1795
|
+
<tr>
|
|
1796
|
+
<th align=left>Device</th>
|
|
1797
|
+
<th align=center width=120>Adapter</th>
|
|
1798
|
+
<th align=right>Link Quality</th>
|
|
1799
|
+
</tr>
|
|
1800
|
+
<tr>
|
|
1801
|
+
<td colspan="5"><hr></td>
|
|
1802
|
+
</tr>`;
|
|
1803
|
+
|
|
1804
|
+
for (const device of devices) {
|
|
1805
|
+
html += `<tr>
|
|
1806
|
+
<td><font>${device.Device}</font></td>
|
|
1807
|
+
<td align=center><font>${device.Adapter}</font></td>
|
|
1808
|
+
<td align=right><font>${device['Signal strength']}</font></td>
|
|
1809
|
+
</tr>`;
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
html += '</table>';
|
|
1813
|
+
return html;
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
/**
|
|
1817
|
+
* @param {object} devices - Device
|
|
1818
|
+
* @param {number} deviceCount - Counted devices
|
|
1819
|
+
*/
|
|
1820
|
+
async createOfflineListHTML(devices, deviceCount) {
|
|
1821
|
+
devices = devices.sort((a, b) => { return a.Device.localeCompare(b.Device); });
|
|
1822
|
+
let html = `<center>
|
|
1823
|
+
<b>Offline Devices: <font color=${deviceCount == 0 ? '#3bcf0e' : 'orange'}>${deviceCount}</b><small></small></font>
|
|
1824
|
+
<p></p>
|
|
1825
|
+
</center>
|
|
1826
|
+
<table width=100%>
|
|
1827
|
+
<tr>
|
|
1828
|
+
<th align=left>Device</th>
|
|
1829
|
+
<th align=center width=120>Adapter</th>
|
|
1830
|
+
<th align=center>Letzter Kontakt</th>
|
|
1831
|
+
</tr>
|
|
1832
|
+
<tr>
|
|
1833
|
+
<td colspan="5"><hr></td>
|
|
1834
|
+
</tr>`;
|
|
1835
|
+
|
|
1836
|
+
for (const device of devices) {
|
|
1837
|
+
html += `<tr>
|
|
1838
|
+
<td><font>${device.Device}</font></td>
|
|
1839
|
+
<td align=center><font>${device.Adapter}</font></td>
|
|
1840
|
+
<td align=center><font color=orange>${device['Last contact']}</font></td>
|
|
1841
|
+
</tr>`;
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
html += '</table>';
|
|
1845
|
+
return html;
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
/**
|
|
1849
|
+
* @param {object} [devices] - Device
|
|
1850
|
+
* @param {object} [deviceCount] - Counted devices
|
|
1851
|
+
* @param {object} [isLowBatteryList] - list Low Battery Devices
|
|
1852
|
+
*/
|
|
1853
|
+
async createBatteryListHTML(devices, deviceCount, isLowBatteryList) {
|
|
1854
|
+
devices = devices.sort((a, b) => { return a.Device.localeCompare(b.Device); });
|
|
1855
|
+
let html = `<center>
|
|
1856
|
+
<b>${isLowBatteryList == true ? 'Schwache ' : ''}Batterie Devices: <font color=${isLowBatteryList == true ? (deviceCount > 0 ? 'orange' : '#3bcf0e') : ''}>${deviceCount}</b></font>
|
|
1857
|
+
<p></p>
|
|
1858
|
+
</center>
|
|
1859
|
+
<table width=100%>
|
|
1860
|
+
<tr>
|
|
1861
|
+
<th align=left>Device</th>
|
|
1862
|
+
<th align=center width=120>Adapter</th>
|
|
1863
|
+
<th align=${isLowBatteryList ? 'center' : 'right'}>Batterie</th>
|
|
1864
|
+
</tr>
|
|
1865
|
+
<tr>
|
|
1866
|
+
<td colspan="5"><hr></td>
|
|
1867
|
+
</tr>`;
|
|
1868
|
+
|
|
1869
|
+
for (const device of devices) {
|
|
1870
|
+
html += `<tr>
|
|
1871
|
+
<td><font>${device.Device}</font></td>
|
|
1872
|
+
<td align=center><font>${device.Adapter}</font></td>`;
|
|
1873
|
+
|
|
1874
|
+
if (isLowBatteryList) {
|
|
1875
|
+
html += `<td align=center><font color=orange>${device.Battery}</font></td>`;
|
|
1876
|
+
} else {
|
|
1877
|
+
html += `<td align=right><font color=#3bcf0e>${device.Battery}</font></td>`;
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
html += `</tr>`;
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
html += '</table>';
|
|
1884
|
+
return html;
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
/**
|
|
1888
|
+
* @param {string} codePart - Message Prefix
|
|
1889
|
+
* @param {object} error - Sentry message
|
|
1890
|
+
*/
|
|
1891
|
+
errorReporting(codePart, error) {
|
|
1892
|
+
const msg = `[${codePart}] error: ${error.message}`;
|
|
1893
|
+
if (enableSendSentry) {
|
|
1894
|
+
if (this.supportsFeature && this.supportsFeature('PLUGINS')) {
|
|
1895
|
+
const sentryInstance = this.getPluginInstance('sentry');
|
|
1896
|
+
if (sentryInstance) {
|
|
1897
|
+
this.log.warn(`Error catched and sent to Sentry, error: ${msg}`);
|
|
1898
|
+
sentryInstance.getSentryObject().captureException(msg);
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
} else {
|
|
1902
|
+
this.log.error(`Sentry disabled, error catched : ${msg}`);
|
|
1903
|
+
}
|
|
1904
|
+
} // <-- end of errorReporting
|
|
1494
1905
|
|
|
1495
1906
|
|
|
1907
|
+
/**
|
|
1908
|
+
* @param {() => void} callback
|
|
1909
|
+
*/
|
|
1496
1910
|
onUnload(callback) {
|
|
1497
1911
|
try {
|
|
1498
1912
|
this.log.info('cleaned everything up...');
|
|
1913
|
+
|
|
1914
|
+
if (this.refreshDataTimeout) {
|
|
1915
|
+
this.log.debug('clearing refresh timeout');
|
|
1916
|
+
this.clearTimeout(this.refreshDataTimeout);
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1499
1919
|
callback();
|
|
1500
1920
|
} catch (e) {
|
|
1501
1921
|
callback();
|
|
@@ -1503,6 +1923,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1503
1923
|
}
|
|
1504
1924
|
}
|
|
1505
1925
|
|
|
1926
|
+
// @ts-ignore parent is a valid property on module
|
|
1506
1927
|
if (require.main !== module) {
|
|
1507
1928
|
// Export the constructor in compact mode
|
|
1508
1929
|
/**
|