iobroker.device-watcher 2.13.1 → 2.15.0-alpha.1
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 +26 -415
- package/admin/jsonConfig.json5 +1524 -2856
- package/io-package.json +544 -225
- package/lib/{arrApart.js → adapterArray.js} +809 -669
- package/lib/crud.js +1985 -1932
- package/lib/tools.js +158 -155
- package/lib/translations.js +26 -0
- package/main.js +384 -438
- package/package.json +16 -20
package/main.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
const utils = require('@iobroker/adapter-core');
|
|
4
4
|
const adapterName = require('./package.json').name.split('.').pop();
|
|
5
5
|
const schedule = require('node-schedule');
|
|
6
|
-
const
|
|
6
|
+
const cronParserLib = require('cron-parser');
|
|
7
|
+
const adapterArray = require('./lib/adapterArray.js'); // list of supported adapters
|
|
7
8
|
const translations = require('./lib/translations.js');
|
|
8
9
|
const tools = require('./lib/tools.js');
|
|
9
10
|
const crud = require('./lib/crud.js');
|
|
@@ -90,9 +91,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
90
91
|
this.on('objectChange', this.onObjectChange.bind(this));
|
|
91
92
|
this.on('message', this.onMessage.bind(this));
|
|
92
93
|
this.on('unload', this.onUnload.bind(this));
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
94
|
}
|
|
97
95
|
|
|
98
96
|
/**
|
|
@@ -116,146 +114,23 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
116
114
|
this.configCreateOwnFolder = this.config.createOwnFolder;
|
|
117
115
|
this.configCreateHtmlList = this.config.createHtmlList;
|
|
118
116
|
|
|
119
|
-
this.configSetAdapter = {
|
|
120
|
-
alexa2: this.config.alexa2Devices,
|
|
121
|
-
apcups: this.config.apcupsDevices,
|
|
122
|
-
ble: this.config.bleDevices,
|
|
123
|
-
deconz: this.config.deconzDevices,
|
|
124
|
-
ecovacsdeebot: this.config.ecovacsdeebotDevices,
|
|
125
|
-
enocean: this.config.enoceanDevices,
|
|
126
|
-
esphome: this.config.esphomeDevices,
|
|
127
|
-
eusec: this.config.eusecDevices,
|
|
128
|
-
fhemTFAsensors: this.config.fhemTFAsensorsDevices,
|
|
129
|
-
fritzdect: this.config.fritzdectDevices,
|
|
130
|
-
fullybrowser: this.config.fullybrowserDevices,
|
|
131
|
-
fullybrowserV3: this.config.fullybrowserV3Devices,
|
|
132
|
-
fullyMQTT: this.config.fullyMQTTDevices,
|
|
133
|
-
ham: this.config.hamDevices,
|
|
134
|
-
harmony: this.config.harmonyDevices,
|
|
135
|
-
hmiP: this.config.hmiPDevices,
|
|
136
|
-
hmrpc: this.config.hmrpcDevices,
|
|
137
|
-
homeconnect: this.config.homeconnectDevices,
|
|
138
|
-
homekitController: this.config.homekitControllerDevices,
|
|
139
|
-
hs100: this.config.hs100Devices,
|
|
140
|
-
hue: this.config.hueDevices,
|
|
141
|
-
hueExt: this.config.hueExtDevices,
|
|
142
|
-
innogy: this.config.innogyDevices,
|
|
143
|
-
jeelink: this.config.jeelinkDevices,
|
|
144
|
-
loqedSmartLock: this.config.loqedSmartLockDevices,
|
|
145
|
-
lupusec: this.config.lupusecDevices,
|
|
146
|
-
maxcube: this.config.maxcubeDevices,
|
|
147
|
-
meross: this.config.merossDevices,
|
|
148
|
-
mihome: this.config.mihomeDevices,
|
|
149
|
-
mihomeGW: this.config.mihomeDevices,
|
|
150
|
-
mihomeVacuum: this.config.mihomeVacuumDevices,
|
|
151
|
-
mqttClientZigbee2Mqtt: this.config.mqttClientZigbee2MqttDevices,
|
|
152
|
-
mqttNuki: this.config.mqttNukiDevices,
|
|
153
|
-
musiccast: this.config.musiccastDevices,
|
|
154
|
-
netatmo: this.config.netatmoDevices,
|
|
155
|
-
nukiExt: this.config.nukiExtDevices,
|
|
156
|
-
nut: this.config.nutDevices,
|
|
157
|
-
ping: this.config.pingDevices,
|
|
158
|
-
proxmox: this.config.proxmoxDevices,
|
|
159
|
-
ring: this.config.ringDevices,
|
|
160
|
-
roomba: this.config.roombaDevices,
|
|
161
|
-
shelly: this.config.shellyDevices,
|
|
162
|
-
smartgarden: this.config.smartgardenDevices,
|
|
163
|
-
sonoff: this.config.sonoffDevices,
|
|
164
|
-
sonos: this.config.sonosDevices,
|
|
165
|
-
sureflap: this.config.sureflapDevices,
|
|
166
|
-
switchbotBle: this.config.switchbotBleDevices,
|
|
167
|
-
tado: this.config.tadoDevices,
|
|
168
|
-
tapo: this.config.tapoDevices,
|
|
169
|
-
tradfri: this.config.tradfriDevices,
|
|
170
|
-
tuya: this.config.tuyaDevices,
|
|
171
|
-
unifi: this.config.unifiDevices,
|
|
172
|
-
viessmann: this.config.viessmannDevices,
|
|
173
|
-
wifilight: this.config.wifilightDevices,
|
|
174
|
-
wled: this.config.wledDevices,
|
|
175
|
-
xsense: this.config.xsenseDevices,
|
|
176
|
-
yeelight: this.config.yeelightDevices,
|
|
177
|
-
zigbee: this.config.zigbeeDevices,
|
|
178
|
-
zigbee2MQTT: this.config.zigbee2mqttDevices,
|
|
179
|
-
zwave2: this.config.zwaveDevices,
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
this.configMaxMinutes = {
|
|
183
|
-
alexa2: this.config.alexa2MaxMinutes,
|
|
184
|
-
apcups: this.config.apcupsMaxMinutes,
|
|
185
|
-
ble: this.config.bleMaxMinutes,
|
|
186
|
-
deconz: this.config.deconzMaxMinutes,
|
|
187
|
-
ecovacsdeebot: this.config.ecovacsdeebotMaxMinutes,
|
|
188
|
-
enocean: this.config.enoceanMaxMinutes,
|
|
189
|
-
esphome: this.config.esphomeMaxMinutes,
|
|
190
|
-
eusec: this.config.eusecMaxMinutes,
|
|
191
|
-
fhemTFAsensors: this.config.fhemTFAsensorsMaxMinutes,
|
|
192
|
-
fritzdect: this.config.fritzdectMaxMinutes,
|
|
193
|
-
fullybrowser: this.config.fullybrowserMaxMinutes,
|
|
194
|
-
fullybrowserV3: this.config.fullybrowserV3MaxMinutes,
|
|
195
|
-
fullyMQTT: this.config.fullyMQTTMaxMinutes,
|
|
196
|
-
ham: this.config.hamMaxMinutes,
|
|
197
|
-
harmony: this.config.harmonyMaxMinutes,
|
|
198
|
-
hmiP: this.config.hmiPMaxMinutes,
|
|
199
|
-
hmrpc: this.config.hmrpcMaxMinutes,
|
|
200
|
-
homeconnect: this.config.homeconnectMaxMinutes,
|
|
201
|
-
homekitController: this.config.homekitControllerMaxMinutes,
|
|
202
|
-
hs100: this.config.hs100MaxMinutes,
|
|
203
|
-
hue: this.config.hueMaxMinutes,
|
|
204
|
-
hueExt: this.config.hueextMaxMinutes,
|
|
205
|
-
innogy: this.config.innogyMaxMinutes,
|
|
206
|
-
jeelink: this.config.jeelinkMaxMinutes,
|
|
207
|
-
loqedSmartLock: this.config.loqedSmartLockMaxMinutes,
|
|
208
|
-
lupusec: this.config.lupusecMaxMinutes,
|
|
209
|
-
maxcube: this.config.maxcubeMaxMinutes,
|
|
210
|
-
meross: this.config.merossMaxMinutes,
|
|
211
|
-
mihome: this.config.mihomeMaxMinutes,
|
|
212
|
-
mihomeGW: this.config.mihomeMaxMinutes,
|
|
213
|
-
mihomeVacuum: this.config.mihomeVacuumMaxMinutes,
|
|
214
|
-
mqttClientZigbee2Mqtt: this.config.mqttClientZigbee2MqttMaxMinutes,
|
|
215
|
-
mqttNuki: this.config.mqttNukiMaxMinutes,
|
|
216
|
-
musiccast: this.config.musiccastMaxMinutes,
|
|
217
|
-
netatmo: this.config.netatmoMaxMinutes,
|
|
218
|
-
nukiExt: this.config.nukiextendMaxMinutes,
|
|
219
|
-
nut: this.config.nutMaxMinutes,
|
|
220
|
-
ping: this.config.pingMaxMinutes,
|
|
221
|
-
proxmox: this.config.proxmoxMaxMinutes,
|
|
222
|
-
ring: this.config.ringMaxMinutes,
|
|
223
|
-
roomba: this.config.roombaMaxMinutes,
|
|
224
|
-
shelly: this.config.shellyMaxMinutes,
|
|
225
|
-
smartgarden: this.config.smartgardenMaxMinutes,
|
|
226
|
-
sonoff: this.config.sonoffMaxMinutes,
|
|
227
|
-
sonos: this.config.sonosMaxMinutes,
|
|
228
|
-
sureflap: this.config.sureflapMaxMinutes,
|
|
229
|
-
switchbotBle: this.config.switchbotMaxMinutes,
|
|
230
|
-
tado: this.config.tadoMaxMinutes,
|
|
231
|
-
tapo: this.config.tapoMaxMinutes,
|
|
232
|
-
tradfri: this.config.tradfriMaxMinutes,
|
|
233
|
-
tuya: this.config.tuyaMaxMinutes,
|
|
234
|
-
unifi: this.config.unifiMaxMinutes,
|
|
235
|
-
viessmann: this.config.viessmannMaxMinutes,
|
|
236
|
-
wifilight: this.config.wifilightMaxMinutes,
|
|
237
|
-
wled: this.config.wledMaxMinutes,
|
|
238
|
-
xsense: this.config.xsenseMaxMinutes,
|
|
239
|
-
yeelight: this.config.yeelightMaxMinutes,
|
|
240
|
-
zigbee: this.config.zigbeeMaxMinutes,
|
|
241
|
-
zigbee2MQTT: this.config.zigbee2mqttMaxMinutes,
|
|
242
|
-
zwave2: this.config.zwaveMaxMinutes,
|
|
243
|
-
};
|
|
244
|
-
|
|
245
117
|
try {
|
|
246
|
-
// create list with
|
|
247
|
-
for (const
|
|
248
|
-
if (
|
|
249
|
-
|
|
250
|
-
|
|
118
|
+
// create list with enabled adapters for monitor devices
|
|
119
|
+
for (const device of Object.values(this.config.tableDevices)) {
|
|
120
|
+
if (device.enabled) {
|
|
121
|
+
for (const [adapterName, adapter] of Object.entries(adapterArray)) {
|
|
122
|
+
if (String(adapter.adapterKey).toLowerCase() === String(device.adapterKey).toLowerCase()) {
|
|
123
|
+
this.selAdapter.push(adapter);
|
|
124
|
+
this.adapterSelected.push(adapter.adapterKey);
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
251
128
|
}
|
|
252
129
|
}
|
|
253
130
|
|
|
254
131
|
// Check if an adapter to monitor devices is selected.
|
|
255
132
|
if (this.adapterSelected.length >= 1) {
|
|
256
|
-
// show list in debug log
|
|
257
133
|
this.log.debug(JSON.stringify(this.selAdapter));
|
|
258
|
-
|
|
259
134
|
this.log.info(`Number of selected adapters to monitor devices: ${this.adapterSelected.length}. Loading data from: ${this.adapterSelected.join(', ')} ...`);
|
|
260
135
|
} else {
|
|
261
136
|
this.log.info(`No adapters selected to monitor devices.`);
|
|
@@ -268,13 +143,15 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
268
143
|
await crud.createTimeListInstances(this);
|
|
269
144
|
|
|
270
145
|
//create datapoints for each adapter if selected
|
|
271
|
-
for (const [id] of Object.entries(
|
|
146
|
+
for (const [id] of Object.entries(adapterArray)) {
|
|
272
147
|
try {
|
|
273
148
|
if (!this.configCreateOwnFolder) {
|
|
274
149
|
await crud.deleteDPsForEachAdapter(this, id);
|
|
275
150
|
await crud.deleteHtmlListDatapoints(this, id);
|
|
276
151
|
} else {
|
|
277
|
-
|
|
152
|
+
const adapter = adapterArray[id];
|
|
153
|
+
|
|
154
|
+
if (this.adapterSelected.includes(adapter.adapterKey)) {
|
|
278
155
|
await crud.createDPsForEachAdapter(this, id);
|
|
279
156
|
// create HTML list datapoints
|
|
280
157
|
if (!this.configCreateHtmlList) {
|
|
@@ -296,10 +173,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
296
173
|
await crud.deleteHtmlListDatapointsInstances(this);
|
|
297
174
|
} else {
|
|
298
175
|
await crud.createHtmlListDatapoints(this);
|
|
299
|
-
if (this.config.checkAdapterInstances)
|
|
176
|
+
if (this.config.checkAdapterInstances) {
|
|
177
|
+
await crud.createHtmlListDatapointsInstances(this);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (!this.config.checkAdapterInstances) {
|
|
181
|
+
await crud.deleteHtmlListDatapointsInstances(this);
|
|
300
182
|
}
|
|
301
|
-
if (!this.config.checkAdapterInstances) await crud.deleteHtmlListDatapointsInstances(this);
|
|
302
|
-
|
|
303
183
|
|
|
304
184
|
// instances and adapters
|
|
305
185
|
if (this.configCreateInstanceList) {
|
|
@@ -318,24 +198,35 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
318
198
|
await this.refreshData();
|
|
319
199
|
|
|
320
200
|
// send overview for low battery devices
|
|
321
|
-
if (this.config.checkSendBatteryMsgDaily)
|
|
201
|
+
if (this.config.checkSendBatteryMsgDaily) {
|
|
202
|
+
await this.sendScheduleNotifications('lowBatteryDevices');
|
|
203
|
+
}
|
|
322
204
|
|
|
323
205
|
// send overview of offline devices
|
|
324
|
-
if (this.config.checkSendOfflineMsgDaily)
|
|
206
|
+
if (this.config.checkSendOfflineMsgDaily) {
|
|
207
|
+
await this.sendScheduleNotifications('offlineDevices');
|
|
208
|
+
}
|
|
325
209
|
|
|
326
210
|
// send overview of upgradeable devices
|
|
327
|
-
if (this.config.checkSendUpgradeMsgDaily)
|
|
211
|
+
if (this.config.checkSendUpgradeMsgDaily) {
|
|
212
|
+
await this.sendScheduleNotifications('updateDevices');
|
|
213
|
+
}
|
|
328
214
|
|
|
329
215
|
// send overview of updatable adapters
|
|
330
|
-
if (this.config.checkSendAdapterUpdateMsgDaily)
|
|
216
|
+
if (this.config.checkSendAdapterUpdateMsgDaily) {
|
|
217
|
+
await this.sendScheduleNotifications('updateAdapter');
|
|
218
|
+
}
|
|
331
219
|
|
|
332
220
|
// send overview of deactivated instances
|
|
333
|
-
if (this.config.checkSendInstanceDeactivatedDaily)
|
|
221
|
+
if (this.config.checkSendInstanceDeactivatedDaily) {
|
|
222
|
+
await this.sendScheduleNotifications('deactivatedInstance');
|
|
223
|
+
}
|
|
334
224
|
|
|
335
225
|
// send overview of instances with error
|
|
336
|
-
if (this.config.checkSendInstanceFailedDaily)
|
|
337
|
-
|
|
338
|
-
|
|
226
|
+
if (this.config.checkSendInstanceFailedDaily) {
|
|
227
|
+
await this.sendScheduleNotifications('errorInstance');
|
|
228
|
+
}
|
|
229
|
+
} catch (error) {
|
|
339
230
|
this.log.error(`[onReady] - ${error}`);
|
|
340
231
|
this.terminate ? this.terminate(15) : process.exit(15);
|
|
341
232
|
}
|
|
@@ -349,7 +240,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
349
240
|
this.mainRunning = true;
|
|
350
241
|
|
|
351
242
|
// cancel run if no adapter is selected
|
|
352
|
-
if (this.adapterSelected.length === 0)
|
|
243
|
+
if (this.adapterSelected.length === 0) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
353
246
|
|
|
354
247
|
// fill counts and lists of all selected adapter
|
|
355
248
|
try {
|
|
@@ -366,11 +259,15 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
366
259
|
// fill datapoints for each adapter if selected
|
|
367
260
|
if (this.configCreateOwnFolder) {
|
|
368
261
|
try {
|
|
369
|
-
for (const [id] of Object.entries(
|
|
370
|
-
|
|
262
|
+
for (const [id] of Object.entries(adapterArray)) {
|
|
263
|
+
const adapter = adapterArray[id];
|
|
264
|
+
|
|
265
|
+
if (this.adapterSelected.includes(adapter.adapterKey)) {
|
|
371
266
|
for (const deviceData of this.listAllDevicesRaw.values()) {
|
|
372
267
|
// list device only if selected adapter matched with device
|
|
373
|
-
if (!deviceData.adapterID.includes(id))
|
|
268
|
+
if (!deviceData.adapterID.includes(id)) {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
374
271
|
await crud.createLists(this, id);
|
|
375
272
|
}
|
|
376
273
|
await crud.writeDatapoints(this, id); // fill the datapoints
|
|
@@ -388,11 +285,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
388
285
|
// If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.
|
|
389
286
|
// You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`.
|
|
390
287
|
//
|
|
391
|
-
|
|
392
|
-
* Is called if a subscribed object changes
|
|
393
|
-
* @param {string} id
|
|
394
|
-
* @param {ioBroker.Object | null | undefined} obj
|
|
395
|
-
*/
|
|
288
|
+
|
|
396
289
|
async onObjectChange(id, obj) {
|
|
397
290
|
if (obj) {
|
|
398
291
|
try {
|
|
@@ -440,11 +333,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
440
333
|
}
|
|
441
334
|
}
|
|
442
335
|
|
|
443
|
-
/**
|
|
444
|
-
* Is called if a subscribed state changes
|
|
445
|
-
* @param {string} id
|
|
446
|
-
* @param {ioBroker.State | null | undefined} state
|
|
447
|
-
*/
|
|
448
336
|
async onStateChange(id, state) {
|
|
449
337
|
if (state) {
|
|
450
338
|
// this.log.debug(`State changed: ${id} changed ${state.val}`);
|
|
@@ -470,7 +358,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
470
358
|
await this.renewDeviceData(id, state);
|
|
471
359
|
}
|
|
472
360
|
} catch (error) {
|
|
473
|
-
this.log.error(`Issue at state change: ${
|
|
361
|
+
this.log.error(`Issue at state change: ${id}`);
|
|
474
362
|
}
|
|
475
363
|
} else {
|
|
476
364
|
// The state was deleted
|
|
@@ -478,9 +366,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
478
366
|
}
|
|
479
367
|
}
|
|
480
368
|
|
|
481
|
-
/**
|
|
482
|
-
* @param {ioBroker.Message} obj
|
|
483
|
-
*/
|
|
484
369
|
onMessage(obj) {
|
|
485
370
|
const devices = [];
|
|
486
371
|
const instances = [];
|
|
@@ -571,7 +456,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
571
456
|
* is neccessary to refresh lastContact data, especially of devices without state changes
|
|
572
457
|
*/
|
|
573
458
|
async refreshData() {
|
|
574
|
-
if (isUnloaded)
|
|
459
|
+
if (isUnloaded) {
|
|
460
|
+
return;
|
|
461
|
+
} // cancel run if unloaded was called.
|
|
575
462
|
const nextTimeout = this.config.updateinterval * 1000;
|
|
576
463
|
|
|
577
464
|
// devices data
|
|
@@ -581,8 +468,10 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
581
468
|
|
|
582
469
|
// devices data in own adapter folder
|
|
583
470
|
if (this.configCreateOwnFolder) {
|
|
584
|
-
for (const [id] of Object.entries(
|
|
585
|
-
|
|
471
|
+
for (const [id] of Object.entries(adapterArray)) {
|
|
472
|
+
const adapter = adapterArray[id];
|
|
473
|
+
|
|
474
|
+
if (this.adapterSelected.includes(adapter.adapterKey)) {
|
|
586
475
|
await crud.createLists(this, id);
|
|
587
476
|
await crud.writeDatapoints(this, id);
|
|
588
477
|
this.log.debug(`Created and filled data for ${tools.capitalize(id)}`);
|
|
@@ -634,7 +523,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
634
523
|
|
|
635
524
|
switch (this.selAdapter[i].adapterID) {
|
|
636
525
|
case 'fullybrowser':
|
|
637
|
-
deviceName =
|
|
526
|
+
deviceName = `${await tools.getInitValue(this, currDeviceString + this.selAdapter[i].id)} ${await tools.getInitValue(this, currDeviceString + this.selAdapter[i].id2)}`;
|
|
638
527
|
break;
|
|
639
528
|
|
|
640
529
|
// Get ID with short currDeviceString from objectjson
|
|
@@ -663,7 +552,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
663
552
|
case 'mihomeVacuum':
|
|
664
553
|
case 'roomba':
|
|
665
554
|
folderName = shortCurrDeviceString.slice(shortCurrDeviceString.lastIndexOf('.') + 1);
|
|
666
|
-
deviceID = await tools.getInitValue(this,shortCurrDeviceString + this.selAdapter[i].id);
|
|
555
|
+
deviceID = await tools.getInitValue(this, shortCurrDeviceString + this.selAdapter[i].id);
|
|
667
556
|
deviceName = `I${folderName} ${deviceID}`;
|
|
668
557
|
break;
|
|
669
558
|
|
|
@@ -671,7 +560,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
671
560
|
case 'tado':
|
|
672
561
|
case 'wifilight':
|
|
673
562
|
case 'fullybrowserV3':
|
|
674
|
-
|
|
563
|
+
case 'sonoff':
|
|
675
564
|
deviceName = currDeviceString.slice(currDeviceString.lastIndexOf('.') + 1);
|
|
676
565
|
break;
|
|
677
566
|
|
|
@@ -679,7 +568,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
679
568
|
case 'sureflap':
|
|
680
569
|
if (deviceObject && typeof deviceObject === 'object' && deviceObject.common) {
|
|
681
570
|
deviceName = deviceObject.common.name
|
|
682
|
-
// @ts-ignore FIXME: fix syntax error
|
|
683
571
|
.replace(/'/g, '')
|
|
684
572
|
.replace(/\(\d+\)/g, '')
|
|
685
573
|
.trim()
|
|
@@ -695,7 +583,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
695
583
|
|
|
696
584
|
// Get ID with main selektor from objectjson
|
|
697
585
|
default:
|
|
698
|
-
if (this.selAdapter[i].id !== 'none' || this.selAdapter[i].id !== undefined)
|
|
586
|
+
if (this.selAdapter[i].id !== 'none' || this.selAdapter[i].id !== undefined) {
|
|
587
|
+
deviceName = await tools.getInitValue(this, currDeviceString + this.selAdapter[i].id);
|
|
588
|
+
}
|
|
699
589
|
if (deviceName === null || deviceName === undefined) {
|
|
700
590
|
if (deviceObject && typeof deviceObject === 'object' && deviceObject.common) {
|
|
701
591
|
deviceName = deviceObject.common.name;
|
|
@@ -711,6 +601,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
711
601
|
|
|
712
602
|
/**
|
|
713
603
|
* calculate Signalstrength
|
|
604
|
+
*
|
|
714
605
|
* @param {object} deviceQualityState - State value
|
|
715
606
|
* @param {object} adapterID - adapter name
|
|
716
607
|
*/
|
|
@@ -778,6 +669,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
778
669
|
|
|
779
670
|
/**
|
|
780
671
|
* get battery data
|
|
672
|
+
*
|
|
781
673
|
* @param {object} deviceBatteryState - State value
|
|
782
674
|
* @param {object} deviceLowBatState - State value
|
|
783
675
|
* @param {object} faultReportingState - State value
|
|
@@ -790,6 +682,17 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
790
682
|
let batteryHealthUnitRaw;
|
|
791
683
|
|
|
792
684
|
switch (adapterID) {
|
|
685
|
+
case 'lupusec':
|
|
686
|
+
if (deviceBatteryState === undefined) {
|
|
687
|
+
if (deviceLowBatState === 1) {
|
|
688
|
+
batteryHealth = 'ok';
|
|
689
|
+
isBatteryDevice = true;
|
|
690
|
+
} else {
|
|
691
|
+
batteryHealth = 'low';
|
|
692
|
+
isBatteryDevice = true;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
break;
|
|
793
696
|
case 'hmrpc':
|
|
794
697
|
if (deviceBatteryState === undefined) {
|
|
795
698
|
if (faultReportingState !== undefined && faultReportingState !== 6) {
|
|
@@ -829,7 +732,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
829
732
|
break;
|
|
830
733
|
default:
|
|
831
734
|
batteryHealth = 'error';
|
|
832
|
-
|
|
735
|
+
}
|
|
833
736
|
}
|
|
834
737
|
break;
|
|
835
738
|
default:
|
|
@@ -845,12 +748,10 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
845
748
|
}
|
|
846
749
|
} else {
|
|
847
750
|
if (typeof deviceBatteryState === 'string') {
|
|
848
|
-
if (deviceBatteryState === 'high' || deviceBatteryState === 'medium')
|
|
849
|
-
{
|
|
751
|
+
if (deviceBatteryState === 'high' || deviceBatteryState === 'medium') {
|
|
850
752
|
batteryHealth = 'ok';
|
|
851
753
|
isBatteryDevice = true;
|
|
852
|
-
}
|
|
853
|
-
else if (deviceBatteryState === 'low') {
|
|
754
|
+
} else if (deviceBatteryState === 'low') {
|
|
854
755
|
batteryHealth = 'low';
|
|
855
756
|
isBatteryDevice = true;
|
|
856
757
|
}
|
|
@@ -869,6 +770,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
869
770
|
|
|
870
771
|
/**
|
|
871
772
|
* set low bat indicator
|
|
773
|
+
*
|
|
872
774
|
* @param {object} deviceBatteryState
|
|
873
775
|
* @param {object} deviceLowBatState
|
|
874
776
|
* @param {object} faultReportState
|
|
@@ -896,7 +798,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
896
798
|
}
|
|
897
799
|
} else if (typeof deviceBatteryState === 'number' && deviceBatteryState < this.config.minWarnBatterie) {
|
|
898
800
|
lowBatIndicator = true;
|
|
899
|
-
} else if
|
|
801
|
+
} else if (typeof deviceBatteryState === 'string' && deviceBatteryState === 'low') {
|
|
900
802
|
lowBatIndicator = true;
|
|
901
803
|
}
|
|
902
804
|
|
|
@@ -905,209 +807,217 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
905
807
|
|
|
906
808
|
/**
|
|
907
809
|
* get Last Contact
|
|
810
|
+
*
|
|
908
811
|
* @param {object} selector - Selector
|
|
909
812
|
*/
|
|
910
813
|
async getLastContact(selector) {
|
|
911
|
-
const lastContact = tools.getTimestamp(selector);
|
|
912
|
-
let lastContactString;
|
|
814
|
+
const lastContact = tools.getTimestamp(selector); // z. B. Differenz in Sekunden?
|
|
913
815
|
|
|
914
|
-
lastContactString = `${this.formatDate(new Date(selector), 'hh:mm')}`;
|
|
915
|
-
|
|
916
|
-
|
|
816
|
+
let lastContactString = `${this.formatDate(new Date(selector), 'hh:mm:ss')}`;
|
|
817
|
+
|
|
818
|
+
// Falls du die vergangene Zeit in Sekunden anzeigen willst:
|
|
819
|
+
if (Math.round(lastContact) >= 0) {
|
|
820
|
+
lastContactString = `${Math.round(lastContact)} ${translations.secs[this.config.userSelectedLanguage]}`;
|
|
917
821
|
}
|
|
918
|
-
|
|
919
|
-
|
|
822
|
+
|
|
823
|
+
// Optional: Wenn du ab einem bestimmten Wert lieber Minuten oder Stunden willst
|
|
824
|
+
if (lastContact >= 3600) {
|
|
825
|
+
lastContactString = `${(lastContact / 3600).toFixed(1)} ${translations.hours[this.config.userSelectedLanguage]}`;
|
|
826
|
+
} else {
|
|
827
|
+
lastContactString = `${Math.round(lastContact / 60)} ${translations.minits[this.config.userSelectedLanguage]}`;
|
|
920
828
|
}
|
|
829
|
+
|
|
921
830
|
return lastContactString;
|
|
922
831
|
}
|
|
923
832
|
|
|
924
|
-
|
|
925
|
-
* get online state and time
|
|
926
|
-
* @param {object} timeSelector - device Timeselector
|
|
927
|
-
* @param {string} adapterID - ID of Adapter
|
|
928
|
-
* @param {string} unreachDP - Datapoint of Unreach
|
|
929
|
-
* @param {object} linkQuality - Linkquality Value
|
|
930
|
-
* @param {object} deviceUnreachState - State of deviceUnreach datapoint
|
|
931
|
-
* @param {string} deviceStateSelectorHMRPC - Selector of device state (like .state)
|
|
932
|
-
* @param {string} rssiPeerSelectorHMRPC - HM RSSI Peer Datapoint
|
|
933
|
-
*/
|
|
934
|
-
async getOnlineState(timeSelector, adapterID, unreachDP, linkQuality, deviceUnreachState, deviceStateSelectorHMRPC, rssiPeerSelectorHMRPC) {
|
|
833
|
+
async getOnlineState(timeSelector, adapterID, treeDP, linkQuality, deviceUnreachState, deviceStateSelectorHMRPC, rssiPeerSelectorHMRPC) {
|
|
935
834
|
let lastContactString;
|
|
835
|
+
let lastContact;
|
|
936
836
|
let deviceState = 'Online';
|
|
837
|
+
let linkQualitySet = linkQuality ?? '0%';
|
|
937
838
|
|
|
938
839
|
try {
|
|
939
840
|
const deviceTimeSelector = await this.getForeignStateAsync(timeSelector);
|
|
940
|
-
const deviceUnreachSelector = await this.getForeignStateAsync(
|
|
941
|
-
|
|
942
|
-
const rssiPeerSelector = await this.getForeignStateAsync(rssiPeerSelectorHMRPC);
|
|
841
|
+
const deviceUnreachSelector = await this.getForeignStateAsync(treeDP);
|
|
842
|
+
|
|
943
843
|
const lastDeviceUnreachStateChange = deviceUnreachSelector != undefined ? tools.getTimestamp(deviceUnreachSelector.lc) : tools.getTimestamp(timeSelector.ts);
|
|
944
844
|
|
|
945
845
|
// ignore disabled device from zigbee2MQTT
|
|
946
846
|
if (adapterID === 'zigbee2MQTT') {
|
|
947
|
-
const is_device_disabled = await tools.isDisabledDevice(this,
|
|
847
|
+
const is_device_disabled = await tools.isDisabledDevice(this, treeDP.substring(0, treeDP.lastIndexOf('.')));
|
|
948
848
|
|
|
949
849
|
if (is_device_disabled) {
|
|
950
|
-
return [null, 'disabled', '
|
|
850
|
+
return [null, 'disabled', ' - '];
|
|
951
851
|
}
|
|
952
852
|
}
|
|
953
853
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
854
|
+
if (adapterID === 'hmrpc') {
|
|
855
|
+
const deviceState = await this.getForeignStateAsync(deviceStateSelectorHMRPC);
|
|
856
|
+
const rssiPeer = await this.getForeignStateAsync(rssiPeerSelectorHMRPC);
|
|
857
|
+
|
|
858
|
+
if (linkQuality !== ' - ' && deviceTimeSelector) {
|
|
859
|
+
const ts = deviceUnreachState === 1 ? deviceTimeSelector.lc : deviceTimeSelector.ts;
|
|
860
|
+
lastContactString = await this.getLastContact(ts);
|
|
861
|
+
} else if (deviceState) {
|
|
862
|
+
lastContactString = await this.getLastContact(deviceState.ts);
|
|
863
|
+
} else if (rssiPeer) {
|
|
864
|
+
lastContactString = await this.getLastContact(rssiPeer.ts);
|
|
865
|
+
}
|
|
866
|
+
} else if (deviceTimeSelector) {
|
|
867
|
+
const ts = !deviceUnreachState ? deviceTimeSelector.lc : deviceTimeSelector.ts;
|
|
868
|
+
lastContactString = await this.getLastContact(ts);
|
|
869
|
+
}
|
|
960
870
|
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
if (adapterID === 'hmrpc') {
|
|
964
|
-
if (linkQuality !== ' - ' && deviceTimeSelector) {
|
|
965
|
-
if (deviceUnreachState === 1) {
|
|
966
|
-
lastContactString = await this.getLastContact(deviceTimeSelector.lc);
|
|
967
|
-
} else {
|
|
968
|
-
lastContactString = await this.getLastContact(deviceTimeSelector.ts);
|
|
969
|
-
}
|
|
970
|
-
} else {
|
|
971
|
-
if (deviceStateSelector) {
|
|
972
|
-
// because old hm devices don't send rssi states
|
|
973
|
-
lastContactString = await this.getLastContact(deviceStateSelector.ts);
|
|
974
|
-
} else if (rssiPeerSelector) {
|
|
975
|
-
// because old hm sensors don't send rssi/state values
|
|
976
|
-
lastContactString = await this.getLastContact(rssiPeerSelector.ts);
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
} else {
|
|
980
|
-
if ((!deviceUnreachState || deviceUnreachState === 0) && deviceTimeSelector) {
|
|
981
|
-
lastContactString = await this.getLastContact(deviceTimeSelector.lc);
|
|
982
|
-
} else {
|
|
983
|
-
if (deviceTimeSelector) lastContactString = await this.getLastContact(deviceTimeSelector.ts);
|
|
984
|
-
}
|
|
985
|
-
break;
|
|
986
|
-
}
|
|
871
|
+
if (deviceTimeSelector) {
|
|
872
|
+
lastContact = tools.getTimestamp(deviceTimeSelector.ts);
|
|
987
873
|
}
|
|
988
874
|
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
let lastContact;
|
|
993
|
-
if (deviceTimeSelector) lastContact = tools.getTimestamp(deviceTimeSelector.ts);
|
|
875
|
+
const gefundenerAdapter = Object.values(adapterArray).find((adapter) => adapter.adapterID === adapterID);
|
|
876
|
+
const device = Object.values(this.config.tableDevices).find((adapter) => adapter.adapterKey === gefundenerAdapter.adapterKey);
|
|
877
|
+
const maxSecondDevicesOffline = device.maxSecondDevicesOffline;
|
|
994
878
|
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
if (
|
|
999
|
-
if (deviceUnreachState === 1) {
|
|
1000
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1001
|
-
if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
|
|
1002
|
-
}
|
|
1003
|
-
} else if (lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID] && deviceUnreachState === 1) {
|
|
879
|
+
switch (adapterID) {
|
|
880
|
+
case 'hmrpc': {
|
|
881
|
+
if (maxSecondDevicesOffline <= 0) {
|
|
882
|
+
if (deviceUnreachState === 1) {
|
|
1004
883
|
deviceState = 'Offline'; //set online state to offline
|
|
1005
|
-
if (linkQuality !== ' - ')
|
|
884
|
+
if (linkQuality !== ' - ') {
|
|
885
|
+
linkQualitySet = '0%';
|
|
886
|
+
} // set linkQuality to nothing
|
|
1006
887
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
if (
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
888
|
+
} else if (lastDeviceUnreachStateChange > maxSecondDevicesOffline && deviceUnreachState === 1) {
|
|
889
|
+
deviceState = 'Offline'; //set online state to offline
|
|
890
|
+
if (linkQuality !== ' - ') {
|
|
891
|
+
linkQualitySet = '0%';
|
|
892
|
+
} // set linkQuality to nothing
|
|
893
|
+
}
|
|
894
|
+
break;
|
|
895
|
+
}
|
|
896
|
+
case 'proxmox': {
|
|
897
|
+
if (maxSecondDevicesOffline <= 0) {
|
|
898
|
+
if (deviceUnreachState !== 'running' && deviceUnreachState !== 'online') {
|
|
1015
899
|
deviceState = 'Offline'; //set online state to offline
|
|
1016
|
-
if (linkQuality !== ' - ')
|
|
900
|
+
if (linkQuality !== ' - ') {
|
|
901
|
+
linkQualitySet = '0%';
|
|
902
|
+
} // set linkQuality to nothing
|
|
1017
903
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
904
|
+
} else if (lastDeviceUnreachStateChange > maxSecondDevicesOffline && deviceUnreachState !== 'running' && deviceUnreachState !== 'online') {
|
|
905
|
+
deviceState = 'Offline'; //set online state to offline
|
|
906
|
+
if (linkQuality !== ' - ') {
|
|
907
|
+
linkQualitySet = '0%';
|
|
908
|
+
} // set linkQuality to nothing
|
|
909
|
+
}
|
|
910
|
+
break;
|
|
911
|
+
}
|
|
912
|
+
case 'hmiP':
|
|
913
|
+
case 'maxcube': {
|
|
914
|
+
if (maxSecondDevicesOffline <= 0) {
|
|
915
|
+
if (deviceUnreachState) {
|
|
1027
916
|
deviceState = 'Offline'; //set online state to offline
|
|
1028
|
-
if (linkQuality !== ' - ')
|
|
917
|
+
if (linkQuality !== ' - ') {
|
|
918
|
+
linkQualitySet = '0%';
|
|
919
|
+
} // set linkQuality to nothing
|
|
1029
920
|
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
921
|
+
} else if (lastDeviceUnreachStateChange > maxSecondDevicesOffline && deviceUnreachState) {
|
|
922
|
+
deviceState = 'Offline'; //set online state to offline
|
|
923
|
+
if (linkQuality !== ' - ') {
|
|
924
|
+
linkQualitySet = '0%';
|
|
925
|
+
} // set linkQuality to nothing
|
|
926
|
+
}
|
|
927
|
+
break;
|
|
928
|
+
}
|
|
929
|
+
case 'apcups':
|
|
930
|
+
case 'hue':
|
|
931
|
+
case 'hueExt':
|
|
932
|
+
case 'ping':
|
|
933
|
+
case 'deconz':
|
|
934
|
+
case 'shelly':
|
|
935
|
+
case 'sonoff':
|
|
936
|
+
case 'tradfri':
|
|
937
|
+
case 'unifi':
|
|
938
|
+
case 'zigbee':
|
|
939
|
+
case 'zigbee2MQTT': {
|
|
940
|
+
if (maxSecondDevicesOffline <= 0) {
|
|
941
|
+
if (!deviceUnreachState) {
|
|
1048
942
|
deviceState = 'Offline'; //set online state to offline
|
|
1049
|
-
if (linkQuality !== ' - ')
|
|
943
|
+
if (linkQuality !== ' - ') {
|
|
944
|
+
linkQualitySet = '0%';
|
|
945
|
+
} // set linkQuality to nothing
|
|
1050
946
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
if (
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
947
|
+
} else if (!deviceUnreachState && lastDeviceUnreachStateChange > maxSecondDevicesOffline) {
|
|
948
|
+
deviceState = 'Offline'; //set online state to offline
|
|
949
|
+
if (linkQuality !== ' - ') {
|
|
950
|
+
linkQualitySet = '0%';
|
|
951
|
+
} // set linkQuality to nothing
|
|
952
|
+
}
|
|
953
|
+
break;
|
|
954
|
+
}
|
|
955
|
+
case 'mqttClientZigbee2Mqtt': {
|
|
956
|
+
if (maxSecondDevicesOffline <= 0) {
|
|
957
|
+
if (deviceUnreachState !== 'online') {
|
|
1059
958
|
deviceState = 'Offline'; //set online state to offline
|
|
1060
|
-
if (linkQuality !== ' - ')
|
|
959
|
+
if (linkQuality !== ' - ') {
|
|
960
|
+
linkQualitySet = '0%';
|
|
961
|
+
} // set linkQuality to nothing
|
|
1061
962
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
if (
|
|
1065
|
-
|
|
1066
|
-
if (!deviceUnreachState) {
|
|
1067
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1068
|
-
if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
|
|
1069
|
-
}
|
|
1070
|
-
} else if (lastContact && lastContact > this.configMaxMinutes[adapterID]) {
|
|
1071
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1072
|
-
if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
|
|
1073
|
-
}
|
|
1074
|
-
} else {
|
|
1075
|
-
if (this.config.mihomeMaxMinutes <= 0) {
|
|
1076
|
-
if (this.configMaxMinutes[adapterID] <= 0) {
|
|
1077
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1078
|
-
if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
|
|
1079
|
-
}
|
|
1080
|
-
} else if (lastContact && lastContact > this.configMaxMinutes[adapterID]) {
|
|
1081
|
-
deviceState = 'Offline'; //set online state to offline
|
|
1082
|
-
if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
|
|
1083
|
-
}
|
|
963
|
+
} else if (deviceUnreachState !== 'online' && lastDeviceUnreachStateChange > maxSecondDevicesOffline) {
|
|
964
|
+
deviceState = 'Offline'; //set online state to offline
|
|
965
|
+
if (linkQuality !== ' - ') {
|
|
966
|
+
linkQualitySet = '0%';
|
|
1084
967
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
968
|
+
}
|
|
969
|
+
break;
|
|
970
|
+
}
|
|
971
|
+
case 'mihome': {
|
|
972
|
+
const offlineByTime = maxSecondDevicesOffline <= 0 || (lastContact && lastContact > maxSecondDevicesOffline);
|
|
973
|
+
const offlineByState = deviceUnreachState !== undefined ? !deviceUnreachState && offlineByTime : offlineByTime;
|
|
974
|
+
|
|
975
|
+
if (offlineByState) {
|
|
976
|
+
deviceState = 'Offline';
|
|
977
|
+
if (linkQuality !== ' - ') {
|
|
978
|
+
linkQualitySet = '0%';
|
|
1095
979
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
}
|
|
1103
|
-
} else if (lastContact && lastContact > this.configMaxMinutes[adapterID]) {
|
|
980
|
+
}
|
|
981
|
+
break;
|
|
982
|
+
}
|
|
983
|
+
case 'smartgarden': {
|
|
984
|
+
if (maxSecondDevicesOffline <= 0) {
|
|
985
|
+
if (deviceUnreachState === 'OFFLINE') {
|
|
1104
986
|
deviceState = 'Offline'; //set online state to offline
|
|
1105
|
-
if (linkQuality !== ' - ')
|
|
987
|
+
if (linkQuality !== ' - ') {
|
|
988
|
+
linkQualitySet = '0%';
|
|
989
|
+
} // set linkQuality to nothing
|
|
1106
990
|
}
|
|
1107
|
-
|
|
991
|
+
} else if (deviceUnreachState === 'OFFLINE' && lastDeviceUnreachStateChange > maxSecondDevicesOffline) {
|
|
992
|
+
deviceState = 'Offline'; //set online state to offline
|
|
993
|
+
if (linkQuality !== ' - ') {
|
|
994
|
+
linkQualitySet = '0%';
|
|
995
|
+
} // set linkQuality to nothing
|
|
996
|
+
}
|
|
997
|
+
break;
|
|
998
|
+
}
|
|
999
|
+
default: {
|
|
1000
|
+
// Gerät gilt als offline, wenn es unerreichbar ist und keine Wartezeit definiert ist, oder wenn der letzte Kontakt zu lange her ist als Wartezeit
|
|
1001
|
+
let shouldBeOffline = false;
|
|
1002
|
+
|
|
1003
|
+
if (maxSecondDevicesOffline <= 0) {
|
|
1004
|
+
if (!deviceUnreachState) {
|
|
1005
|
+
shouldBeOffline = true;
|
|
1006
|
+
}
|
|
1007
|
+
} else if (lastContact && lastContact > maxSecondDevicesOffline) {
|
|
1008
|
+
shouldBeOffline = true;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
if (shouldBeOffline) {
|
|
1012
|
+
deviceState = 'Offline'; // Gerät auf offline setzen
|
|
1013
|
+
if (linkQuality !== ' - ') {
|
|
1014
|
+
linkQualitySet = '0%';
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1108
1017
|
}
|
|
1109
1018
|
}
|
|
1110
|
-
|
|
1019
|
+
|
|
1020
|
+
return [lastContactString, deviceState, linkQualitySet];
|
|
1111
1021
|
} catch (error) {
|
|
1112
1022
|
this.log.error(`[getLastContact] - ${error}`);
|
|
1113
1023
|
}
|
|
@@ -1118,31 +1028,22 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1118
1028
|
* @param {string | number | boolean | null} deviceUpdateSelector
|
|
1119
1029
|
*/
|
|
1120
1030
|
async checkDeviceUpdate(adapterID, deviceUpdateSelector) {
|
|
1121
|
-
let isUpgradable;
|
|
1031
|
+
let isUpgradable = false;
|
|
1122
1032
|
|
|
1123
1033
|
switch (adapterID) {
|
|
1124
1034
|
case 'hmiP':
|
|
1125
|
-
|
|
1126
|
-
isUpgradable = true;
|
|
1127
|
-
} else {
|
|
1128
|
-
isUpgradable = false;
|
|
1129
|
-
}
|
|
1035
|
+
isUpgradable = deviceUpdateSelector === 'UPDATE_AVAILABLE';
|
|
1130
1036
|
break;
|
|
1037
|
+
|
|
1131
1038
|
case 'ring':
|
|
1132
|
-
|
|
1133
|
-
isUpgradable = true;
|
|
1134
|
-
} else {
|
|
1135
|
-
isUpgradable = false;
|
|
1136
|
-
}
|
|
1039
|
+
isUpgradable = deviceUpdateSelector !== 'Up to Date';
|
|
1137
1040
|
break;
|
|
1041
|
+
|
|
1138
1042
|
default:
|
|
1139
|
-
if (
|
|
1140
|
-
|
|
1141
|
-
isUpgradable = true;
|
|
1142
|
-
} else if (!deviceUpdateSelector) {
|
|
1143
|
-
isUpgradable = false;
|
|
1144
|
-
}
|
|
1043
|
+
if (typeof deviceUpdateSelector === 'boolean') {
|
|
1044
|
+
isUpgradable = deviceUpdateSelector;
|
|
1145
1045
|
}
|
|
1046
|
+
break;
|
|
1146
1047
|
}
|
|
1147
1048
|
|
|
1148
1049
|
return isUpgradable;
|
|
@@ -1150,17 +1051,17 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1150
1051
|
|
|
1151
1052
|
/**
|
|
1152
1053
|
* fill the lists for user
|
|
1054
|
+
*
|
|
1153
1055
|
* @param {object} device
|
|
1154
1056
|
*/
|
|
1155
1057
|
async theLists(device) {
|
|
1156
1058
|
// Raw List with all devices for user
|
|
1157
1059
|
if (device.Status !== 'disabled') {
|
|
1158
|
-
|
|
1159
1060
|
this.listAllDevicesUserRaw.push({
|
|
1160
1061
|
Device: device.Device,
|
|
1161
1062
|
Adapter: device.Adapter,
|
|
1162
1063
|
Instance: device.instance,
|
|
1163
|
-
'Instance connected': device.
|
|
1064
|
+
'Instance connected': device.instanceDeviceConnected,
|
|
1164
1065
|
isBatteryDevice: device.isBatteryDevice,
|
|
1165
1066
|
Battery: device.Battery,
|
|
1166
1067
|
BatteryRaw: device.BatteryRaw,
|
|
@@ -1230,12 +1131,12 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1230
1131
|
}
|
|
1231
1132
|
}
|
|
1232
1133
|
|
|
1233
|
-
|
|
1234
1134
|
/**
|
|
1235
1135
|
* @param {string | string[]} id
|
|
1236
1136
|
* @param {ioBroker.State} state
|
|
1237
1137
|
*/
|
|
1238
1138
|
async renewDeviceData(id, state) {
|
|
1139
|
+
const regex = /^([^.]+\.\d+\.[^.]+)/;
|
|
1239
1140
|
let batteryData;
|
|
1240
1141
|
let signalData;
|
|
1241
1142
|
let oldLowBatState;
|
|
@@ -1243,16 +1144,21 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1243
1144
|
let oldStatus;
|
|
1244
1145
|
let isLowBatValue;
|
|
1245
1146
|
|
|
1246
|
-
const deviceID = id.
|
|
1147
|
+
const deviceID = id.match(regex)[1];
|
|
1247
1148
|
const deviceData = this.listAllDevicesRaw.get(deviceID);
|
|
1248
1149
|
|
|
1150
|
+
this.log.debug(`[renewDeviceData] - ${id}`);
|
|
1151
|
+
|
|
1249
1152
|
if (deviceData) {
|
|
1153
|
+
const gefundenerAdapter = Object.values(adapterArray).find((adapter) => adapter.adapterID === deviceData.adapterID);
|
|
1154
|
+
const silentEnabled = Object.values(this.config.tableDevices).find((adapter) => adapter.adapterKey === gefundenerAdapter.adapterKey);
|
|
1155
|
+
|
|
1250
1156
|
// On statechange update available datapoint
|
|
1251
1157
|
switch (id) {
|
|
1252
1158
|
// device connection
|
|
1253
1159
|
case deviceData.instanceDeviceConnectionDP:
|
|
1254
|
-
if (state.val !== deviceData.
|
|
1255
|
-
deviceData.
|
|
1160
|
+
if (state.val !== deviceData.instanceDeviceConnected) {
|
|
1161
|
+
deviceData.instanceDeviceConnected = state.val;
|
|
1256
1162
|
}
|
|
1257
1163
|
break;
|
|
1258
1164
|
|
|
@@ -1262,7 +1168,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1262
1168
|
deviceData.Upgradable = await this.checkDeviceUpdate(deviceData.adapterID, state.val);
|
|
1263
1169
|
if (deviceData.Upgradable === true) {
|
|
1264
1170
|
if (this.config.checkSendDeviceUpgrade && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
1265
|
-
await this.sendStateNotifications('Devices', 'updateDevice', deviceID);
|
|
1171
|
+
await this.sendStateNotifications('Devices', 'updateDevice', deviceID, silentEnabled.telegramSilent);
|
|
1266
1172
|
}
|
|
1267
1173
|
}
|
|
1268
1174
|
}
|
|
@@ -1279,14 +1185,16 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1279
1185
|
case deviceData.batteryDP:
|
|
1280
1186
|
if (deviceData.isBatteryDevice) {
|
|
1281
1187
|
oldLowBatState = deviceData.LowBat;
|
|
1282
|
-
if (state.val === 0 && deviceData.BatteryRaw >= 5)
|
|
1188
|
+
if (state.val === 0 && deviceData.BatteryRaw >= 5) {
|
|
1189
|
+
return;
|
|
1190
|
+
}
|
|
1283
1191
|
batteryData = await this.getBatteryData(state.val, oldLowBatState, deviceData.faultReport, deviceData.adapterID);
|
|
1284
1192
|
|
|
1285
1193
|
deviceData.Battery = batteryData[0];
|
|
1286
1194
|
deviceData.BatteryRaw = batteryData[2];
|
|
1287
1195
|
deviceData.BatteryUnitRaw = batteryData[3];
|
|
1288
1196
|
if (deviceData.LowBatDP !== 'none') {
|
|
1289
|
-
isLowBatValue = await tools.getInitValue(this,deviceData.LowBatDP);
|
|
1197
|
+
isLowBatValue = await tools.getInitValue(this, deviceData.LowBatDP);
|
|
1290
1198
|
} else {
|
|
1291
1199
|
isLowBatValue = undefined;
|
|
1292
1200
|
}
|
|
@@ -1294,7 +1202,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1294
1202
|
|
|
1295
1203
|
if (deviceData.LowBat && oldLowBatState !== deviceData.LowBat) {
|
|
1296
1204
|
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
1297
|
-
await this.sendStateNotifications('Devices', 'lowBatDevice', deviceID);
|
|
1205
|
+
await this.sendStateNotifications('Devices', 'lowBatDevice', deviceID, silentEnabled.telegramSilent);
|
|
1298
1206
|
}
|
|
1299
1207
|
}
|
|
1300
1208
|
}
|
|
@@ -1312,7 +1220,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1312
1220
|
|
|
1313
1221
|
if (deviceData.LowBat && oldLowBatState !== deviceData.LowBat) {
|
|
1314
1222
|
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
1315
|
-
await this.sendStateNotifications('Devices', 'lowBatDevice', deviceID);
|
|
1223
|
+
await this.sendStateNotifications('Devices', 'lowBatDevice', deviceID, silentEnabled.telegramSilent);
|
|
1316
1224
|
}
|
|
1317
1225
|
}
|
|
1318
1226
|
}
|
|
@@ -1331,7 +1239,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1331
1239
|
|
|
1332
1240
|
if (deviceData.LowBat && oldLowBatState !== deviceData.LowBat) {
|
|
1333
1241
|
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
1334
|
-
await this.sendStateNotifications('Devices', 'lowBatDevice', deviceID);
|
|
1242
|
+
await this.sendStateNotifications('Devices', 'lowBatDevice', deviceID, silentEnabled.telegramSilent);
|
|
1335
1243
|
}
|
|
1336
1244
|
}
|
|
1337
1245
|
}
|
|
@@ -1339,10 +1247,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1339
1247
|
|
|
1340
1248
|
// device unreach
|
|
1341
1249
|
case deviceData.UnreachDP:
|
|
1342
|
-
if (deviceData.
|
|
1250
|
+
if (deviceData.instanceDeviceConnected !== undefined) {
|
|
1343
1251
|
if (deviceData.UnreachState !== state.val) {
|
|
1344
1252
|
oldStatus = deviceData.Status;
|
|
1345
1253
|
deviceData.UnreachState = state.val;
|
|
1254
|
+
|
|
1346
1255
|
contactData = await this.getOnlineState(
|
|
1347
1256
|
deviceData.timeSelector,
|
|
1348
1257
|
deviceData.adapterID,
|
|
@@ -1352,20 +1261,21 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1352
1261
|
deviceData.deviceStateSelectorHMRPC,
|
|
1353
1262
|
deviceData.rssiPeerSelectorHMRPC,
|
|
1354
1263
|
);
|
|
1355
|
-
|
|
1264
|
+
|
|
1265
|
+
if (contactData !== undefined || contactData !== null) {
|
|
1356
1266
|
deviceData.LastContact = contactData[0];
|
|
1357
1267
|
deviceData.Status = contactData[1];
|
|
1358
1268
|
deviceData.SignalStrength = contactData[2];
|
|
1359
1269
|
}
|
|
1270
|
+
|
|
1360
1271
|
if (this.config.checkSendOfflineMsg && oldStatus !== deviceData.Status && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
1361
1272
|
// check if the generally deviceData connected state is for a while true
|
|
1362
1273
|
if (await tools.getTimestampConnectionDP(this, deviceData.instanceDeviceConnectionDP, 50000)) {
|
|
1363
|
-
await this.sendStateNotifications('Devices', 'onlineStateDevice', deviceID);
|
|
1274
|
+
await this.sendStateNotifications('Devices', 'onlineStateDevice', deviceID, silentEnabled.telegramSilent);
|
|
1364
1275
|
}
|
|
1365
1276
|
}
|
|
1366
1277
|
}
|
|
1367
1278
|
}
|
|
1368
|
-
break;
|
|
1369
1279
|
}
|
|
1370
1280
|
}
|
|
1371
1281
|
}
|
|
@@ -1384,6 +1294,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1384
1294
|
|
|
1385
1295
|
/**
|
|
1386
1296
|
* get instance data
|
|
1297
|
+
*
|
|
1387
1298
|
*@param {string} instanceObject
|
|
1388
1299
|
*/
|
|
1389
1300
|
async getInstanceData(instanceObject) {
|
|
@@ -1392,22 +1303,23 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1392
1303
|
|
|
1393
1304
|
this.adapterUpdatesJsonRaw = await this.getAdapterUpdateData(adapterUpdateListDP);
|
|
1394
1305
|
|
|
1395
|
-
|
|
1396
1306
|
for (const [id] of Object.entries(instanceAliveDP)) {
|
|
1397
|
-
if (!(typeof id === 'string' && id.startsWith(`system.adapter.`)))
|
|
1307
|
+
if (!(typeof id === 'string' && id.startsWith(`system.adapter.`))) {
|
|
1308
|
+
continue;
|
|
1309
|
+
}
|
|
1398
1310
|
|
|
1399
1311
|
// get instance name
|
|
1400
1312
|
const instanceID = await this.getInstanceName(id);
|
|
1401
1313
|
|
|
1402
1314
|
// get instance connected to host data
|
|
1403
1315
|
const instanceConnectedHostDP = `system.adapter.${instanceID}.connected`;
|
|
1404
|
-
const instanceConnectedHostVal = await tools.getInitValue(this,instanceConnectedHostDP);
|
|
1316
|
+
const instanceConnectedHostVal = await tools.getInitValue(this, instanceConnectedHostDP);
|
|
1405
1317
|
|
|
1406
1318
|
// get instance connected to device data
|
|
1407
1319
|
const instanceConnectedDeviceDP = `${instanceID}.info.connection`;
|
|
1408
1320
|
let instanceConnectedDeviceVal;
|
|
1409
1321
|
if (instanceConnectedDeviceDP !== undefined && typeof instanceConnectedDeviceDP === 'boolean') {
|
|
1410
|
-
instanceConnectedDeviceVal = await tools.getInitValue(this,instanceConnectedDeviceDP);
|
|
1322
|
+
instanceConnectedDeviceVal = await tools.getInitValue(this, instanceConnectedDeviceDP);
|
|
1411
1323
|
} else {
|
|
1412
1324
|
instanceConnectedDeviceVal = 'N/A';
|
|
1413
1325
|
}
|
|
@@ -1421,7 +1333,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1421
1333
|
let scheduleTime = 'N/A';
|
|
1422
1334
|
const instanceObjectData = await this.getForeignObjectAsync(instanceObjectPath);
|
|
1423
1335
|
if (instanceObjectData) {
|
|
1424
|
-
// @ts-ignore
|
|
1425
1336
|
adapterName = tools.capitalize(instanceObjectData.common.name);
|
|
1426
1337
|
adapterVersion = instanceObjectData.common.version;
|
|
1427
1338
|
instanceMode = instanceObjectData.common.mode;
|
|
@@ -1431,10 +1342,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1431
1342
|
}
|
|
1432
1343
|
}
|
|
1433
1344
|
|
|
1434
|
-
|
|
1435
|
-
const updateEntry = this.adapterUpdatesJsonRaw.find(
|
|
1436
|
-
entry => entry.adapter.toLowerCase() === adapterName.toLowerCase()
|
|
1437
|
-
);
|
|
1345
|
+
const updateEntry = this.adapterUpdatesJsonRaw.find((entry) => entry.adapter.toLowerCase() === adapterName.toLowerCase());
|
|
1438
1346
|
|
|
1439
1347
|
if (updateEntry) {
|
|
1440
1348
|
adapterAvailableUpdate = updateEntry.newVersion;
|
|
@@ -1492,6 +1400,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1492
1400
|
|
|
1493
1401
|
/**
|
|
1494
1402
|
* get Instances
|
|
1403
|
+
*
|
|
1495
1404
|
* @param {string} id - Path of alive datapoint
|
|
1496
1405
|
*/
|
|
1497
1406
|
async getInstanceName(id) {
|
|
@@ -1503,12 +1412,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1503
1412
|
|
|
1504
1413
|
/**
|
|
1505
1414
|
* Check if instance is alive and ok
|
|
1415
|
+
*
|
|
1506
1416
|
* @param {string} instanceID
|
|
1507
1417
|
*/
|
|
1508
1418
|
async checkDaemonIsHealthy(instanceID) {
|
|
1509
|
-
const connectedHostState = await tools.getInitValue(this
|
|
1510
|
-
const isAlive = await tools.getInitValue(this
|
|
1511
|
-
let connectedDeviceState = await tools.getInitValue(this
|
|
1419
|
+
const connectedHostState = await tools.getInitValue(this, `system.adapter.${instanceID}.connected`);
|
|
1420
|
+
const isAlive = await tools.getInitValue(this, `system.adapter.${instanceID}.alive`);
|
|
1421
|
+
let connectedDeviceState = await tools.getInitValue(this, `${instanceID}.info.connection`);
|
|
1512
1422
|
if (connectedDeviceState === undefined) {
|
|
1513
1423
|
connectedDeviceState = true;
|
|
1514
1424
|
}
|
|
@@ -1532,11 +1442,12 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1532
1442
|
|
|
1533
1443
|
/**
|
|
1534
1444
|
* Check if instance is alive and ok
|
|
1445
|
+
*
|
|
1535
1446
|
* @param {string} instanceID
|
|
1536
1447
|
* @param {number} instanceDeactivationTime
|
|
1537
1448
|
*/
|
|
1538
1449
|
async checkDaemonIsAlive(instanceID, instanceDeactivationTime) {
|
|
1539
|
-
let isAlive = await tools.getInitValue(this
|
|
1450
|
+
let isAlive = await tools.getInitValue(this, `system.adapter.${instanceID}.alive`);
|
|
1540
1451
|
let daemonIsAlive;
|
|
1541
1452
|
let isHealthy = false;
|
|
1542
1453
|
let instanceStatusString = isAlive ? translations.instance_activated[this.config.userSelectedLanguage] : translations.instance_deactivated[this.config.userSelectedLanguage];
|
|
@@ -1573,7 +1484,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1573
1484
|
|
|
1574
1485
|
if (isAliveSchedule) {
|
|
1575
1486
|
lastUpdate = Math.round((Date.now() - isAliveSchedule.lc) / 1000); // Last state change in seconds
|
|
1576
|
-
previousCronRun =
|
|
1487
|
+
previousCronRun = this.getPreviousCronRun(scheduleTime); // When was the last cron run
|
|
1577
1488
|
if (previousCronRun) {
|
|
1578
1489
|
lastCronRun = Math.round(previousCronRun / 1000); // change distance to last run in seconds
|
|
1579
1490
|
diff = lastCronRun - lastUpdate;
|
|
@@ -1591,6 +1502,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1591
1502
|
|
|
1592
1503
|
/**
|
|
1593
1504
|
* set status for instance
|
|
1505
|
+
*
|
|
1594
1506
|
* @param {string} instanceMode
|
|
1595
1507
|
* @param {string} scheduleTime
|
|
1596
1508
|
* @param {any} instanceID
|
|
@@ -1655,33 +1567,29 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1655
1567
|
|
|
1656
1568
|
/**
|
|
1657
1569
|
* create adapter update raw lists
|
|
1570
|
+
*
|
|
1658
1571
|
* @param {string} adapterUpdateListDP
|
|
1659
1572
|
*/
|
|
1660
1573
|
async getAdapterUpdateData(adapterUpdateListDP) {
|
|
1661
1574
|
// Clear the existing adapter updates data
|
|
1662
1575
|
let adapterUpdatesJsonRaw = [];
|
|
1576
|
+
let adapterJsonList;
|
|
1663
1577
|
|
|
1664
1578
|
// Fetch the adapter updates list
|
|
1665
1579
|
const adapterUpdatesListVal = await this.getForeignStatesAsync(adapterUpdateListDP);
|
|
1666
1580
|
|
|
1667
|
-
let adapterJsonList;
|
|
1668
|
-
let adapterUpdatesJsonPath;
|
|
1669
|
-
|
|
1670
1581
|
// Extract adapter data from the list
|
|
1671
1582
|
for (const [id, value] of Object.entries(adapterUpdatesListVal)) {
|
|
1672
1583
|
adapterJsonList = tools.parseData(value.val);
|
|
1673
|
-
adapterUpdatesJsonPath = id;
|
|
1674
1584
|
}
|
|
1675
1585
|
|
|
1676
1586
|
// Populate the adapter updates data
|
|
1677
1587
|
for (const [id, adapterData] of Object.entries(adapterJsonList)) {
|
|
1678
|
-
adapterUpdatesJsonRaw.push(
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
}
|
|
1684
|
-
);
|
|
1588
|
+
adapterUpdatesJsonRaw.push({
|
|
1589
|
+
adapter: tools.capitalize(id),
|
|
1590
|
+
newVersion: adapterData.availableVersion,
|
|
1591
|
+
oldVersion: adapterData.installedVersion,
|
|
1592
|
+
});
|
|
1685
1593
|
}
|
|
1686
1594
|
|
|
1687
1595
|
return adapterUpdatesJsonRaw;
|
|
@@ -1746,7 +1654,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1746
1654
|
});
|
|
1747
1655
|
}
|
|
1748
1656
|
|
|
1749
|
-
if (this.blacklistInstancesLists.includes(instance))
|
|
1657
|
+
if (this.blacklistInstancesLists.includes(instance)) {
|
|
1658
|
+
continue;
|
|
1659
|
+
}
|
|
1750
1660
|
// all instances
|
|
1751
1661
|
this.listAllInstances.push({
|
|
1752
1662
|
[translations.Adapter[this.config.userSelectedLanguage]]: instanceData.Adapter,
|
|
@@ -1862,9 +1772,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1862
1772
|
|
|
1863
1773
|
// Update instances with available adapter updates
|
|
1864
1774
|
for (const instance of this.listInstanceRaw.values()) {
|
|
1865
|
-
const adapterUpdate = this.adapterUpdatesJsonRaw.find(
|
|
1866
|
-
entry => entry.adapter.toLowerCase() === instance.Adapter.toLowerCase()
|
|
1867
|
-
);
|
|
1775
|
+
const adapterUpdate = this.adapterUpdatesJsonRaw.find((entry) => entry.adapter.toLowerCase() === instance.Adapter.toLowerCase());
|
|
1868
1776
|
|
|
1869
1777
|
if (adapterUpdate) {
|
|
1870
1778
|
instance.updateAvailable = adapterUpdate.newVersion;
|
|
@@ -1875,6 +1783,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1875
1783
|
}
|
|
1876
1784
|
/**
|
|
1877
1785
|
* call function on state change, renew data and send messages
|
|
1786
|
+
*
|
|
1878
1787
|
* @param {string} id
|
|
1879
1788
|
* @param {ioBroker.State} state
|
|
1880
1789
|
*/
|
|
@@ -1900,7 +1809,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1900
1809
|
await checkInstance(instanceID, instanceData);
|
|
1901
1810
|
// send message when instance was deactivated
|
|
1902
1811
|
if (this.config.checkSendInstanceDeactivatedMsg && !instanceData.isAlive) {
|
|
1903
|
-
if (this.blacklistInstancesNotify.includes(instanceID))
|
|
1812
|
+
if (this.blacklistInstancesNotify.includes(instanceID)) {
|
|
1813
|
+
return;
|
|
1814
|
+
}
|
|
1904
1815
|
await this.sendStateNotifications('Instances', 'deactivatedInstance', instanceID);
|
|
1905
1816
|
}
|
|
1906
1817
|
}
|
|
@@ -1911,7 +1822,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1911
1822
|
await checkInstance(instanceID, instanceData);
|
|
1912
1823
|
// send message when instance has an error
|
|
1913
1824
|
if (this.config.checkSendInstanceFailedMsg && !instanceData.isHealthy && instanceData.isAlive) {
|
|
1914
|
-
if (this.blacklistInstancesNotify.includes(instanceID))
|
|
1825
|
+
if (this.blacklistInstancesNotify.includes(instanceID)) {
|
|
1826
|
+
return;
|
|
1827
|
+
}
|
|
1915
1828
|
await this.sendStateNotifications('Instances', 'errorInstance', instanceID);
|
|
1916
1829
|
}
|
|
1917
1830
|
}
|
|
@@ -1922,7 +1835,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1922
1835
|
await checkInstance(instanceID, instanceData);
|
|
1923
1836
|
// send message when instance has an error
|
|
1924
1837
|
if (this.config.checkSendInstanceFailedMsg && !instanceData.isHealthy && instanceData.isAlive) {
|
|
1925
|
-
if (this.blacklistInstancesNotify.includes(instanceID))
|
|
1838
|
+
if (this.blacklistInstancesNotify.includes(instanceID)) {
|
|
1839
|
+
return;
|
|
1840
|
+
}
|
|
1926
1841
|
await this.sendStateNotifications('Instances', 'errorInstance', instanceID);
|
|
1927
1842
|
}
|
|
1928
1843
|
}
|
|
@@ -1937,14 +1852,16 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1937
1852
|
|
|
1938
1853
|
/**
|
|
1939
1854
|
* Notification service
|
|
1855
|
+
*
|
|
1940
1856
|
* @param {string} text - Text which should be send
|
|
1857
|
+
* @param silent
|
|
1941
1858
|
*/
|
|
1942
|
-
async sendNotification(text) {
|
|
1859
|
+
async sendNotification(text, silent = false) {
|
|
1943
1860
|
// Pushover
|
|
1944
1861
|
if (this.config.instancePushover) {
|
|
1945
1862
|
try {
|
|
1946
1863
|
//first check if instance is living
|
|
1947
|
-
const pushoverAliveState = await tools.getInitValue(this,
|
|
1864
|
+
const pushoverAliveState = await tools.getInitValue(this, `system.adapter.${this.config.instancePushover}.alive`);
|
|
1948
1865
|
|
|
1949
1866
|
if (!pushoverAliveState) {
|
|
1950
1867
|
this.log.warn('Pushover instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
@@ -1966,7 +1883,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1966
1883
|
if (this.config.instanceTelegram) {
|
|
1967
1884
|
try {
|
|
1968
1885
|
//first check if instance is living
|
|
1969
|
-
const telegramAliveState = await tools.getInitValue(this,
|
|
1886
|
+
const telegramAliveState = await tools.getInitValue(this, `system.adapter.${this.config.instanceTelegram}.alive`);
|
|
1970
1887
|
|
|
1971
1888
|
if (!telegramAliveState) {
|
|
1972
1889
|
this.log.warn('Telegram instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
@@ -1975,6 +1892,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1975
1892
|
text: text,
|
|
1976
1893
|
user: this.config.deviceTelegram,
|
|
1977
1894
|
chatId: this.config.chatIdTelegram,
|
|
1895
|
+
disable_notification: silent,
|
|
1978
1896
|
});
|
|
1979
1897
|
}
|
|
1980
1898
|
} catch (error) {
|
|
@@ -1986,7 +1904,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1986
1904
|
if (this.config.instanceWhatsapp) {
|
|
1987
1905
|
try {
|
|
1988
1906
|
//first check if instance is living
|
|
1989
|
-
const whatsappAliveState = await tools.getInitValue(this,
|
|
1907
|
+
const whatsappAliveState = await tools.getInitValue(this, `system.adapter.${this.config.instanceWhatsapp}.alive`);
|
|
1990
1908
|
|
|
1991
1909
|
if (!whatsappAliveState) {
|
|
1992
1910
|
this.log.warn('Whatsapp instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
@@ -2005,7 +1923,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2005
1923
|
if (this.config.instanceMatrix) {
|
|
2006
1924
|
try {
|
|
2007
1925
|
//first check if instance is living
|
|
2008
|
-
const matrixAliveState = await tools.getInitValue(this,
|
|
1926
|
+
const matrixAliveState = await tools.getInitValue(this, `system.adapter.${this.config.instanceMatrix}.alive`);
|
|
2009
1927
|
|
|
2010
1928
|
if (!matrixAliveState) {
|
|
2011
1929
|
this.log.warn('Matrix instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
@@ -2024,7 +1942,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2024
1942
|
if (this.config.instanceSignal) {
|
|
2025
1943
|
try {
|
|
2026
1944
|
//first check if instance is living
|
|
2027
|
-
const signalAliveState = await tools.getInitValue(this,
|
|
1945
|
+
const signalAliveState = await tools.getInitValue(this, `system.adapter.${this.config.instanceSignal}.alive`);
|
|
2028
1946
|
|
|
2029
1947
|
if (!signalAliveState) {
|
|
2030
1948
|
this.log.warn('Signal instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
@@ -2043,7 +1961,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2043
1961
|
if (this.config.instanceEmail) {
|
|
2044
1962
|
try {
|
|
2045
1963
|
//first check if instance is living
|
|
2046
|
-
const eMailAliveState = await tools.getInitValue(this,
|
|
1964
|
+
const eMailAliveState = await tools.getInitValue(this, `system.adapter.${this.config.instanceEmail}.alive`);
|
|
2047
1965
|
|
|
2048
1966
|
if (!eMailAliveState) {
|
|
2049
1967
|
this.log.warn('eMail instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
@@ -2063,7 +1981,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2063
1981
|
if (this.config.instanceJarvis) {
|
|
2064
1982
|
try {
|
|
2065
1983
|
//first check if instance is living
|
|
2066
|
-
const jarvisAliveState = await tools.getInitValue(this,
|
|
1984
|
+
const jarvisAliveState = await tools.getInitValue(this, `system.adapter.${this.config.instanceJarvis}.alive`);
|
|
2067
1985
|
|
|
2068
1986
|
if (!jarvisAliveState) {
|
|
2069
1987
|
this.log.warn('Jarvis instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
@@ -2071,7 +1989,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2071
1989
|
const jsonText = JSON.stringify(text);
|
|
2072
1990
|
await this.setForeignStateAsync(
|
|
2073
1991
|
`${this.config.instanceJarvis}.addNotification`,
|
|
2074
|
-
|
|
1992
|
+
`{"title":"${this.config.titleJarvis} (${this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss')})","message": ${jsonText},"display": "drawer"}`,
|
|
2075
1993
|
);
|
|
2076
1994
|
}
|
|
2077
1995
|
} catch (error) {
|
|
@@ -2083,7 +2001,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2083
2001
|
if (this.config.instanceLovelace) {
|
|
2084
2002
|
try {
|
|
2085
2003
|
//first check if instance is living
|
|
2086
|
-
const lovelaceAliveState = await tools.getInitValue(this,
|
|
2004
|
+
const lovelaceAliveState = await tools.getInitValue(this, `system.adapter.${this.config.instanceLovelace}.alive`);
|
|
2087
2005
|
|
|
2088
2006
|
if (!lovelaceAliveState) {
|
|
2089
2007
|
this.log.warn('Lovelace instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
@@ -2091,7 +2009,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2091
2009
|
const jsonText = JSON.stringify(text);
|
|
2092
2010
|
await this.setForeignStateAsync(
|
|
2093
2011
|
`${this.config.instanceLovelace}.notifications.add`,
|
|
2094
|
-
|
|
2012
|
+
`{"message":${jsonText}, "title":"${this.config.titleLovelace} (${this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss')})"}`,
|
|
2095
2013
|
);
|
|
2096
2014
|
}
|
|
2097
2015
|
} catch (error) {
|
|
@@ -2103,7 +2021,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2103
2021
|
if (this.config.instanceSynochat) {
|
|
2104
2022
|
try {
|
|
2105
2023
|
//first check if instance is living
|
|
2106
|
-
const synochatAliveState = await tools.getInitValue(this,
|
|
2024
|
+
const synochatAliveState = await tools.getInitValue(this, `system.adapter.${this.config.instanceSynochat}.alive`);
|
|
2107
2025
|
|
|
2108
2026
|
if (!synochatAliveState) {
|
|
2109
2027
|
this.log.warn('Synochat instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
@@ -2123,12 +2041,16 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2123
2041
|
/*---------- Notifications ----------*/
|
|
2124
2042
|
/**
|
|
2125
2043
|
* Notifications on state changes
|
|
2044
|
+
*
|
|
2126
2045
|
* @param {string} mainType
|
|
2127
2046
|
* @param {string} type
|
|
2128
2047
|
* @param {object} id
|
|
2048
|
+
* @param silent
|
|
2129
2049
|
*/
|
|
2130
|
-
async sendStateNotifications(mainType, type, id) {
|
|
2131
|
-
if (isUnloaded)
|
|
2050
|
+
async sendStateNotifications(mainType, type, id, silent = false) {
|
|
2051
|
+
if (isUnloaded) {
|
|
2052
|
+
return;
|
|
2053
|
+
}
|
|
2132
2054
|
let objectData;
|
|
2133
2055
|
let adapterName;
|
|
2134
2056
|
let list = '';
|
|
@@ -2146,7 +2068,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2146
2068
|
const setMessage = async (message) => {
|
|
2147
2069
|
this.log.info(message);
|
|
2148
2070
|
await this.setStateAsync('lastNotification', message, true);
|
|
2149
|
-
await this.sendNotification(message);
|
|
2071
|
+
await this.sendNotification(message, silent);
|
|
2150
2072
|
};
|
|
2151
2073
|
|
|
2152
2074
|
switch (type) {
|
|
@@ -2174,7 +2096,9 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2174
2096
|
break;
|
|
2175
2097
|
|
|
2176
2098
|
case 'updateAdapter':
|
|
2177
|
-
if (this.countAdapterUpdates === 0)
|
|
2099
|
+
if (this.countAdapterUpdates === 0) {
|
|
2100
|
+
return;
|
|
2101
|
+
}
|
|
2178
2102
|
|
|
2179
2103
|
objectData = this.listAdapterUpdates;
|
|
2180
2104
|
list = '';
|
|
@@ -2197,10 +2121,14 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2197
2121
|
|
|
2198
2122
|
/**
|
|
2199
2123
|
* Notifications per user defined schedule
|
|
2124
|
+
*
|
|
2200
2125
|
* @param {string} type
|
|
2126
|
+
* @param silent
|
|
2201
2127
|
*/
|
|
2202
|
-
async sendScheduleNotifications(type) {
|
|
2203
|
-
if (isUnloaded)
|
|
2128
|
+
async sendScheduleNotifications(type, silent = false) {
|
|
2129
|
+
if (isUnloaded) {
|
|
2130
|
+
return;
|
|
2131
|
+
}
|
|
2204
2132
|
|
|
2205
2133
|
const checkDays = [];
|
|
2206
2134
|
const dayConfigKeys = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
@@ -2211,28 +2139,34 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2211
2139
|
this.log.info(message);
|
|
2212
2140
|
await this.setStateAsync('lastNotification', message, true);
|
|
2213
2141
|
if (!message.includes('no updates')) {
|
|
2214
|
-
await this.sendNotification(message);
|
|
2142
|
+
await this.sendNotification(message, silent);
|
|
2215
2143
|
}
|
|
2216
2144
|
};
|
|
2217
2145
|
|
|
2218
2146
|
const processDeviceList = (deviceList, property1, property2) => {
|
|
2219
2147
|
list = '';
|
|
2220
2148
|
for (const id of deviceList) {
|
|
2221
|
-
if (this.blacklistNotify.includes(id.Path))
|
|
2222
|
-
|
|
2149
|
+
if (this.blacklistNotify.includes(id.Path)) {
|
|
2150
|
+
continue;
|
|
2151
|
+
}
|
|
2152
|
+
list += `\n${!this.config.showAdapterNameinMsg ? '' : `${id.Adapter}: `}${id[property1]}${property2 ? ` (${id[property2]})` : ''}`;
|
|
2223
2153
|
}
|
|
2224
2154
|
};
|
|
2225
2155
|
|
|
2226
2156
|
const processInstanceList = (instanceList, property) => {
|
|
2227
2157
|
list = '';
|
|
2228
2158
|
for (const id of instanceList) {
|
|
2229
|
-
if (this.blacklistInstancesNotify.includes(id[translations['Instance'][this.config.userSelectedLanguage]]))
|
|
2159
|
+
if (this.blacklistInstancesNotify.includes(id[translations['Instance'][this.config.userSelectedLanguage]])) {
|
|
2160
|
+
continue;
|
|
2161
|
+
}
|
|
2230
2162
|
list += `\n${id[translations['Instance'][this.config.userSelectedLanguage]]}${property ? `: ${id[property]}` : ''}`;
|
|
2231
2163
|
}
|
|
2232
2164
|
};
|
|
2233
2165
|
|
|
2234
2166
|
const processNotification = async (list, messageType) => {
|
|
2235
|
-
if (list.length === 0)
|
|
2167
|
+
if (list.length === 0) {
|
|
2168
|
+
return;
|
|
2169
|
+
}
|
|
2236
2170
|
|
|
2237
2171
|
switch (checkDays.length) {
|
|
2238
2172
|
case 1:
|
|
@@ -2251,7 +2185,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2251
2185
|
|
|
2252
2186
|
switch (type) {
|
|
2253
2187
|
case 'lowBatteryDevices':
|
|
2254
|
-
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[
|
|
2188
|
+
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[`check${day}`] ? index : null)).filter((day) => day !== null));
|
|
2255
2189
|
|
|
2256
2190
|
if (checkDays.length === 0) {
|
|
2257
2191
|
this.log.warn(`No days selected for daily low battery devices message. Please check the instance configuration!`);
|
|
@@ -2267,7 +2201,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2267
2201
|
break;
|
|
2268
2202
|
|
|
2269
2203
|
case 'offlineDevices':
|
|
2270
|
-
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[
|
|
2204
|
+
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[`checkOffline${day}`] ? index : null)).filter((day) => day !== null));
|
|
2271
2205
|
|
|
2272
2206
|
if (checkDays.length === 0) {
|
|
2273
2207
|
this.log.warn(`No days selected for daily offline devices message. Please check the instance configuration!`);
|
|
@@ -2283,7 +2217,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2283
2217
|
break;
|
|
2284
2218
|
|
|
2285
2219
|
case 'updateDevices':
|
|
2286
|
-
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[
|
|
2220
|
+
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[`checkUpgrade${day}`] ? index : null)).filter((day) => day !== null));
|
|
2287
2221
|
|
|
2288
2222
|
if (checkDays.length === 0) {
|
|
2289
2223
|
this.log.warn(`No days selected for daily updatable devices message. Please check the instance configuration!`);
|
|
@@ -2299,7 +2233,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2299
2233
|
break;
|
|
2300
2234
|
|
|
2301
2235
|
case 'updateAdapter':
|
|
2302
|
-
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[
|
|
2236
|
+
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[`checkAdapterUpdate${day}`] ? index : null)).filter((day) => day !== null));
|
|
2303
2237
|
|
|
2304
2238
|
if (checkDays.length === 0) {
|
|
2305
2239
|
this.log.warn(`No days selected for daily adapter update message. Please check the instance configuration!`);
|
|
@@ -2317,7 +2251,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2317
2251
|
break;
|
|
2318
2252
|
|
|
2319
2253
|
case 'errorInstance':
|
|
2320
|
-
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[
|
|
2254
|
+
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[`checkFailedInstances${day}`] ? index : null)).filter((day) => day !== null));
|
|
2321
2255
|
|
|
2322
2256
|
if (checkDays.length === 0) {
|
|
2323
2257
|
this.log.warn(`No days selected for daily instance error message. Please check the instance configuration!`);
|
|
@@ -2333,7 +2267,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2333
2267
|
break;
|
|
2334
2268
|
|
|
2335
2269
|
case 'deactivatedInstance':
|
|
2336
|
-
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[
|
|
2270
|
+
checkDays.push(...dayConfigKeys.map((day, index) => (this.config[`checkInstanceDeactivated${day}`] ? index : null)).filter((day) => day !== null));
|
|
2337
2271
|
|
|
2338
2272
|
if (checkDays.length === 0) {
|
|
2339
2273
|
this.log.warn(`No days selected for daily instance deactivated message. Please check the instance configuration!`);
|
|
@@ -2349,6 +2283,19 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2349
2283
|
break;
|
|
2350
2284
|
}
|
|
2351
2285
|
}
|
|
2286
|
+
async getPreviousCronRun(lastCronRun) {
|
|
2287
|
+
try {
|
|
2288
|
+
const cronParser = cronParserLib.parseExpression
|
|
2289
|
+
? cronParserLib // klassischer Import
|
|
2290
|
+
: cronParserLib.default; // ESM-Fallback
|
|
2291
|
+
|
|
2292
|
+
const interval = cronParser.parseExpression(lastCronRun);
|
|
2293
|
+
const previous = interval.prev();
|
|
2294
|
+
return Math.floor(Date.now() - previous.getTime()); // in ms
|
|
2295
|
+
} catch (error) {
|
|
2296
|
+
this.log.error(`[getPreviousCronRun] - ${error}`);
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2352
2299
|
|
|
2353
2300
|
/**
|
|
2354
2301
|
* @param {() => void} callback
|
|
@@ -2373,11 +2320,10 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2373
2320
|
}
|
|
2374
2321
|
}
|
|
2375
2322
|
|
|
2376
|
-
// @ts-ignore parent is a valid property on module
|
|
2377
2323
|
if (require.main !== module) {
|
|
2378
2324
|
// Export the constructor in compact mode
|
|
2379
2325
|
/**
|
|
2380
|
-
* @param {Partial<utils.AdapterOptions>} [options
|
|
2326
|
+
* @param {Partial<utils.AdapterOptions>} [options]
|
|
2381
2327
|
*/
|
|
2382
2328
|
module.exports = (options) => new DeviceWatcher(options);
|
|
2383
2329
|
} else {
|