iobroker.device-watcher 2.5.0 → 2.6.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/README.md +22 -0
- package/admin/i18n/de/translations.json +135 -120
- package/admin/i18n/en/translations.json +15 -1
- package/admin/i18n/es/translations.json +16 -1
- package/admin/i18n/fr/translations.json +16 -1
- package/admin/i18n/it/translations.json +16 -1
- package/admin/i18n/nl/translations.json +16 -1
- package/admin/i18n/pl/translations.json +16 -1
- package/admin/i18n/pt/translations.json +16 -1
- package/admin/i18n/ru/translations.json +16 -1
- package/admin/i18n/uk/translations.json +16 -1
- package/admin/i18n/zh-cn/translations.json +16 -1
- package/admin/jsonConfig.json +131 -48
- package/io-package.json +805 -792
- package/lib/arrApart.js +22 -0
- package/main.js +1344 -1198
- package/package.json +7 -6
package/main.js
CHANGED
|
@@ -26,13 +26,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
26
26
|
|
|
27
27
|
// instances and adapters
|
|
28
28
|
// raw arrays
|
|
29
|
-
this.
|
|
30
|
-
this.
|
|
29
|
+
this.listInstanceRaw = new Map();
|
|
30
|
+
this.adapterUpdatesJsonRaw = new Map();
|
|
31
31
|
this.listErrorInstanceRaw = [];
|
|
32
32
|
|
|
33
33
|
// user arrays
|
|
34
|
-
this.blacklistInstancesLists = [];
|
|
35
|
-
this.blacklistInstancesNotify = [];
|
|
36
34
|
this.listAllInstances = [];
|
|
37
35
|
this.listDeactivatedInstances = [];
|
|
38
36
|
this.listAdapterUpdates = [];
|
|
@@ -45,25 +43,23 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
45
43
|
this.countErrorInstance = 0;
|
|
46
44
|
|
|
47
45
|
// devices
|
|
46
|
+
// raw arrays
|
|
47
|
+
this.listAllDevicesRaw = new Map();
|
|
48
|
+
this.batteryLowPoweredRaw = [];
|
|
49
|
+
this.offlineDevicesRaw = [];
|
|
50
|
+
this.upgradableDevicesRaw = [];
|
|
51
|
+
|
|
48
52
|
// arrays
|
|
53
|
+
this.listAllDevicesUserRaw = [];
|
|
54
|
+
this.listAllDevices = [];
|
|
49
55
|
this.offlineDevices = [];
|
|
50
56
|
this.linkQualityDevices = [];
|
|
51
57
|
this.batteryPowered = [];
|
|
52
58
|
this.batteryLowPowered = [];
|
|
53
|
-
this.listAllDevices = [];
|
|
54
|
-
this.blacklistLists = [];
|
|
55
|
-
this.blacklistAdapterLists = [];
|
|
56
|
-
this.blacklistNotify = [];
|
|
57
59
|
this.selAdapter = [];
|
|
58
60
|
this.adapterSelected = [];
|
|
59
61
|
this.upgradableList = [];
|
|
60
62
|
|
|
61
|
-
// raw arrays
|
|
62
|
-
this.listAllDevicesRaw = [];
|
|
63
|
-
this.batteryLowPoweredRaw = [];
|
|
64
|
-
this.offlineDevicesRaw = [];
|
|
65
|
-
this.upgradableDevicesRaw = [];
|
|
66
|
-
|
|
67
63
|
// counts
|
|
68
64
|
this.offlineDevicesCount = 0;
|
|
69
65
|
this.deviceCounter = 0;
|
|
@@ -72,12 +68,22 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
72
68
|
this.lowBatteryPoweredCount = 0;
|
|
73
69
|
this.upgradableDevicesCount = 0;
|
|
74
70
|
|
|
71
|
+
// Blacklist
|
|
72
|
+
// Instances
|
|
73
|
+
this.blacklistInstancesLists = [];
|
|
74
|
+
this.blacklistInstancesNotify = [];
|
|
75
|
+
|
|
76
|
+
// Devices
|
|
77
|
+
this.blacklistLists = [];
|
|
78
|
+
this.blacklistAdapterLists = [];
|
|
79
|
+
this.blacklistNotify = [];
|
|
80
|
+
|
|
75
81
|
// Interval timer
|
|
76
82
|
this.refreshDataTimeout = null;
|
|
77
83
|
|
|
78
84
|
this.on('ready', this.onReady.bind(this));
|
|
79
85
|
this.on('stateChange', this.onStateChange.bind(this));
|
|
80
|
-
|
|
86
|
+
this.on('objectChange', this.onObjectChange.bind(this));
|
|
81
87
|
this.on('message', this.onMessage.bind(this));
|
|
82
88
|
this.on('unload', this.onUnload.bind(this));
|
|
83
89
|
}
|
|
@@ -88,117 +94,122 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
88
94
|
async onReady() {
|
|
89
95
|
this.log.debug(`Adapter ${adapterName} was started`);
|
|
90
96
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
97
|
+
this.configCreateInstanceList = this.config.checkAdapterInstances;
|
|
98
|
+
this.configListOnlyBattery = this.config.listOnlyBattery;
|
|
99
|
+
this.configCreateOwnFolder = this.config.createOwnFolder;
|
|
100
|
+
this.configCreateHtmlList = this.config.createHtmlList;
|
|
101
|
+
|
|
102
|
+
this.configSetAdapter = {
|
|
103
|
+
alexa2: this.config.alexa2Devices,
|
|
104
|
+
apcups: this.config.apcupsDevices,
|
|
105
|
+
ble: this.config.bleDevices,
|
|
106
|
+
deconz: this.config.deconzDevices,
|
|
107
|
+
enocean: this.config.enoceanDevices,
|
|
108
|
+
esphome: this.config.esphomeDevices,
|
|
109
|
+
eusec: this.config.eusecDevices,
|
|
110
|
+
fhemTFAsensors: this.config.fhemTFAsensorsDevices,
|
|
111
|
+
fritzdect: this.config.fritzdectDevices,
|
|
112
|
+
fullybrowser: this.config.fullybrowserDevices,
|
|
113
|
+
ham: this.config.hamDevices,
|
|
114
|
+
harmony: this.config.harmonyDevices,
|
|
115
|
+
hmiP: this.config.hmiPDevices,
|
|
116
|
+
hmrpc: this.config.hmrpcDevices,
|
|
117
|
+
homeconnect: this.config.homeconnectDevices,
|
|
118
|
+
hs100: this.config.hs100Devices,
|
|
119
|
+
hue: this.config.hueDevices,
|
|
120
|
+
hueExt: this.config.hueExtDevices,
|
|
121
|
+
innogy: this.config.innogyDevices,
|
|
122
|
+
jeelink: this.config.jeelinkDevices,
|
|
123
|
+
lupusec: this.config.lupusecDevices,
|
|
124
|
+
maxcube: this.config.maxcubeDevices,
|
|
125
|
+
meross: this.config.merossDevices,
|
|
126
|
+
mihome: this.config.mihomeDevices,
|
|
127
|
+
mihomeGW: this.config.mihomeDevices,
|
|
128
|
+
mihomeVacuum: this.config.mihomeVacuumDevices,
|
|
129
|
+
mqttClientZigbee2Mqtt: this.config.mqttClientZigbee2MqttDevices,
|
|
130
|
+
mqttNuki: this.config.mqttNukiDevices,
|
|
131
|
+
musiccast: this.config.musiccastDevices,
|
|
132
|
+
netatmo: this.config.netatmoDevices,
|
|
133
|
+
nukiExt: this.config.nukiExtDevices,
|
|
134
|
+
nut: this.config.nutDevices,
|
|
135
|
+
ping: this.config.pingDevices,
|
|
136
|
+
proxmox: this.config.proxmoxDevices,
|
|
137
|
+
roomba: this.config.roombaDevices,
|
|
138
|
+
shelly: this.config.shellyDevices,
|
|
139
|
+
smartgarden: this.config.smartgardenDevices,
|
|
140
|
+
sonoff: this.config.sonoffDevices,
|
|
141
|
+
sonos: this.config.sonosDevices,
|
|
142
|
+
sureflap: this.config.sureflapDevices,
|
|
143
|
+
switchbotBle: this.config.switchbotBleDevices,
|
|
144
|
+
tado: this.config.tadoDevices,
|
|
145
|
+
tapo: this.config.tapoDevices,
|
|
146
|
+
tradfri: this.config.tradfriDevices,
|
|
147
|
+
unifi: this.config.unifiDevices,
|
|
148
|
+
wled: this.config.wledDevices,
|
|
149
|
+
yeelight: this.config.yeelightDevices,
|
|
150
|
+
zigbee: this.config.zigbeeDevices,
|
|
151
|
+
zigbee2MQTT: this.config.zigbee2mqttDevices,
|
|
152
|
+
zwave: this.config.zwaveDevices,
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
this.configMaxMinutes = {
|
|
156
|
+
alexa2: this.config.alexa2MaxMinutes,
|
|
157
|
+
apcups: this.config.apcupsMaxMinutes,
|
|
158
|
+
ble: this.config.bleMaxMinutes,
|
|
159
|
+
deconz: this.config.deconzMaxMinutes,
|
|
160
|
+
enocean: this.config.enoceanMaxMinutes,
|
|
161
|
+
esphome: this.config.esphomeMaxMinutes,
|
|
162
|
+
eusec: this.config.eusecMaxMinutes,
|
|
163
|
+
fhemTFAsensors: this.config.fhemTFAsensorsMaxMinutes,
|
|
164
|
+
fritzdect: this.config.fritzdectMaxMinutes,
|
|
165
|
+
fullybrowser: this.config.fullybrowserMaxMinutes,
|
|
166
|
+
ham: this.config.hamMaxMinutes,
|
|
167
|
+
harmony: this.config.harmonyMaxMinutes,
|
|
168
|
+
hmiP: this.config.hmiPMaxMinutes,
|
|
169
|
+
hmrpc: this.config.hmrpcMaxMinutes,
|
|
170
|
+
homeconnect: this.config.homeconnectMaxMinutes,
|
|
171
|
+
hs100: this.config.hs100MaxMinutes,
|
|
172
|
+
hue: this.config.hueMaxMinutes,
|
|
173
|
+
hueExt: this.config.hueextMaxMinutes,
|
|
174
|
+
innogy: this.config.innogyMaxMinutes,
|
|
175
|
+
jeelink: this.config.jeelinkMaxMinutes,
|
|
176
|
+
lupusec: this.config.lupusecMaxMinutes,
|
|
177
|
+
maxcube: this.config.maxcubeMaxMinutes,
|
|
178
|
+
meross: this.config.merossMaxMinutes,
|
|
179
|
+
mihome: this.config.mihomeMaxMinutes,
|
|
180
|
+
mihomeGW: this.config.mihomeMaxMinutes,
|
|
181
|
+
mihomeVacuum: this.config.mihomeVacuumMaxMinutes,
|
|
182
|
+
mqttClientZigbee2Mqtt: this.config.mqttClientZigbee2MqttMaxMinutes,
|
|
183
|
+
mqttNuki: this.config.mqttNukiMaxMinutes,
|
|
184
|
+
musiccast: this.config.musiccastMaxMinutes,
|
|
185
|
+
netatmo: this.config.netatmoMaxMinutes,
|
|
186
|
+
nukiExt: this.config.nukiextendMaxMinutes,
|
|
187
|
+
nut: this.config.nutMaxMinutes,
|
|
188
|
+
ping: this.config.pingMaxMinutes,
|
|
189
|
+
proxmox: this.config.proxmoxMaxMinutes,
|
|
190
|
+
roomba: this.config.roombaMaxMinutes,
|
|
191
|
+
shelly: this.config.shellyMaxMinutes,
|
|
192
|
+
smartgarden: this.config.smartgardenMaxMinutes,
|
|
193
|
+
sonoff: this.config.sonoffMaxMinutes,
|
|
194
|
+
sonos: this.config.sonosMaxMinutes,
|
|
195
|
+
sureflap: this.config.sureflapMaxMinutes,
|
|
196
|
+
switchbotBle: this.config.switchbotMaxMinutes,
|
|
197
|
+
tado: this.config.tadoMaxMinutes,
|
|
198
|
+
tapo: this.config.tapoMaxMinutes,
|
|
199
|
+
tradfri: this.config.tradfriMaxMinutes,
|
|
200
|
+
unifi: this.config.unifiMaxMinutes,
|
|
201
|
+
wled: this.config.wledMaxMinutes,
|
|
202
|
+
yeelight: this.config.yeelightMaxMinutes,
|
|
203
|
+
zigbee: this.config.zigbeeMaxMinutes,
|
|
204
|
+
zigbee2MQTT: this.config.zigbee2mqttMaxMinutes,
|
|
205
|
+
zwave: this.config.zwaveMaxMinutes,
|
|
206
|
+
};
|
|
197
207
|
|
|
208
|
+
try {
|
|
198
209
|
for (const [id] of Object.entries(arrApart)) {
|
|
199
210
|
if (this.configSetAdapter[id]) {
|
|
200
211
|
this.selAdapter.push(arrApart[id]);
|
|
201
|
-
this.adapterSelected.push(
|
|
212
|
+
this.adapterSelected.push(this.capitalize(id));
|
|
202
213
|
}
|
|
203
214
|
}
|
|
204
215
|
|
|
@@ -214,19 +225,23 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
214
225
|
}
|
|
215
226
|
|
|
216
227
|
//create Blacklist
|
|
217
|
-
|
|
218
|
-
await this.createBlacklist();
|
|
219
|
-
} catch (error) {
|
|
220
|
-
this.errorReporting('[onReady - create blacklist]', error);
|
|
221
|
-
}
|
|
228
|
+
await this.createBlacklist();
|
|
222
229
|
|
|
223
|
-
//create
|
|
224
|
-
|
|
230
|
+
//create datapoints for each adapter if selected
|
|
231
|
+
for (const [id] of Object.entries(arrApart)) {
|
|
225
232
|
try {
|
|
226
|
-
|
|
227
|
-
|
|
233
|
+
if (!this.configCreateOwnFolder) {
|
|
234
|
+
await this.deleteDPsForEachAdapter(id);
|
|
235
|
+
await this.deleteHtmlListDatapoints(id);
|
|
236
|
+
} else {
|
|
237
|
+
if (this.configSetAdapter && this.configSetAdapter[id]) {
|
|
228
238
|
await this.createDPsForEachAdapter(id);
|
|
229
|
-
|
|
239
|
+
// create HTML list datapoints
|
|
240
|
+
if (!this.configCreateHtmlList) {
|
|
241
|
+
await this.deleteHtmlListDatapoints(id);
|
|
242
|
+
} else {
|
|
243
|
+
await this.createHtmlListDatapoints(id);
|
|
244
|
+
}
|
|
230
245
|
this.log.debug(`Created datapoints for ${this.capitalize(id)}`);
|
|
231
246
|
}
|
|
232
247
|
}
|
|
@@ -236,36 +251,98 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
236
251
|
}
|
|
237
252
|
|
|
238
253
|
// create HTML list datapoints
|
|
239
|
-
if (this.
|
|
254
|
+
if (!this.configCreateHtmlList) {
|
|
255
|
+
await this.deleteHtmlListDatapoints();
|
|
256
|
+
} else {
|
|
257
|
+
await this.createHtmlListDatapoints();
|
|
258
|
+
}
|
|
240
259
|
|
|
241
|
-
//read data first at start
|
|
260
|
+
// read data first at start
|
|
261
|
+
// devices
|
|
242
262
|
await this.main();
|
|
243
263
|
|
|
244
|
-
|
|
245
|
-
|
|
264
|
+
// instances and adapters
|
|
265
|
+
if (this.configCreateInstanceList) {
|
|
266
|
+
// instances
|
|
267
|
+
await this.createDPsForInstances();
|
|
268
|
+
await this.getAllInstanceData();
|
|
269
|
+
// adapter updates
|
|
246
270
|
await this.createAdapterUpdateData();
|
|
271
|
+
} else {
|
|
272
|
+
await this.deleteDPsForInstances();
|
|
247
273
|
}
|
|
248
274
|
|
|
249
275
|
// update last contact data in interval
|
|
250
276
|
await this.refreshData();
|
|
251
277
|
|
|
252
278
|
// send overview for low battery devices
|
|
253
|
-
if (this.config.checkSendBatteryMsgDaily)
|
|
279
|
+
if (this.config.checkSendBatteryMsgDaily) this.sendScheduleNotifications('lowBatteryDevices');
|
|
254
280
|
|
|
255
281
|
// send overview of offline devices
|
|
256
|
-
if (this.config.checkSendOfflineMsgDaily)
|
|
282
|
+
if (this.config.checkSendOfflineMsgDaily) this.sendScheduleNotifications('offlineDevices');
|
|
257
283
|
|
|
258
284
|
// send overview of upgradeable devices
|
|
259
|
-
if (this.config.checkSendUpgradeMsgDaily)
|
|
285
|
+
if (this.config.checkSendUpgradeMsgDaily) this.sendScheduleNotifications('updateDevices');
|
|
286
|
+
|
|
287
|
+
// send overview of updatable adapters
|
|
288
|
+
if (this.config.checkSendAdapterUpdateMsgDaily) this.sendScheduleNotifications('updateAdapter');
|
|
260
289
|
|
|
261
290
|
// send overview of instances with error
|
|
262
|
-
if (this.config.checkSendInstanceFailedDaily)
|
|
291
|
+
if (this.config.checkSendInstanceFailedDaily) this.sendScheduleNotifications('errorInstance');
|
|
263
292
|
} catch (error) {
|
|
264
293
|
this.errorReporting('[onReady]', error);
|
|
265
294
|
this.terminate ? this.terminate(15) : process.exit(15);
|
|
266
295
|
}
|
|
267
296
|
} // <-- onReady end
|
|
268
297
|
|
|
298
|
+
// If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.
|
|
299
|
+
// You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`.
|
|
300
|
+
//
|
|
301
|
+
/**
|
|
302
|
+
* Is called if a subscribed object changes
|
|
303
|
+
* @param {string} id
|
|
304
|
+
* @param {ioBroker.Object | null | undefined} obj
|
|
305
|
+
*/
|
|
306
|
+
async onObjectChange(id, obj) {
|
|
307
|
+
if (obj) {
|
|
308
|
+
try {
|
|
309
|
+
// The object was changed
|
|
310
|
+
//this.log.debug(`object ${id} changed: ${JSON.stringify(obj)}`);
|
|
311
|
+
|
|
312
|
+
if (id.startsWith('system.adapter.')) {
|
|
313
|
+
//read new instance data and add it to the lists
|
|
314
|
+
await this.getInstanceData(id);
|
|
315
|
+
} else {
|
|
316
|
+
//read devices data and renew the lists
|
|
317
|
+
await this.main();
|
|
318
|
+
}
|
|
319
|
+
} catch (error) {
|
|
320
|
+
this.log.error(`Issue at object change: ${error}`);
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
try {
|
|
324
|
+
// The object was deleted
|
|
325
|
+
this.log.info(`object ${id} deleted`);
|
|
326
|
+
|
|
327
|
+
// delete instance data in map
|
|
328
|
+
if (this.listInstanceRaw.has(id)) {
|
|
329
|
+
this.listInstanceRaw.delete(id);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// delete device data in map
|
|
333
|
+
if (this.listAllDevicesRaw.has(id)) {
|
|
334
|
+
this.listAllDevicesRaw.delete(id);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
//unsubscribe of Objects and states
|
|
338
|
+
this.unsubscribeForeignObjects(id);
|
|
339
|
+
this.unsubscribeForeignStates(id);
|
|
340
|
+
} catch (error) {
|
|
341
|
+
this.log.error(`Issue at object deletion: ${error}`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
269
346
|
/**
|
|
270
347
|
* Is called if a subscribed state changes
|
|
271
348
|
* @param {string} id
|
|
@@ -273,199 +350,221 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
273
350
|
*/
|
|
274
351
|
async onStateChange(id, state) {
|
|
275
352
|
// Admin JSON for Adapter updates
|
|
276
|
-
if (
|
|
277
|
-
this.log.debug(`State changed: ${id} changed ${state.val}`);
|
|
353
|
+
if (state) {
|
|
354
|
+
// this.log.debug(`State changed: ${id} changed ${state.val}`);
|
|
278
355
|
let batteryData;
|
|
356
|
+
let signalData;
|
|
279
357
|
let oldLowBatState;
|
|
280
358
|
let contactData;
|
|
281
359
|
let oldStatus;
|
|
282
360
|
let isLowBatValue;
|
|
283
361
|
let instanceStatusRaw;
|
|
284
|
-
let
|
|
285
|
-
|
|
362
|
+
let oldInstanceHostState;
|
|
363
|
+
let oldInstanceDeviceState;
|
|
286
364
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
this.sendAdapterUpdatesNotification(id, state);
|
|
365
|
+
try {
|
|
366
|
+
if (id.endsWith('updatesJson')) {
|
|
367
|
+
await this.getAdapterUpdateData(id);
|
|
368
|
+
await this.createAdapterUpdateList();
|
|
369
|
+
if (this.config.checkSendAdapterUpdateMsg) {
|
|
370
|
+
await this.sendStateNotifications('updateAdapter', null);
|
|
294
371
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
switch (id) {
|
|
300
|
-
case instance.instanceAlivePath:
|
|
301
|
-
if (state.val !== instance.isAlive) {
|
|
302
|
-
instanceStatusRaw = await this.setInstanceStatus(
|
|
303
|
-
instance.instanceMode,
|
|
304
|
-
instance.schedule,
|
|
305
|
-
instance.instanceAlivePath,
|
|
306
|
-
state.val,
|
|
307
|
-
instance.isConnectedHost,
|
|
308
|
-
instance.isConnectedDevice,
|
|
309
|
-
);
|
|
310
|
-
instance.isAlive = instanceStatusRaw[1];
|
|
311
|
-
instance.status = instanceStatusRaw[0];
|
|
312
|
-
instance.isHealthy = instanceStatusRaw[2];
|
|
313
|
-
}
|
|
314
|
-
break;
|
|
315
|
-
case instance.connectedHostPath:
|
|
316
|
-
if (instance.isAlive && state.val !== instance.isConnectedHost) {
|
|
317
|
-
instance.isConnectedHost = state.val;
|
|
318
|
-
instanceStatusRaw = await this.setInstanceStatus(
|
|
319
|
-
instance.instanceMode,
|
|
320
|
-
instance.schedule,
|
|
321
|
-
instance.instanceAlivePath,
|
|
322
|
-
instance.isAlive,
|
|
323
|
-
state.val,
|
|
324
|
-
instance.isConnectedDevice,
|
|
325
|
-
);
|
|
326
|
-
instance.isAlive = instanceStatusRaw[1];
|
|
327
|
-
instance.status = instanceStatusRaw[0];
|
|
328
|
-
instance.isHealthy = instanceStatusRaw[2];
|
|
329
|
-
|
|
330
|
-
if (this.config.checkSendInstanceFailedMsg && !instance.isHealthy && !this.blacklistNotify.includes(instance.instanceAlivePath)) {
|
|
331
|
-
await this.sendInstanceErrorNotification(instance.InstanceName, instance.status);
|
|
372
|
+
for (const instance of this.listInstanceRaw.values()) {
|
|
373
|
+
if (this.adapterUpdatesJsonRaw.has(instance.Adapter)) {
|
|
374
|
+
for (const adapter of this.adapterUpdatesJsonRaw.values()) {
|
|
375
|
+
instance.updateAvailable = adapter.newVersion;
|
|
332
376
|
}
|
|
377
|
+
} else {
|
|
378
|
+
instance.updateAvailable = ' - ';
|
|
333
379
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
if (instance.isAlive && state.val !== instance.isConnectedDevice) {
|
|
337
|
-
instance.isConnectedDevice = state.val;
|
|
338
|
-
instanceStatusRaw = await this.setInstanceStatus(
|
|
339
|
-
instance.instanceMode,
|
|
340
|
-
instance.schedule,
|
|
341
|
-
instance.instanceAlivePath,
|
|
342
|
-
instance.isAlive,
|
|
343
|
-
instance.isConnectedHost,
|
|
344
|
-
state.val,
|
|
345
|
-
);
|
|
346
|
-
instance.isAlive = instanceStatusRaw[1];
|
|
347
|
-
instance.status = instanceStatusRaw[0];
|
|
348
|
-
instance.isHealthy = instanceStatusRaw[2];
|
|
380
|
+
}
|
|
381
|
+
}
|
|
349
382
|
|
|
350
|
-
|
|
351
|
-
|
|
383
|
+
for (const [instance, instanceData] of this.listInstanceRaw) {
|
|
384
|
+
switch (id) {
|
|
385
|
+
case instanceData.instanceAlivePath:
|
|
386
|
+
if (state.val !== instanceData.isAlive) {
|
|
387
|
+
instanceStatusRaw = await this.setInstanceStatus(
|
|
388
|
+
instanceData.instanceMode,
|
|
389
|
+
instanceData.schedule,
|
|
390
|
+
instanceData.instanceAlivePath,
|
|
391
|
+
instanceData.connectedHostPath,
|
|
392
|
+
instanceData.connectedDevicePath,
|
|
393
|
+
);
|
|
394
|
+
instanceData.isAlive = instanceStatusRaw[1];
|
|
395
|
+
instanceData.status = instanceStatusRaw[0];
|
|
396
|
+
instanceData.isHealthy = instanceStatusRaw[2];
|
|
352
397
|
}
|
|
353
|
-
|
|
354
|
-
|
|
398
|
+
break;
|
|
399
|
+
case instanceData.connectedHostPath:
|
|
400
|
+
oldInstanceHostState = instanceData.isConnectedHost;
|
|
401
|
+
instanceData.isConnectedHost = state.val;
|
|
402
|
+
if (oldInstanceHostState !== instanceData.isConnectedHost) {
|
|
403
|
+
instanceStatusRaw = await this.setInstanceStatus(
|
|
404
|
+
instanceData.instanceMode,
|
|
405
|
+
instanceData.schedule,
|
|
406
|
+
instanceData.instanceAlivePath,
|
|
407
|
+
instanceData.connectedHostPath,
|
|
408
|
+
instanceData.connectedDevicePath,
|
|
409
|
+
);
|
|
410
|
+
instanceData.isAlive = instanceStatusRaw[1];
|
|
411
|
+
instanceData.status = instanceStatusRaw[0];
|
|
412
|
+
instanceData.isHealthy = instanceStatusRaw[2];
|
|
413
|
+
|
|
414
|
+
if (!instanceData.isAlive) continue;
|
|
415
|
+
if (this.config.checkSendInstanceFailedMsg && !this.blacklistInstancesNotify.includes(instanceData.instanceAlivePath)) {
|
|
416
|
+
if (!instanceData.isHealthy) {
|
|
417
|
+
await this.sendStateNotifications('errorInstance', instance);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
break;
|
|
422
|
+
case instanceData.connectedDevicePath:
|
|
423
|
+
oldInstanceDeviceState = instanceData.isConnectedDevice;
|
|
424
|
+
instanceData.isConnectedDevice = state.val;
|
|
425
|
+
if (oldInstanceDeviceState !== instanceData.isConnectedDevice) {
|
|
426
|
+
instanceStatusRaw = await this.setInstanceStatus(
|
|
427
|
+
instanceData.instanceMode,
|
|
428
|
+
instanceData.schedule,
|
|
429
|
+
instanceData.instanceAlivePath,
|
|
430
|
+
instanceData.connectedHostPath,
|
|
431
|
+
instanceData.connectedDevicePath,
|
|
432
|
+
);
|
|
433
|
+
instanceData.isAlive = instanceStatusRaw[1];
|
|
434
|
+
instanceData.status = instanceStatusRaw[0];
|
|
435
|
+
instanceData.isHealthy = instanceStatusRaw[2];
|
|
436
|
+
|
|
437
|
+
if (!instanceData.isAlive) continue;
|
|
438
|
+
if (this.config.checkSendInstanceFailedMsg && !this.blacklistInstancesNotify.includes(instanceData.instanceAlivePath)) {
|
|
439
|
+
if (!instanceData.isHealthy) {
|
|
440
|
+
await this.sendStateNotifications('errorInstance', instance);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
355
446
|
}
|
|
356
|
-
}
|
|
357
447
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
448
|
+
for (const [device, deviceData] of this.listAllDevicesRaw) {
|
|
449
|
+
// On statechange update available datapoint
|
|
450
|
+
switch (id) {
|
|
451
|
+
case deviceData.instanceDeviceConnectionDP:
|
|
452
|
+
if (state.val !== deviceData.instancedeviceConnected) {
|
|
453
|
+
deviceData.instancedeviceConnected = state.val;
|
|
454
|
+
}
|
|
455
|
+
break;
|
|
366
456
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
457
|
+
case deviceData.UpdateDP:
|
|
458
|
+
if (state.val !== deviceData.Upgradable) {
|
|
459
|
+
deviceData.Upgradable = state.val;
|
|
460
|
+
if (state.val) {
|
|
461
|
+
if (this.config.checkSendDeviceUpgrade && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
462
|
+
await this.sendStateNotifications('updateDevice', device);
|
|
463
|
+
}
|
|
373
464
|
}
|
|
374
465
|
}
|
|
375
|
-
|
|
376
|
-
break;
|
|
466
|
+
break;
|
|
377
467
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
468
|
+
case deviceData.SignalStrengthDP:
|
|
469
|
+
signalData = await this.calculateSignalStrength(state, deviceData.adapterID);
|
|
470
|
+
deviceData.SignalStrength = signalData[0];
|
|
381
471
|
|
|
382
|
-
|
|
383
|
-
if (device.isBatteryDevice) {
|
|
384
|
-
oldLowBatState = device.LowBat;
|
|
385
|
-
batteryData = await this.getBatteryData(state.val, oldLowBatState, device.adapterID);
|
|
472
|
+
break;
|
|
386
473
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
474
|
+
case deviceData.batteryDP:
|
|
475
|
+
if (deviceData.isBatteryDevice) {
|
|
476
|
+
oldLowBatState = deviceData.LowBat;
|
|
477
|
+
batteryData = await this.getBatteryData(state.val, oldLowBatState, deviceData.faultReport, deviceData.adapterID);
|
|
478
|
+
|
|
479
|
+
deviceData.Battery = batteryData[0];
|
|
480
|
+
deviceData.BatteryRaw = batteryData[2];
|
|
481
|
+
deviceData.BatteryUnitRaw = batteryData[3];
|
|
482
|
+
if (deviceData.LowBatDP !== 'none') {
|
|
483
|
+
isLowBatValue = await this.getInitValue(deviceData.LowBatDP);
|
|
484
|
+
} else {
|
|
485
|
+
isLowBatValue = undefined;
|
|
486
|
+
}
|
|
487
|
+
deviceData.LowBat = await this.setLowbatIndicator(state.val, isLowBatValue, deviceData.faultReport, deviceData.adapterID);
|
|
395
488
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
489
|
+
if (deviceData.LowBat && oldLowBatState !== deviceData.LowBat) {
|
|
490
|
+
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
491
|
+
await this.sendStateNotifications('lowBatDevice', device);
|
|
492
|
+
}
|
|
399
493
|
}
|
|
400
494
|
}
|
|
401
|
-
|
|
402
|
-
break;
|
|
495
|
+
break;
|
|
403
496
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
if (
|
|
414
|
-
|
|
497
|
+
case deviceData.LowBatDP:
|
|
498
|
+
if (deviceData.isBatteryDevice) {
|
|
499
|
+
oldLowBatState = deviceData.LowBat;
|
|
500
|
+
batteryData = await this.getBatteryData(deviceData.BatteryRaw, state.val, deviceData.faultReport, deviceData.adapterID);
|
|
501
|
+
deviceData.Battery = batteryData[0];
|
|
502
|
+
deviceData.BatteryRaw = batteryData[2];
|
|
503
|
+
deviceData.BatteryUnitRaw = batteryData[3];
|
|
504
|
+
deviceData.LowBat = await this.setLowbatIndicator(deviceData.BatteryRaw, state.val, deviceData.faultReport, deviceData.adapterID);
|
|
505
|
+
|
|
506
|
+
if (deviceData.LowBat && oldLowBatState !== deviceData.LowBat) {
|
|
507
|
+
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
508
|
+
await this.sendStateNotifications('lowBatDevice', device);
|
|
509
|
+
}
|
|
415
510
|
}
|
|
416
511
|
}
|
|
417
|
-
|
|
418
|
-
break;
|
|
512
|
+
break;
|
|
419
513
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
514
|
+
case deviceData.faultReportDP:
|
|
515
|
+
if (deviceData.isBatteryDevice) {
|
|
516
|
+
oldLowBatState = deviceData.LowBat;
|
|
517
|
+
batteryData = await this.getBatteryData(deviceData.BatteryRaw, oldLowBatState, state.val, deviceData.adapterID);
|
|
424
518
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
519
|
+
deviceData.Battery = batteryData[0];
|
|
520
|
+
deviceData.BatteryRaw = batteryData[2];
|
|
521
|
+
deviceData.BatteryUnitRaw = batteryData[3];
|
|
522
|
+
deviceData.LowBat = await this.setLowbatIndicator(deviceData.BatteryRaw, undefined, state.val, deviceData.adapterID);
|
|
428
523
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
524
|
+
if (deviceData.LowBat && oldLowBatState !== deviceData.LowBat) {
|
|
525
|
+
if (this.config.checkSendBatteryMsg && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
526
|
+
await this.sendStateNotifications('lowBatDevice', device);
|
|
527
|
+
}
|
|
432
528
|
}
|
|
433
529
|
}
|
|
434
|
-
|
|
435
|
-
break;
|
|
530
|
+
break;
|
|
436
531
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
}
|
|
454
|
-
if (device.instanceDeviceConnectionDP !== undefined) {
|
|
455
|
-
instanceDeviceConnectionDpTS = await this.getTimestampConnectionDP(device.instanceDeviceConnectionDP);
|
|
456
|
-
if (device.instancedeviceConnected !== false && instanceDeviceConnectionDpTS && instanceDeviceConnectionDpTS >= instanceDeviceConnectionDpTSminTime) {
|
|
457
|
-
if (this.config.checkSendOfflineMsg && oldStatus !== device.Status && !this.blacklistNotify.includes(device.Path)) {
|
|
458
|
-
await this.sendOfflineNotifications(device.Device, device.Adapter, device.Status, device.LastContact);
|
|
459
|
-
}
|
|
532
|
+
case deviceData.UnreachDP:
|
|
533
|
+
oldStatus = deviceData.Status;
|
|
534
|
+
deviceData.UnreachState = await this.getInitValue(deviceData.UnreachDP);
|
|
535
|
+
contactData = await this.getOnlineState(
|
|
536
|
+
deviceData.timeSelector,
|
|
537
|
+
deviceData.adapterID,
|
|
538
|
+
deviceData.UnreachDP,
|
|
539
|
+
deviceData.SignalStrength,
|
|
540
|
+
deviceData.UnreachState,
|
|
541
|
+
deviceData.DeviceStateSelectorDP,
|
|
542
|
+
deviceData.rssiPeerSelectorDP,
|
|
543
|
+
);
|
|
544
|
+
if (contactData !== undefined) {
|
|
545
|
+
deviceData.LastContact = contactData[0];
|
|
546
|
+
deviceData.Status = contactData[1];
|
|
547
|
+
deviceData.SignalStrength = contactData[2];
|
|
460
548
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
549
|
+
if (this.config.checkSendOfflineMsg && oldStatus !== deviceData.Status && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
550
|
+
if (deviceData.instanceDeviceConnectionDP !== undefined) {
|
|
551
|
+
// check if the generally deviceData connected state is for a while true
|
|
552
|
+
if (await this.getTimestampConnectionDP(deviceData.instanceDeviceConnectionDP, 20000)) {
|
|
553
|
+
await this.sendStateNotifications('onlineStateDevice', device);
|
|
554
|
+
}
|
|
555
|
+
} else {
|
|
556
|
+
await this.sendStateNotifications('onlineStateDevice', device);
|
|
557
|
+
}
|
|
464
558
|
}
|
|
465
|
-
|
|
466
|
-
|
|
559
|
+
break;
|
|
560
|
+
}
|
|
467
561
|
}
|
|
562
|
+
} catch (error) {
|
|
563
|
+
this.log.error(`Issue at state change: ${error}`);
|
|
468
564
|
}
|
|
565
|
+
} else {
|
|
566
|
+
// The state was deleted
|
|
567
|
+
this.log.debug(`state ${id} deleted`);
|
|
469
568
|
}
|
|
470
569
|
}
|
|
471
570
|
|
|
@@ -474,26 +573,23 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
474
573
|
*/
|
|
475
574
|
onMessage(obj) {
|
|
476
575
|
const devices = [];
|
|
477
|
-
let myCount = 0;
|
|
478
|
-
let result;
|
|
479
576
|
const instances = [];
|
|
480
|
-
let
|
|
481
|
-
let
|
|
577
|
+
let countDevices = 0;
|
|
578
|
+
let countInstances = 0;
|
|
482
579
|
|
|
483
580
|
switch (obj.command) {
|
|
484
581
|
case 'devicesList':
|
|
485
582
|
if (obj.message) {
|
|
486
583
|
try {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
const
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
path: result[element].Path,
|
|
584
|
+
for (const deviceData of this.listAllDevicesRaw.values()) {
|
|
585
|
+
const label = `${deviceData.Adapter}: ${deviceData.Device}`;
|
|
586
|
+
const valueObjectDevices = {
|
|
587
|
+
deviceName: deviceData.Device,
|
|
588
|
+
adapter: deviceData.Adapter,
|
|
589
|
+
path: deviceData.Path,
|
|
494
590
|
};
|
|
495
|
-
devices[
|
|
496
|
-
|
|
591
|
+
devices[countDevices] = { label: label, value: JSON.stringify(valueObjectDevices) };
|
|
592
|
+
countDevices++;
|
|
497
593
|
}
|
|
498
594
|
const sortDevices = devices.slice(0);
|
|
499
595
|
sortDevices.sort(function (a, b) {
|
|
@@ -503,7 +599,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
503
599
|
});
|
|
504
600
|
this.sendTo(obj.from, obj.command, sortDevices, obj.callback);
|
|
505
601
|
} catch (error) {
|
|
506
|
-
this.
|
|
602
|
+
this.errorReporting('[onMessage - deviceList for blacklisttable]', error);
|
|
507
603
|
}
|
|
508
604
|
} else {
|
|
509
605
|
this.sendTo(obj.from, obj.command, obj.callback);
|
|
@@ -513,16 +609,15 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
513
609
|
case 'instancesList':
|
|
514
610
|
if (obj.message) {
|
|
515
611
|
try {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
const
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
path: resultInstances[element].instanceAlivePath,
|
|
612
|
+
for (const instanceData of this.listInstanceRaw.values()) {
|
|
613
|
+
const label = `${instanceData.Adapter}: ${instanceData.InstanceName}`;
|
|
614
|
+
const valueObjectInstances = {
|
|
615
|
+
adapter: instanceData.Adapter,
|
|
616
|
+
instanceName: instanceData.InstanceName,
|
|
617
|
+
path: instanceData.instanceAlivePath,
|
|
523
618
|
};
|
|
524
|
-
instances[
|
|
525
|
-
|
|
619
|
+
instances[countInstances] = { label: label, value: JSON.stringify(valueObjectInstances) };
|
|
620
|
+
countInstances++;
|
|
526
621
|
}
|
|
527
622
|
const sortInstances = instances.slice(0);
|
|
528
623
|
sortInstances.sort(function (a, b) {
|
|
@@ -532,7 +627,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
532
627
|
});
|
|
533
628
|
this.sendTo(obj.from, obj.command, sortInstances, obj.callback);
|
|
534
629
|
} catch (error) {
|
|
535
|
-
this.
|
|
630
|
+
this.errorReporting('[onMessage - instanceList for blacklisttable]', error);
|
|
536
631
|
}
|
|
537
632
|
} else {
|
|
538
633
|
this.sendTo(obj.from, obj.command, obj.callback);
|
|
@@ -549,18 +644,27 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
549
644
|
|
|
550
645
|
// fill counts and lists of all selected adapter
|
|
551
646
|
try {
|
|
552
|
-
|
|
647
|
+
for (let i = 0; i < this.selAdapter.length; i++) {
|
|
648
|
+
await this.createData(i);
|
|
649
|
+
await this.createLists();
|
|
650
|
+
}
|
|
651
|
+
await this.writeDatapoints(); // fill the datapoints
|
|
553
652
|
this.log.debug(`Created and filled data for all adapters`);
|
|
554
653
|
} catch (error) {
|
|
555
654
|
this.errorReporting('[main - create data of all adapter]', error);
|
|
556
655
|
}
|
|
557
656
|
|
|
558
657
|
// fill datapoints for each adapter if selected
|
|
559
|
-
if (this.
|
|
658
|
+
if (this.configCreateOwnFolder) {
|
|
560
659
|
try {
|
|
561
660
|
for (const [id] of Object.entries(arrApart)) {
|
|
562
|
-
if (this.configSetAdapter
|
|
563
|
-
|
|
661
|
+
if (this.configSetAdapter && this.configSetAdapter[id]) {
|
|
662
|
+
for (const deviceData of this.listAllDevicesRaw.values()) {
|
|
663
|
+
// list device only if selected adapter matched with device
|
|
664
|
+
if (!deviceData.adapterID.includes(id)) continue;
|
|
665
|
+
await this.createLists(id);
|
|
666
|
+
}
|
|
667
|
+
await this.writeDatapoints(id); // fill the datapoints
|
|
564
668
|
this.log.debug(`Created and filled data for ${this.capitalize(id)}`);
|
|
565
669
|
}
|
|
566
670
|
}
|
|
@@ -577,15 +681,18 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
577
681
|
* is neccessary to refresh lastContact data, especially of devices without state changes
|
|
578
682
|
*/
|
|
579
683
|
async refreshData() {
|
|
684
|
+
if (isUnloaded) return; // cancel run if unloaded was called.
|
|
580
685
|
const nextTimeout = this.config.updateinterval * 1000;
|
|
581
686
|
|
|
687
|
+
// devices data
|
|
582
688
|
await this.checkLastContact();
|
|
583
689
|
await this.createLists();
|
|
584
690
|
await this.writeDatapoints();
|
|
585
691
|
|
|
586
|
-
|
|
692
|
+
// devices data in own adapter folder
|
|
693
|
+
if (this.configCreateOwnFolder) {
|
|
587
694
|
for (const [id] of Object.entries(arrApart)) {
|
|
588
|
-
if (this.configSetAdapter
|
|
695
|
+
if (this.configSetAdapter && this.configSetAdapter[id]) {
|
|
589
696
|
await this.createLists(id);
|
|
590
697
|
await this.writeDatapoints(id);
|
|
591
698
|
this.log.debug(`Created and filled data for ${this.capitalize(id)}`);
|
|
@@ -593,26 +700,22 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
593
700
|
}
|
|
594
701
|
}
|
|
595
702
|
|
|
596
|
-
|
|
703
|
+
// instance and adapter data
|
|
704
|
+
if (this.configCreateInstanceList) {
|
|
597
705
|
await this.createInstanceList();
|
|
598
706
|
await this.writeInstanceDPs();
|
|
599
707
|
}
|
|
600
708
|
|
|
601
709
|
// Clear existing timeout
|
|
602
710
|
if (this.refreshDataTimeout) {
|
|
603
|
-
this.
|
|
604
|
-
this.
|
|
711
|
+
clearTimeout(this.refreshDataTimeout);
|
|
712
|
+
this.refreshDataTimeout = null;
|
|
605
713
|
}
|
|
606
|
-
if (!isUnloaded) {
|
|
607
|
-
this.refreshDataTimeout = this.setTimeout(() => {
|
|
608
|
-
this.log.debug('Updating Data');
|
|
609
714
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
}
|
|
614
|
-
return; // cancel run if unloaded was called.
|
|
615
|
-
}
|
|
715
|
+
this.refreshDataTimeout = setTimeout(() => {
|
|
716
|
+
this.log.debug('Updating Data');
|
|
717
|
+
this.refreshData();
|
|
718
|
+
}, nextTimeout);
|
|
616
719
|
} // <-- refreshData end
|
|
617
720
|
|
|
618
721
|
/**
|
|
@@ -626,7 +729,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
626
729
|
|
|
627
730
|
for (const i in myBlacklist) {
|
|
628
731
|
try {
|
|
629
|
-
const blacklistParse =
|
|
732
|
+
const blacklistParse = this.parseData(myBlacklist[i].devices);
|
|
630
733
|
// push devices in list to ignor device in lists
|
|
631
734
|
if (myBlacklist[i].checkIgnorLists) {
|
|
632
735
|
this.blacklistLists.push(blacklistParse.path);
|
|
@@ -645,14 +748,14 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
645
748
|
|
|
646
749
|
if (this.blacklistLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistLists}`);
|
|
647
750
|
if (this.blacklistAdapterLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistAdapterLists}`);
|
|
648
|
-
if (this.blacklistNotify.length >= 1) this.log.info(`Found items on blacklist for
|
|
751
|
+
if (this.blacklistNotify.length >= 1) this.log.info(`Found items on blacklist for notifications: ${this.blacklistNotify}`);
|
|
649
752
|
|
|
650
753
|
// INSTANCES
|
|
651
754
|
const myBlacklistInstances = this.config.tableBlacklistInstances;
|
|
652
755
|
|
|
653
756
|
for (const i in myBlacklistInstances) {
|
|
654
757
|
try {
|
|
655
|
-
const blacklistParse =
|
|
758
|
+
const blacklistParse = this.parseData(myBlacklistInstances[i].instances);
|
|
656
759
|
// push devices in list to ignor device in lists
|
|
657
760
|
if (myBlacklistInstances[i].checkIgnorLists) {
|
|
658
761
|
this.blacklistInstancesLists.push(blacklistParse.path);
|
|
@@ -667,7 +770,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
667
770
|
}
|
|
668
771
|
|
|
669
772
|
if (this.blacklistInstancesLists.length >= 1) this.log.info(`Found items on blacklist for lists: ${this.blacklistInstancesLists}`);
|
|
670
|
-
if (this.blacklistInstancesNotify.length >= 1) this.log.info(`Found items on blacklist for
|
|
773
|
+
if (this.blacklistInstancesNotify.length >= 1) this.log.info(`Found items on blacklist for notifications: ${this.blacklistInstancesNotify}`);
|
|
671
774
|
|
|
672
775
|
this.log.debug(`Function finished: ${this.createBlacklist.name}`);
|
|
673
776
|
}
|
|
@@ -676,189 +779,209 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
676
779
|
* @param {object} i - Device Object
|
|
677
780
|
*/
|
|
678
781
|
async createData(i) {
|
|
679
|
-
|
|
680
|
-
|
|
782
|
+
try {
|
|
783
|
+
const devices = await this.getForeignStatesAsync(this.selAdapter[i].Selektor);
|
|
784
|
+
const adapterID = this.selAdapter[i].adapterID;
|
|
681
785
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
786
|
+
/*---------- Start of loop ----------*/
|
|
787
|
+
for (const [id] of Object.entries(devices)) {
|
|
788
|
+
/*=============================================
|
|
685
789
|
= get Instanz =
|
|
686
790
|
=============================================*/
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
791
|
+
const instance = id.slice(0, id.indexOf('.') + 2);
|
|
792
|
+
const instanceDeviceConnectionDP = `${instance}.info.connection`;
|
|
793
|
+
const instancedeviceConnected = await this.getInitValue(instanceDeviceConnectionDP);
|
|
794
|
+
this.subscribeForeignStates(instanceDeviceConnectionDP);
|
|
795
|
+
this.subscribeForeignObjects(`${this.selAdapter[i].Selektor}`);
|
|
691
796
|
|
|
692
|
-
|
|
797
|
+
/*=============================================
|
|
693
798
|
= Get device name =
|
|
694
799
|
=============================================*/
|
|
695
|
-
|
|
800
|
+
const deviceName = await this.getDeviceName(id, i);
|
|
696
801
|
|
|
697
|
-
|
|
802
|
+
/*=============================================
|
|
698
803
|
= Get adapter name =
|
|
699
804
|
=============================================*/
|
|
700
|
-
|
|
805
|
+
const adapter = this.selAdapter[i].adapter;
|
|
701
806
|
|
|
702
|
-
|
|
807
|
+
/*=============================================
|
|
703
808
|
= Get path to datapoints =
|
|
704
809
|
=============================================*/
|
|
705
|
-
|
|
706
|
-
|
|
810
|
+
const currDeviceString = id.slice(0, id.lastIndexOf('.') + 1 - 1);
|
|
811
|
+
const shortCurrDeviceString = currDeviceString.slice(0, currDeviceString.lastIndexOf('.') + 1 - 1);
|
|
707
812
|
|
|
708
|
-
|
|
813
|
+
// subscribe to object device path
|
|
814
|
+
this.subscribeForeignObjects(currDeviceString);
|
|
815
|
+
|
|
816
|
+
/*=============================================
|
|
709
817
|
= Get signal strength =
|
|
710
818
|
=============================================*/
|
|
711
|
-
|
|
712
|
-
|
|
819
|
+
let deviceQualityDP = currDeviceString + this.selAdapter[i].rssiState;
|
|
820
|
+
let deviceQualityState;
|
|
713
821
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
822
|
+
switch (adapterID) {
|
|
823
|
+
case 'mihomeVacuum':
|
|
824
|
+
deviceQualityDP = shortCurrDeviceString + this.selAdapter[i].rssiState;
|
|
825
|
+
deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
|
|
826
|
+
break;
|
|
719
827
|
|
|
720
|
-
|
|
721
|
-
deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
|
|
722
|
-
if (!deviceQualityState) {
|
|
723
|
-
deviceQualityDP = currDeviceString + this.selAdapter[i].rfState;
|
|
828
|
+
case 'netatmo':
|
|
724
829
|
deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
|
|
725
|
-
|
|
726
|
-
|
|
830
|
+
if (!deviceQualityState) {
|
|
831
|
+
deviceQualityDP = currDeviceString + this.selAdapter[i].rfState;
|
|
832
|
+
deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
|
|
833
|
+
}
|
|
834
|
+
break;
|
|
727
835
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
836
|
+
default:
|
|
837
|
+
deviceQualityState = await this.getForeignStateAsync(deviceQualityDP);
|
|
838
|
+
break;
|
|
839
|
+
}
|
|
840
|
+
//subscribe to states
|
|
841
|
+
this.subscribeForeignStates(deviceQualityDP);
|
|
734
842
|
|
|
735
|
-
|
|
843
|
+
const signalData = await this.calculateSignalStrength(deviceQualityState, adapterID);
|
|
844
|
+
let linkQuality = signalData[0];
|
|
845
|
+
const linkQualityRaw = signalData[1];
|
|
736
846
|
|
|
737
|
-
|
|
847
|
+
/*=============================================
|
|
738
848
|
= Get battery data =
|
|
739
849
|
=============================================*/
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
deviceBatteryStateDP = shortCurrDeviceString + this.selAdapter[i].battery;
|
|
760
|
-
deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
|
|
761
|
-
if (deviceBatteryState === undefined) {
|
|
762
|
-
deviceBatteryStateDP = shortCurrDeviceString + this.selAdapter[i].battery2;
|
|
850
|
+
let deviceBatteryStateDP;
|
|
851
|
+
let deviceBatteryState;
|
|
852
|
+
let batteryHealth;
|
|
853
|
+
let batteryHealthRaw;
|
|
854
|
+
let batteryUnitRaw;
|
|
855
|
+
let lowBatIndicator;
|
|
856
|
+
let isBatteryDevice;
|
|
857
|
+
let isLowBatDP;
|
|
858
|
+
let faultReportingDP;
|
|
859
|
+
let faultReportingState;
|
|
860
|
+
|
|
861
|
+
const deviceChargerStateDP = currDeviceString + this.selAdapter[i].charger;
|
|
862
|
+
const deviceChargerState = await this.getInitValue(deviceChargerStateDP);
|
|
863
|
+
|
|
864
|
+
if (deviceChargerState === undefined || deviceChargerState === false) {
|
|
865
|
+
// Get battery states
|
|
866
|
+
switch (adapterID) {
|
|
867
|
+
case 'hmrpc':
|
|
868
|
+
deviceBatteryStateDP = currDeviceString + this.selAdapter[i].battery;
|
|
763
869
|
deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
870
|
+
if (deviceBatteryState === undefined) {
|
|
871
|
+
deviceBatteryStateDP = shortCurrDeviceString + this.selAdapter[i].hmDNBattery;
|
|
872
|
+
deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
|
|
873
|
+
}
|
|
874
|
+
break;
|
|
875
|
+
case 'hueExt':
|
|
876
|
+
case 'mihomeVacuum':
|
|
877
|
+
case 'mqttNuki':
|
|
878
|
+
deviceBatteryStateDP = shortCurrDeviceString + this.selAdapter[i].battery;
|
|
771
879
|
deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
880
|
+
if (deviceBatteryState === undefined) {
|
|
881
|
+
deviceBatteryStateDP = shortCurrDeviceString + this.selAdapter[i].battery2;
|
|
882
|
+
deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
|
|
883
|
+
}
|
|
884
|
+
break;
|
|
885
|
+
default:
|
|
886
|
+
deviceBatteryStateDP = currDeviceString + this.selAdapter[i].battery;
|
|
887
|
+
deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
|
|
888
|
+
if (deviceBatteryState === undefined) {
|
|
889
|
+
deviceBatteryStateDP = currDeviceString + this.selAdapter[i].battery2;
|
|
890
|
+
deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
|
|
891
|
+
}
|
|
892
|
+
break;
|
|
893
|
+
}
|
|
775
894
|
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
895
|
+
// Get low bat states
|
|
896
|
+
isLowBatDP = currDeviceString + this.selAdapter[i].isLowBat;
|
|
897
|
+
let deviceLowBatState = await this.getInitValue(isLowBatDP);
|
|
898
|
+
if (deviceLowBatState === undefined) {
|
|
899
|
+
isLowBatDP = currDeviceString + this.selAdapter[i].isLowBat2;
|
|
900
|
+
deviceLowBatState = await this.getInitValue(isLowBatDP);
|
|
901
|
+
}
|
|
902
|
+
if (deviceLowBatState === undefined) isLowBatDP = 'none';
|
|
784
903
|
|
|
785
|
-
|
|
786
|
-
|
|
904
|
+
faultReportingDP = shortCurrDeviceString + this.selAdapter[i].faultReporting;
|
|
905
|
+
faultReportingState = await this.getInitValue(faultReportingDP);
|
|
787
906
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
907
|
+
//subscribe to states
|
|
908
|
+
this.subscribeForeignStates(deviceBatteryStateDP);
|
|
909
|
+
this.subscribeForeignStates(isLowBatDP);
|
|
910
|
+
this.subscribeForeignStates(faultReportingDP);
|
|
792
911
|
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
912
|
+
const batteryData = await this.getBatteryData(deviceBatteryState, deviceLowBatState, faultReportingState, adapterID);
|
|
913
|
+
batteryHealth = batteryData[0];
|
|
914
|
+
batteryHealthRaw = batteryData[2];
|
|
915
|
+
batteryUnitRaw = batteryData[3];
|
|
916
|
+
isBatteryDevice = batteryData[1];
|
|
797
917
|
|
|
798
|
-
|
|
799
|
-
|
|
918
|
+
if (isBatteryDevice) {
|
|
919
|
+
lowBatIndicator = await this.setLowbatIndicator(deviceBatteryState, deviceLowBatState, faultReportingState, adapterID);
|
|
920
|
+
}
|
|
800
921
|
}
|
|
801
|
-
}
|
|
802
922
|
|
|
803
|
-
|
|
923
|
+
/*=============================================
|
|
804
924
|
= Get last contact of device =
|
|
805
925
|
=============================================*/
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
// subscribe to states
|
|
818
|
-
this.subscribeForeignStates(timeSelector);
|
|
819
|
-
this.subscribeForeignStates(unreachDP);
|
|
820
|
-
this.subscribeForeignStates(deviceStateSelectorDP);
|
|
821
|
-
this.subscribeForeignStates(rssiPeerSelectorDP);
|
|
926
|
+
let unreachDP = currDeviceString + this.selAdapter[i].reach;
|
|
927
|
+
const deviceStateSelectorDP = shortCurrDeviceString + this.selAdapter[i].stateValue;
|
|
928
|
+
const rssiPeerSelectorDP = currDeviceString + this.selAdapter[i].rssiPeerState;
|
|
929
|
+
const timeSelector = currDeviceString + this.selAdapter[i].timeSelector;
|
|
930
|
+
|
|
931
|
+
let deviceUnreachState = await this.getInitValue(unreachDP);
|
|
932
|
+
if (deviceUnreachState === undefined) {
|
|
933
|
+
unreachDP = shortCurrDeviceString + this.selAdapter[i].reach;
|
|
934
|
+
deviceUnreachState = await this.getInitValue(shortCurrDeviceString + this.selAdapter[i].reach);
|
|
935
|
+
}
|
|
822
936
|
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
937
|
+
// subscribe to states
|
|
938
|
+
this.subscribeForeignStates(timeSelector);
|
|
939
|
+
this.subscribeForeignStates(unreachDP);
|
|
940
|
+
this.subscribeForeignStates(deviceStateSelectorDP);
|
|
941
|
+
this.subscribeForeignStates(rssiPeerSelectorDP);
|
|
942
|
+
|
|
943
|
+
const onlineState = await this.getOnlineState(timeSelector, adapterID, unreachDP, linkQuality, deviceUnreachState, deviceStateSelectorDP, rssiPeerSelectorDP);
|
|
944
|
+
let deviceState;
|
|
945
|
+
let lastContactString;
|
|
946
|
+
|
|
947
|
+
if (onlineState) {
|
|
948
|
+
lastContactString = onlineState[0];
|
|
949
|
+
deviceState = onlineState[1];
|
|
950
|
+
linkQuality = onlineState[2];
|
|
951
|
+
}
|
|
826
952
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
953
|
+
/*=============================================
|
|
954
|
+
= Get update data =
|
|
955
|
+
=============================================*/
|
|
956
|
+
const deviceUpdateDP = currDeviceString + this.selAdapter[i].upgrade;
|
|
957
|
+
let isUpgradable;
|
|
832
958
|
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
=============================================*/
|
|
836
|
-
const deviceUpdateDP = currDeviceString + this.selAdapter[i].upgrade;
|
|
837
|
-
let isUpgradable;
|
|
959
|
+
if (this.config.checkSendDeviceUpgrade) {
|
|
960
|
+
const deviceUpdateSelector = await this.getInitValue(deviceUpdateDP);
|
|
838
961
|
|
|
839
|
-
|
|
840
|
-
|
|
962
|
+
if (deviceUpdateSelector !== undefined) {
|
|
963
|
+
if (deviceUpdateSelector) {
|
|
964
|
+
isUpgradable = true;
|
|
965
|
+
} else if (!deviceUpdateSelector) {
|
|
966
|
+
isUpgradable = false;
|
|
967
|
+
}
|
|
968
|
+
} else {
|
|
969
|
+
isUpgradable = ' - ';
|
|
970
|
+
}
|
|
841
971
|
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
} else if (!deviceUpdateSelector) {
|
|
845
|
-
isUpgradable = false;
|
|
972
|
+
// subscribe to states
|
|
973
|
+
this.subscribeForeignStates(deviceUpdateDP);
|
|
846
974
|
}
|
|
847
|
-
// subscribe to states
|
|
848
|
-
this.subscribeForeignStates(deviceUpdateDP);
|
|
849
|
-
}
|
|
850
975
|
|
|
851
|
-
|
|
976
|
+
/*=============================================
|
|
852
977
|
= Fill Raw Lists =
|
|
853
978
|
=============================================*/
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
if (this.listOnlyBattery) {
|
|
857
|
-
if (isBatteryDevice) {
|
|
858
|
-
this.listAllDevicesRaw.push({
|
|
979
|
+
const setupList = () => {
|
|
980
|
+
this.listAllDevicesRaw.set(currDeviceString, {
|
|
859
981
|
Path: id,
|
|
860
982
|
instanceDeviceConnectionDP: instanceDeviceConnectionDP,
|
|
861
983
|
instancedeviceConnected: instancedeviceConnected,
|
|
984
|
+
instance: instance,
|
|
862
985
|
Device: deviceName,
|
|
863
986
|
adapterID: adapterID,
|
|
864
987
|
Adapter: adapter,
|
|
@@ -866,6 +989,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
866
989
|
isBatteryDevice: isBatteryDevice,
|
|
867
990
|
Battery: batteryHealth,
|
|
868
991
|
BatteryRaw: batteryHealthRaw,
|
|
992
|
+
BatteryUnitRaw: batteryUnitRaw,
|
|
869
993
|
batteryDP: deviceBatteryStateDP,
|
|
870
994
|
LowBat: lowBatIndicator,
|
|
871
995
|
LowBatDP: isLowBatDP,
|
|
@@ -873,6 +997,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
873
997
|
faultReportDP: faultReportingDP,
|
|
874
998
|
SignalStrengthDP: deviceQualityDP,
|
|
875
999
|
SignalStrength: linkQuality,
|
|
1000
|
+
SignalStrengthRaw: linkQualityRaw,
|
|
876
1001
|
UnreachState: deviceUnreachState,
|
|
877
1002
|
UnreachDP: unreachDP,
|
|
878
1003
|
DeviceStateSelectorDP: deviceStateSelectorDP,
|
|
@@ -882,38 +1007,20 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
882
1007
|
UpdateDP: deviceUpdateDP,
|
|
883
1008
|
Upgradable: isUpgradable,
|
|
884
1009
|
});
|
|
1010
|
+
};
|
|
1011
|
+
|
|
1012
|
+
if (!this.configListOnlyBattery) {
|
|
1013
|
+
// Add all devices
|
|
1014
|
+
setupList();
|
|
1015
|
+
} else {
|
|
1016
|
+
// Add only devices with battery in the rawlist
|
|
1017
|
+
if (!isBatteryDevice) continue;
|
|
1018
|
+
setupList();
|
|
885
1019
|
}
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
instanceDeviceConnectionDP: instanceDeviceConnectionDP,
|
|
891
|
-
instancedeviceConnected: instancedeviceConnected,
|
|
892
|
-
Device: deviceName,
|
|
893
|
-
adapterID: adapterID,
|
|
894
|
-
Adapter: adapter,
|
|
895
|
-
timeSelector: timeSelector,
|
|
896
|
-
isBatteryDevice: isBatteryDevice,
|
|
897
|
-
Battery: batteryHealth,
|
|
898
|
-
BatteryRaw: batteryHealthRaw,
|
|
899
|
-
batteryDP: deviceBatteryStateDP,
|
|
900
|
-
LowBat: lowBatIndicator,
|
|
901
|
-
LowBatDP: isLowBatDP,
|
|
902
|
-
faultReport: faultReportingState,
|
|
903
|
-
faultReportDP: faultReportingDP,
|
|
904
|
-
SignalStrengthDP: deviceQualityDP,
|
|
905
|
-
SignalStrength: linkQuality,
|
|
906
|
-
UnreachState: deviceUnreachState,
|
|
907
|
-
UnreachDP: unreachDP,
|
|
908
|
-
DeviceStateSelectorDP: deviceStateSelectorDP,
|
|
909
|
-
rssiPeerSelectorDP: rssiPeerSelectorDP,
|
|
910
|
-
LastContact: lastContactString,
|
|
911
|
-
Status: deviceState,
|
|
912
|
-
UpdateDP: deviceUpdateDP,
|
|
913
|
-
Upgradable: isUpgradable,
|
|
914
|
-
});
|
|
915
|
-
}
|
|
916
|
-
} // <-- end of loop
|
|
1020
|
+
} // <-- end of loop
|
|
1021
|
+
} catch (error) {
|
|
1022
|
+
this.errorReporting('[createData - create data of devices]', error);
|
|
1023
|
+
}
|
|
917
1024
|
} // <-- end of createData
|
|
918
1025
|
|
|
919
1026
|
/*=============================================
|
|
@@ -1015,6 +1122,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1015
1122
|
*/
|
|
1016
1123
|
async calculateSignalStrength(deviceQualityState, adapterID) {
|
|
1017
1124
|
let linkQuality;
|
|
1125
|
+
let linkQualityRaw;
|
|
1018
1126
|
let mqttNukiValue;
|
|
1019
1127
|
|
|
1020
1128
|
if (deviceQualityState != null) {
|
|
@@ -1028,6 +1136,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1028
1136
|
case 'sonoff':
|
|
1029
1137
|
case 'smartgarden':
|
|
1030
1138
|
linkQuality = deviceQualityState.val + '%'; // If quality state is already an percent value
|
|
1139
|
+
linkQualityRaw = deviceQualityState.val;
|
|
1031
1140
|
break;
|
|
1032
1141
|
case 'lupusec':
|
|
1033
1142
|
linkQuality = deviceQualityState.val;
|
|
@@ -1039,9 +1148,12 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1039
1148
|
linkQuality = ' - ';
|
|
1040
1149
|
} else if (deviceQualityState.val < 0) {
|
|
1041
1150
|
linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
|
|
1151
|
+
linkQualityRaw = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100);
|
|
1152
|
+
|
|
1042
1153
|
// If Quality State is an value between 0-255 (zigbee) calculate in percent:
|
|
1043
1154
|
} else if (deviceQualityState.val >= 0) {
|
|
1044
1155
|
linkQuality = parseFloat(((100 / 255) * deviceQualityState.val).toFixed(0)) + '%';
|
|
1156
|
+
linkQualityRaw = parseFloat(((100 / 255) * deviceQualityState.val).toFixed(0));
|
|
1045
1157
|
}
|
|
1046
1158
|
break;
|
|
1047
1159
|
}
|
|
@@ -1064,7 +1176,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1064
1176
|
linkQuality = deviceQualityState.val;
|
|
1065
1177
|
} else if (mqttNukiValue < 0) {
|
|
1066
1178
|
linkQuality = Math.min(Math.max(2 * (mqttNukiValue + 100), 0), 100) + '%';
|
|
1067
|
-
|
|
1179
|
+
linkQualityRaw = Math.min(Math.max(2 * (mqttNukiValue + 100), 0), 100);
|
|
1068
1180
|
}
|
|
1069
1181
|
}
|
|
1070
1182
|
break;
|
|
@@ -1072,24 +1184,33 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1072
1184
|
} else {
|
|
1073
1185
|
linkQuality = ' - ';
|
|
1074
1186
|
}
|
|
1075
|
-
return linkQuality;
|
|
1187
|
+
return [linkQuality, linkQualityRaw];
|
|
1076
1188
|
}
|
|
1077
1189
|
|
|
1078
1190
|
/**
|
|
1079
1191
|
* get battery data
|
|
1080
1192
|
* @param {object} deviceBatteryState - State value
|
|
1081
1193
|
* @param {object} deviceLowBatState - State value
|
|
1194
|
+
* @param {object} faultReportingState - State value
|
|
1082
1195
|
* @param {object} adapterID - adapter name
|
|
1083
1196
|
*/
|
|
1084
|
-
async getBatteryData(deviceBatteryState, deviceLowBatState, adapterID) {
|
|
1197
|
+
async getBatteryData(deviceBatteryState, deviceLowBatState, faultReportingState, adapterID) {
|
|
1085
1198
|
let batteryHealthRaw;
|
|
1199
|
+
let batteryHealthUnitRaw;
|
|
1086
1200
|
let batteryHealth;
|
|
1087
1201
|
let isBatteryDevice;
|
|
1088
1202
|
|
|
1089
1203
|
switch (adapterID) {
|
|
1090
1204
|
case 'hmrpc':
|
|
1091
1205
|
if (deviceBatteryState === undefined) {
|
|
1092
|
-
if (
|
|
1206
|
+
if (faultReportingState !== undefined) {
|
|
1207
|
+
if (faultReportingState !== 6) {
|
|
1208
|
+
batteryHealth = 'ok';
|
|
1209
|
+
} else {
|
|
1210
|
+
batteryHealth = 'low';
|
|
1211
|
+
}
|
|
1212
|
+
isBatteryDevice = true;
|
|
1213
|
+
} else if (deviceLowBatState !== undefined) {
|
|
1093
1214
|
if (deviceLowBatState !== 1) {
|
|
1094
1215
|
batteryHealth = 'ok';
|
|
1095
1216
|
} else {
|
|
@@ -1105,6 +1226,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1105
1226
|
} else {
|
|
1106
1227
|
batteryHealth = deviceBatteryState + 'V';
|
|
1107
1228
|
batteryHealthRaw = deviceBatteryState;
|
|
1229
|
+
batteryHealthUnitRaw = 'V';
|
|
1108
1230
|
isBatteryDevice = true;
|
|
1109
1231
|
}
|
|
1110
1232
|
}
|
|
@@ -1124,12 +1246,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1124
1246
|
} else {
|
|
1125
1247
|
batteryHealth = deviceBatteryState + '%';
|
|
1126
1248
|
batteryHealthRaw = deviceBatteryState;
|
|
1249
|
+
batteryHealthUnitRaw = '%';
|
|
1127
1250
|
isBatteryDevice = true;
|
|
1128
1251
|
}
|
|
1129
1252
|
break;
|
|
1130
1253
|
}
|
|
1131
1254
|
|
|
1132
|
-
return [batteryHealth, isBatteryDevice, batteryHealthRaw];
|
|
1255
|
+
return [batteryHealth, isBatteryDevice, batteryHealthRaw, batteryHealthUnitRaw];
|
|
1133
1256
|
}
|
|
1134
1257
|
|
|
1135
1258
|
/**
|
|
@@ -1187,7 +1310,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1187
1310
|
* @param {object} selector - Selector
|
|
1188
1311
|
*/
|
|
1189
1312
|
async getLastContact(selector) {
|
|
1190
|
-
const lastContact =
|
|
1313
|
+
const lastContact = this.getTimestamp(selector);
|
|
1191
1314
|
let lastContactString;
|
|
1192
1315
|
|
|
1193
1316
|
lastContactString = this.formatDate(new Date(selector), 'hh:mm') + ' Uhr';
|
|
@@ -1220,8 +1343,8 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1220
1343
|
const deviceUnreachSelector = await this.getForeignStateAsync(unreachDP);
|
|
1221
1344
|
const deviceStateSelector = await this.getForeignStateAsync(deviceStateSelectorDP); // for hmrpc devices
|
|
1222
1345
|
const rssiPeerSelector = await this.getForeignStateAsync(rssiPeerSelectorDP);
|
|
1223
|
-
const lastContact =
|
|
1224
|
-
const lastDeviceUnreachStateChange = deviceUnreachSelector != undefined ?
|
|
1346
|
+
const lastContact = this.getTimestamp(deviceTimeSelector.ts);
|
|
1347
|
+
const lastDeviceUnreachStateChange = deviceUnreachSelector != undefined ? this.getTimestamp(deviceUnreachSelector.lc) : this.getTimestamp(timeSelector.ts);
|
|
1225
1348
|
// If there is no contact since user sets minutes add device in offline list
|
|
1226
1349
|
// calculate to days after 48 hours
|
|
1227
1350
|
switch (unreachDP) {
|
|
@@ -1273,6 +1396,16 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1273
1396
|
linkQuality = '0%'; // set linkQuality to nothing
|
|
1274
1397
|
}
|
|
1275
1398
|
break;
|
|
1399
|
+
case 'proxmox':
|
|
1400
|
+
if (this.configMaxMinutes[adapterID] <= 0) {
|
|
1401
|
+
if (deviceUnreachState !== 'running' && deviceUnreachState !== 'online') {
|
|
1402
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1403
|
+
}
|
|
1404
|
+
} else if (lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID] && deviceUnreachState !== 'running' && deviceUnreachState !== 'online') {
|
|
1405
|
+
deviceState = 'Offline'; //set online state to offline
|
|
1406
|
+
linkQuality = '0%'; // set linkQuality to nothing
|
|
1407
|
+
}
|
|
1408
|
+
break;
|
|
1276
1409
|
case 'hmiP':
|
|
1277
1410
|
case 'maxcube':
|
|
1278
1411
|
if (this.configMaxMinutes[adapterID] <= 0) {
|
|
@@ -1374,26 +1507,26 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1374
1507
|
* when was last contact of device
|
|
1375
1508
|
*/
|
|
1376
1509
|
async checkLastContact() {
|
|
1377
|
-
for (const device of this.listAllDevicesRaw) {
|
|
1378
|
-
if (
|
|
1379
|
-
const oldContactState =
|
|
1380
|
-
|
|
1510
|
+
for (const [device, deviceData] of this.listAllDevicesRaw) {
|
|
1511
|
+
if (deviceData.instancedeviceConnected !== false) {
|
|
1512
|
+
const oldContactState = deviceData.Status;
|
|
1513
|
+
deviceData.UnreachState = await this.getInitValue(deviceData.UnreachDP);
|
|
1381
1514
|
const contactData = await this.getOnlineState(
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1515
|
+
deviceData.timeSelector,
|
|
1516
|
+
deviceData.adapterID,
|
|
1517
|
+
deviceData.UnreachDP,
|
|
1518
|
+
deviceData.SignalStrength,
|
|
1519
|
+
deviceData.UnreachState,
|
|
1520
|
+
deviceData.DeviceStateSelectorDP,
|
|
1521
|
+
deviceData.rssiPeerSelectorDP,
|
|
1389
1522
|
);
|
|
1390
1523
|
if (contactData !== undefined) {
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1524
|
+
deviceData.LastContact = contactData[0];
|
|
1525
|
+
deviceData.Status = contactData[1];
|
|
1526
|
+
deviceData.linkQuality = contactData[2];
|
|
1394
1527
|
}
|
|
1395
|
-
if (this.config.checkSendOfflineMsg && oldContactState !==
|
|
1396
|
-
await this.
|
|
1528
|
+
if (this.config.checkSendOfflineMsg && oldContactState !== deviceData.Status && !this.blacklistNotify.includes(deviceData.Path)) {
|
|
1529
|
+
await this.sendStateNotifications('onlineStateDevice', device);
|
|
1397
1530
|
}
|
|
1398
1531
|
}
|
|
1399
1532
|
}
|
|
@@ -1406,6 +1539,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1406
1539
|
this.linkQualityDevices = [];
|
|
1407
1540
|
this.batteryPowered = [];
|
|
1408
1541
|
this.batteryLowPowered = [];
|
|
1542
|
+
this.listAllDevicesUserRaw = [];
|
|
1409
1543
|
this.listAllDevices = [];
|
|
1410
1544
|
this.offlineDevices = [];
|
|
1411
1545
|
this.batteryLowPoweredRaw = [];
|
|
@@ -1417,47 +1551,45 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1417
1551
|
adptName = '';
|
|
1418
1552
|
}
|
|
1419
1553
|
|
|
1420
|
-
for (const
|
|
1554
|
+
for (const deviceData of this.listAllDevicesRaw.values()) {
|
|
1421
1555
|
/*---------- fill raw lists ----------*/
|
|
1422
1556
|
// low bat list
|
|
1423
|
-
if (
|
|
1557
|
+
if (deviceData.LowBat && deviceData.Status !== 'Offline') {
|
|
1424
1558
|
this.batteryLowPoweredRaw.push({
|
|
1425
|
-
Path:
|
|
1426
|
-
Device:
|
|
1427
|
-
Adapter:
|
|
1428
|
-
Battery:
|
|
1559
|
+
Path: deviceData.Path,
|
|
1560
|
+
Device: deviceData.Device,
|
|
1561
|
+
Adapter: deviceData.Adapter,
|
|
1562
|
+
Battery: deviceData.Battery,
|
|
1429
1563
|
});
|
|
1430
1564
|
}
|
|
1431
1565
|
// offline raw list
|
|
1432
|
-
if (
|
|
1566
|
+
if (deviceData.Status === 'Offline') {
|
|
1433
1567
|
this.offlineDevicesRaw.push({
|
|
1434
|
-
Path:
|
|
1435
|
-
Device:
|
|
1436
|
-
Adapter:
|
|
1437
|
-
LastContact:
|
|
1568
|
+
Path: deviceData.Path,
|
|
1569
|
+
Device: deviceData.Device,
|
|
1570
|
+
Adapter: deviceData.Adapter,
|
|
1571
|
+
LastContact: deviceData.LastContact,
|
|
1438
1572
|
});
|
|
1439
1573
|
}
|
|
1440
1574
|
|
|
1441
1575
|
// upgradable raw list
|
|
1442
|
-
if (
|
|
1576
|
+
if (deviceData.Upgradable === true) {
|
|
1443
1577
|
this.upgradableDevicesRaw.push({
|
|
1444
|
-
Path:
|
|
1445
|
-
Device:
|
|
1446
|
-
Adapter:
|
|
1578
|
+
Path: deviceData.Path,
|
|
1579
|
+
Device: deviceData.Device,
|
|
1580
|
+
Adapter: deviceData.Adapter,
|
|
1447
1581
|
});
|
|
1448
1582
|
}
|
|
1449
1583
|
|
|
1450
|
-
if (adptName === '' && !this.blacklistLists.includes(
|
|
1451
|
-
await this.theLists(
|
|
1584
|
+
if (adptName === '' && !this.blacklistLists.includes(deviceData.Path)) {
|
|
1585
|
+
await this.theLists(deviceData);
|
|
1452
1586
|
}
|
|
1453
1587
|
|
|
1454
1588
|
if (this.config.createOwnFolder && adptName !== '') {
|
|
1455
|
-
if (
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1589
|
+
if (!deviceData.adapterID.includes(adptName)) continue;
|
|
1590
|
+
/*---------- fill user lists for each adapter ----------*/
|
|
1591
|
+
if (this.blacklistAdapterLists.includes(deviceData.Path)) continue;
|
|
1592
|
+
await this.theLists(deviceData);
|
|
1461
1593
|
}
|
|
1462
1594
|
}
|
|
1463
1595
|
await this.countDevices();
|
|
@@ -1468,6 +1600,24 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1468
1600
|
* @param {object} device
|
|
1469
1601
|
*/
|
|
1470
1602
|
async theLists(device) {
|
|
1603
|
+
// Raw List with all devices for user
|
|
1604
|
+
this.listAllDevicesUserRaw.push({
|
|
1605
|
+
Device: device.Device,
|
|
1606
|
+
Adapter: device.Adapter,
|
|
1607
|
+
Instance: device.instance,
|
|
1608
|
+
'Instance connected': device.instancedeviceConnected,
|
|
1609
|
+
isBatteryDevice: device.isBatteryDevice,
|
|
1610
|
+
Battery: device.Battery,
|
|
1611
|
+
BatteryRaw: device.BatteryRaw,
|
|
1612
|
+
BatteryUnitRaw: device.BatteryUnitRaw,
|
|
1613
|
+
isLowBat: device.LowBat,
|
|
1614
|
+
'Signal strength': device.SignalStrength,
|
|
1615
|
+
'Signal strength Raw': device.SignalStrengthRaw,
|
|
1616
|
+
'Last contact': device.LastContact,
|
|
1617
|
+
'Update Available': device.Upgradable,
|
|
1618
|
+
Status: device.Status,
|
|
1619
|
+
});
|
|
1620
|
+
|
|
1471
1621
|
// List with all devices
|
|
1472
1622
|
this.listAllDevices.push({
|
|
1473
1623
|
Device: device.Device,
|
|
@@ -1516,7 +1666,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1516
1666
|
}
|
|
1517
1667
|
|
|
1518
1668
|
// Device update List
|
|
1519
|
-
if (device.Upgradable) {
|
|
1669
|
+
if (device.Upgradable === true) {
|
|
1520
1670
|
this.upgradableList.push({
|
|
1521
1671
|
Device: device.Device,
|
|
1522
1672
|
Adapter: device.Adapter,
|
|
@@ -1547,47 +1697,6 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1547
1697
|
this.upgradableDevicesCount = this.upgradableList.length;
|
|
1548
1698
|
}
|
|
1549
1699
|
|
|
1550
|
-
/**
|
|
1551
|
-
* @param {string} adptName - Adapter name
|
|
1552
|
-
*/
|
|
1553
|
-
async createDataForEachAdapter(adptName) {
|
|
1554
|
-
// create Data for each Adapter in own lists
|
|
1555
|
-
this.log.debug(`Function started: ${this.createDataForEachAdapter.name}`);
|
|
1556
|
-
|
|
1557
|
-
try {
|
|
1558
|
-
for (const device of this.listAllDevicesRaw) {
|
|
1559
|
-
if (device.adapterID.includes(adptName)) {
|
|
1560
|
-
// list device only if selected adapter matched with device
|
|
1561
|
-
await this.createLists(adptName);
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
|
-
await this.writeDatapoints(adptName); // fill the datapoints
|
|
1565
|
-
} catch (error) {
|
|
1566
|
-
this.errorReporting('[createDataForEachAdapter]', error);
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
|
-
this.log.debug(`Function finished: ${this.createDataForEachAdapter.name}`);
|
|
1570
|
-
} // <-- end of createDataForEachAdapter
|
|
1571
|
-
|
|
1572
|
-
/**
|
|
1573
|
-
* create Data of all selected adapter in one list
|
|
1574
|
-
*/
|
|
1575
|
-
async createDataOfAllAdapter() {
|
|
1576
|
-
this.log.debug(`Function started: ${this.createDataOfAllAdapter.name}`);
|
|
1577
|
-
|
|
1578
|
-
try {
|
|
1579
|
-
for (let i = 0; i < this.selAdapter.length; i++) {
|
|
1580
|
-
await this.createData(i);
|
|
1581
|
-
await this.createLists();
|
|
1582
|
-
}
|
|
1583
|
-
await this.writeDatapoints(); // fill the datapoints
|
|
1584
|
-
} catch (error) {
|
|
1585
|
-
this.errorReporting('[createDataOfAllAdapter]', error);
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
|
-
this.log.debug(`Function finished: ${this.createDataOfAllAdapter.name}`);
|
|
1589
|
-
} // <-- end of createDataOfAllAdapter
|
|
1590
|
-
|
|
1591
1700
|
/**
|
|
1592
1701
|
* @param {string} [adptName] - Adaptername
|
|
1593
1702
|
*/
|
|
@@ -1606,26 +1715,58 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1606
1715
|
}
|
|
1607
1716
|
|
|
1608
1717
|
// Write Datapoints for counts
|
|
1609
|
-
await this.
|
|
1610
|
-
await this.
|
|
1611
|
-
await this.
|
|
1612
|
-
await this.
|
|
1613
|
-
await this.
|
|
1718
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}offlineCount`, { val: this.offlineDevicesCount, ack: true });
|
|
1719
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}countAll`, { val: this.deviceCounter, ack: true });
|
|
1720
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}batteryCount`, { val: this.batteryPoweredCount, ack: true });
|
|
1721
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}lowBatteryCount`, { val: this.lowBatteryPoweredCount, ack: true });
|
|
1722
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}upgradableCount`, { val: this.upgradableDevicesCount, ack: true });
|
|
1614
1723
|
|
|
1615
1724
|
// List all devices
|
|
1616
1725
|
if (this.deviceCounter === 0) {
|
|
1617
1726
|
// if no device is count, write the JSON List with default value
|
|
1618
|
-
this.listAllDevices = [
|
|
1727
|
+
this.listAllDevices = [
|
|
1728
|
+
{
|
|
1729
|
+
Device: '--none--',
|
|
1730
|
+
Adapter: '',
|
|
1731
|
+
Battery: '',
|
|
1732
|
+
'Signal strength': '',
|
|
1733
|
+
'Last contact': '',
|
|
1734
|
+
Status: '',
|
|
1735
|
+
},
|
|
1736
|
+
];
|
|
1737
|
+
this.listAllDevicesUserRaw = [
|
|
1738
|
+
{
|
|
1739
|
+
Device: '--none--',
|
|
1740
|
+
Adapter: '',
|
|
1741
|
+
Instance: '',
|
|
1742
|
+
'Instance connected': '',
|
|
1743
|
+
isBatteryDevice: '',
|
|
1744
|
+
Battery: '',
|
|
1745
|
+
BatteryRaw: '',
|
|
1746
|
+
isLowBat: '',
|
|
1747
|
+
'Signal strength': '',
|
|
1748
|
+
'Last contact': '',
|
|
1749
|
+
UpdateAvailable: '',
|
|
1750
|
+
Status: '',
|
|
1751
|
+
},
|
|
1752
|
+
];
|
|
1619
1753
|
}
|
|
1620
|
-
await this.
|
|
1754
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}listAll`, { val: JSON.stringify(this.listAllDevices), ack: true });
|
|
1755
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}listAllRawJSON`, { val: JSON.stringify(this.listAllDevicesUserRaw), ack: true });
|
|
1621
1756
|
|
|
1622
1757
|
// List link quality
|
|
1623
1758
|
if (this.linkQualityCount === 0) {
|
|
1624
1759
|
// if no device is count, write the JSON List with default value
|
|
1625
|
-
this.linkQualityDevices = [
|
|
1760
|
+
this.linkQualityDevices = [
|
|
1761
|
+
{
|
|
1762
|
+
Device: '--none--',
|
|
1763
|
+
Adapter: '',
|
|
1764
|
+
'Signal strength': '',
|
|
1765
|
+
},
|
|
1766
|
+
];
|
|
1626
1767
|
}
|
|
1627
1768
|
//write JSON list
|
|
1628
|
-
await this.
|
|
1769
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}linkQualityList`, {
|
|
1629
1770
|
val: JSON.stringify(this.linkQualityDevices),
|
|
1630
1771
|
ack: true,
|
|
1631
1772
|
});
|
|
@@ -1633,10 +1774,16 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1633
1774
|
// List offline devices
|
|
1634
1775
|
if (this.offlineDevicesCount === 0) {
|
|
1635
1776
|
// if no device is count, write the JSON List with default value
|
|
1636
|
-
this.offlineDevices = [
|
|
1777
|
+
this.offlineDevices = [
|
|
1778
|
+
{
|
|
1779
|
+
Device: '--none--',
|
|
1780
|
+
Adapter: '',
|
|
1781
|
+
'Last contact': '',
|
|
1782
|
+
},
|
|
1783
|
+
];
|
|
1637
1784
|
}
|
|
1638
1785
|
//write JSON list
|
|
1639
|
-
await this.
|
|
1786
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}offlineList`, {
|
|
1640
1787
|
val: JSON.stringify(this.offlineDevices),
|
|
1641
1788
|
ack: true,
|
|
1642
1789
|
});
|
|
@@ -1644,10 +1791,16 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1644
1791
|
// List updatable
|
|
1645
1792
|
if (this.upgradableDevicesCount === 0) {
|
|
1646
1793
|
// if no device is count, write the JSON List with default value
|
|
1647
|
-
this.upgradableList = [
|
|
1794
|
+
this.upgradableList = [
|
|
1795
|
+
{
|
|
1796
|
+
Device: '--none--',
|
|
1797
|
+
Adapter: '',
|
|
1798
|
+
'Last contact': '',
|
|
1799
|
+
},
|
|
1800
|
+
];
|
|
1648
1801
|
}
|
|
1649
1802
|
//write JSON list
|
|
1650
|
-
await this.
|
|
1803
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}upgradableList`, {
|
|
1651
1804
|
val: JSON.stringify(this.upgradableList),
|
|
1652
1805
|
ack: true,
|
|
1653
1806
|
});
|
|
@@ -1658,7 +1811,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1658
1811
|
this.batteryPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
|
|
1659
1812
|
}
|
|
1660
1813
|
//write JSON list
|
|
1661
|
-
await this.
|
|
1814
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}batteryList`, {
|
|
1662
1815
|
val: JSON.stringify(this.batteryPowered),
|
|
1663
1816
|
ack: true,
|
|
1664
1817
|
});
|
|
@@ -1669,71 +1822,71 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1669
1822
|
this.batteryLowPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
|
|
1670
1823
|
}
|
|
1671
1824
|
//write JSON list
|
|
1672
|
-
await this.
|
|
1825
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}lowBatteryList`, {
|
|
1673
1826
|
val: JSON.stringify(this.batteryLowPowered),
|
|
1674
1827
|
ack: true,
|
|
1675
1828
|
});
|
|
1676
1829
|
|
|
1677
1830
|
// set booleans datapoints
|
|
1678
1831
|
if (this.offlineDevicesCount === 0) {
|
|
1679
|
-
await this.
|
|
1832
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}oneDeviceOffline`, {
|
|
1680
1833
|
val: false,
|
|
1681
1834
|
ack: true,
|
|
1682
1835
|
});
|
|
1683
1836
|
} else {
|
|
1684
|
-
await this.
|
|
1837
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}oneDeviceOffline`, {
|
|
1685
1838
|
val: true,
|
|
1686
1839
|
ack: true,
|
|
1687
1840
|
});
|
|
1688
1841
|
}
|
|
1689
1842
|
|
|
1690
1843
|
if (this.lowBatteryPoweredCount === 0) {
|
|
1691
|
-
await this.
|
|
1844
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}oneDeviceLowBat`, {
|
|
1692
1845
|
val: false,
|
|
1693
1846
|
ack: true,
|
|
1694
1847
|
});
|
|
1695
1848
|
} else {
|
|
1696
|
-
await this.
|
|
1849
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}oneDeviceLowBat`, {
|
|
1697
1850
|
val: true,
|
|
1698
1851
|
ack: true,
|
|
1699
1852
|
});
|
|
1700
1853
|
}
|
|
1701
1854
|
|
|
1702
1855
|
if (this.upgradableDevicesCount === 0) {
|
|
1703
|
-
await this.
|
|
1856
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}oneDeviceUpdatable`, {
|
|
1704
1857
|
val: false,
|
|
1705
1858
|
ack: true,
|
|
1706
1859
|
});
|
|
1707
1860
|
} else {
|
|
1708
|
-
await this.
|
|
1861
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}oneDeviceUpdatable`, {
|
|
1709
1862
|
val: true,
|
|
1710
1863
|
ack: true,
|
|
1711
1864
|
});
|
|
1712
1865
|
}
|
|
1713
1866
|
|
|
1714
1867
|
//write HTML list
|
|
1715
|
-
if (this.
|
|
1716
|
-
await this.
|
|
1717
|
-
val: await this.
|
|
1868
|
+
if (this.configCreateHtmlList) {
|
|
1869
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}linkQualityListHTML`, {
|
|
1870
|
+
val: await this.createListHTML('linkQualityList', this.linkQualityDevices, this.linkQualityCount, null),
|
|
1718
1871
|
ack: true,
|
|
1719
1872
|
});
|
|
1720
|
-
await this.
|
|
1721
|
-
val: await this.
|
|
1873
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}offlineListHTML`, {
|
|
1874
|
+
val: await this.createListHTML('offlineList', this.offlineDevices, this.offlineDevicesCount, null),
|
|
1722
1875
|
ack: true,
|
|
1723
1876
|
});
|
|
1724
|
-
await this.
|
|
1725
|
-
val: await this.
|
|
1877
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}batteryListHTML`, {
|
|
1878
|
+
val: await this.createListHTML('batteryList', this.batteryPowered, this.batteryPoweredCount, false),
|
|
1726
1879
|
ack: true,
|
|
1727
1880
|
});
|
|
1728
|
-
await this.
|
|
1729
|
-
val: await this.
|
|
1881
|
+
await this.setStateChangedAsync(`devices.${dpSubFolder}lowBatteryListHTML`, {
|
|
1882
|
+
val: await this.createListHTML('batteryList', this.batteryLowPowered, this.lowBatteryPoweredCount, true),
|
|
1730
1883
|
ack: true,
|
|
1731
1884
|
});
|
|
1732
1885
|
}
|
|
1733
1886
|
|
|
1734
1887
|
// create timestamp of last run
|
|
1735
1888
|
const lastCheck = this.formatDate(new Date(), 'DD.MM.YYYY') + ' - ' + this.formatDate(new Date(), 'hh:mm:ss');
|
|
1736
|
-
await this.
|
|
1889
|
+
await this.setStateChangedAsync('lastCheck', lastCheck, true);
|
|
1737
1890
|
} catch (error) {
|
|
1738
1891
|
this.errorReporting('[writeDatapoints]', error);
|
|
1739
1892
|
}
|
|
@@ -1741,13 +1894,25 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1741
1894
|
} //<--End of writing Datapoints
|
|
1742
1895
|
|
|
1743
1896
|
/**
|
|
1744
|
-
* get Instances
|
|
1897
|
+
* get all Instances at start
|
|
1898
|
+
*/
|
|
1899
|
+
async getAllInstanceData() {
|
|
1900
|
+
try {
|
|
1901
|
+
const allInstances = `system.adapter.*`;
|
|
1902
|
+
await this.getInstanceData(allInstances);
|
|
1903
|
+
} catch (error) {
|
|
1904
|
+
this.errorReporting('[getInstance]', error);
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
/**
|
|
1909
|
+
* get instance data
|
|
1910
|
+
*@param {string} instanceObject
|
|
1745
1911
|
*/
|
|
1746
|
-
async getInstanceData() {
|
|
1912
|
+
async getInstanceData(instanceObject) {
|
|
1747
1913
|
try {
|
|
1748
|
-
await this.
|
|
1914
|
+
const instanceAliveDP = await this.getForeignStatesAsync(`${instanceObject}.alive`);
|
|
1749
1915
|
|
|
1750
|
-
const instanceAliveDP = await this.getForeignStatesAsync(`system.adapter.*.alive`);
|
|
1751
1916
|
for (const [id] of Object.entries(instanceAliveDP)) {
|
|
1752
1917
|
if (!(typeof id === 'string' && id.startsWith(`system.adapter.`))) continue;
|
|
1753
1918
|
|
|
@@ -1771,6 +1936,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1771
1936
|
const instanceObjectPath = `system.adapter.${instanceName}`;
|
|
1772
1937
|
let adapterName;
|
|
1773
1938
|
let adapterVersion;
|
|
1939
|
+
let adapterAvailableUpdate = '';
|
|
1774
1940
|
let instanceMode;
|
|
1775
1941
|
let scheduleTime = 'N/A';
|
|
1776
1942
|
const instanceObjectData = await this.getForeignObjectAsync(instanceObjectPath);
|
|
@@ -1785,20 +1951,30 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1785
1951
|
}
|
|
1786
1952
|
}
|
|
1787
1953
|
|
|
1954
|
+
await this.getAdapterUpdateData(`admin.*.info.updatesJson`);
|
|
1955
|
+
|
|
1956
|
+
if (this.adapterUpdatesJsonRaw.has(adapterName)) {
|
|
1957
|
+
for (const adapter of this.adapterUpdatesJsonRaw.values()) {
|
|
1958
|
+
adapterAvailableUpdate = adapter.newVersion;
|
|
1959
|
+
}
|
|
1960
|
+
} else {
|
|
1961
|
+
adapterAvailableUpdate = ' - ';
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1788
1964
|
//const adapterVersionVal = await this.getInitValue(adapterVersionDP);
|
|
1789
|
-
const instanceStatusRaw = await this.setInstanceStatus(instanceMode, scheduleTime, id,
|
|
1965
|
+
const instanceStatusRaw = await this.setInstanceStatus(instanceMode, scheduleTime, id, instanceConnectedHostDP, instanceConnectedDeviceDP);
|
|
1790
1966
|
const isAlive = instanceStatusRaw[1];
|
|
1791
1967
|
const instanceStatus = instanceStatusRaw[0];
|
|
1792
1968
|
const isHealthy = instanceStatusRaw[2];
|
|
1793
1969
|
|
|
1794
1970
|
//subscribe to statechanges
|
|
1795
|
-
this.
|
|
1796
|
-
this.
|
|
1797
|
-
this.
|
|
1798
|
-
|
|
1971
|
+
this.subscribeForeignStates(id);
|
|
1972
|
+
this.subscribeForeignStates(instanceConnectedHostDP);
|
|
1973
|
+
this.subscribeForeignStates(instanceConnectedDeviceDP);
|
|
1974
|
+
this.subscribeForeignObjects(`system.adapter.*`);
|
|
1799
1975
|
|
|
1800
1976
|
// create raw list
|
|
1801
|
-
this.listInstanceRaw.
|
|
1977
|
+
this.listInstanceRaw.set(instanceObjectPath, {
|
|
1802
1978
|
Adapter: adapterName,
|
|
1803
1979
|
InstanceName: instanceName,
|
|
1804
1980
|
instanceObjectPath: instanceObjectPath,
|
|
@@ -1806,6 +1982,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1806
1982
|
instanceMode: instanceMode,
|
|
1807
1983
|
schedule: scheduleTime,
|
|
1808
1984
|
adapterVersion: adapterVersion,
|
|
1985
|
+
updateAvailable: adapterAvailableUpdate,
|
|
1809
1986
|
isAlive: isAlive,
|
|
1810
1987
|
isHealthy: isHealthy,
|
|
1811
1988
|
connectedHostPath: instanceConnectedHostDP,
|
|
@@ -1818,7 +1995,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1818
1995
|
await this.createInstanceList();
|
|
1819
1996
|
await this.writeInstanceDPs();
|
|
1820
1997
|
} catch (error) {
|
|
1821
|
-
this.errorReporting('[
|
|
1998
|
+
this.errorReporting('[getInstanceData]', error);
|
|
1822
1999
|
}
|
|
1823
2000
|
}
|
|
1824
2001
|
|
|
@@ -1835,28 +2012,29 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1835
2012
|
|
|
1836
2013
|
/**
|
|
1837
2014
|
* set status for instance
|
|
1838
|
-
* @param {
|
|
1839
|
-
* @param {
|
|
2015
|
+
* @param {string} instanceMode
|
|
2016
|
+
* @param {string} scheduleTime
|
|
1840
2017
|
* @param {object} instanceAlivePath
|
|
1841
|
-
* @param {
|
|
1842
|
-
* @param {
|
|
1843
|
-
* @param {object} connectedDeviceVal
|
|
2018
|
+
* @param {string} hostConnectedPath
|
|
2019
|
+
* @param {string} isDeviceConnctedPath
|
|
1844
2020
|
*/
|
|
1845
|
-
async setInstanceStatus(instanceMode, scheduleTime, instanceAlivePath,
|
|
1846
|
-
|
|
2021
|
+
async setInstanceStatus(instanceMode, scheduleTime, instanceAlivePath, hostConnectedPath, isDeviceConnctedPath) {
|
|
2022
|
+
const isAliveSchedule = await this.getForeignStateAsync(instanceAlivePath);
|
|
2023
|
+
let isHostConnected = await this.getInitValue(hostConnectedPath);
|
|
2024
|
+
let isAlive = await this.getInitValue(instanceAlivePath);
|
|
2025
|
+
let isDeviceConnected = await this.getInitValue(isDeviceConnctedPath);
|
|
2026
|
+
let instanceStatusString = 'Instance deactivated';
|
|
1847
2027
|
let lastUpdate;
|
|
1848
2028
|
let lastCronRun;
|
|
1849
2029
|
let diff;
|
|
1850
2030
|
let previousCronRun = null;
|
|
1851
|
-
let isAlive = false;
|
|
1852
2031
|
let isHealthy = false;
|
|
1853
|
-
|
|
2032
|
+
|
|
1854
2033
|
switch (instanceMode) {
|
|
1855
2034
|
case 'schedule':
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
previousCronRun = await this.getPreviousCronRun(scheduleTime); // When was the last cron run
|
|
2035
|
+
if (isAliveSchedule) {
|
|
2036
|
+
lastUpdate = Math.round((Date.now() - isAliveSchedule.lc) / 1000); // Last state change in seconds
|
|
2037
|
+
previousCronRun = this.getPreviousCronRun(scheduleTime); // When was the last cron run
|
|
1860
2038
|
if (previousCronRun) {
|
|
1861
2039
|
lastCronRun = Math.round(previousCronRun / 1000); // change distance to last run in seconds
|
|
1862
2040
|
diff = lastCronRun - lastUpdate;
|
|
@@ -1864,42 +2042,43 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1864
2042
|
// if 5 minutes difference exceeded, instance is not alive
|
|
1865
2043
|
isAlive = true;
|
|
1866
2044
|
isHealthy = true;
|
|
1867
|
-
instanceStatusString = '
|
|
2045
|
+
instanceStatusString = 'Instanz okay';
|
|
1868
2046
|
}
|
|
1869
2047
|
}
|
|
1870
2048
|
}
|
|
1871
2049
|
break;
|
|
1872
2050
|
case 'daemon':
|
|
1873
|
-
if (!
|
|
1874
|
-
|
|
2051
|
+
if (!isAlive) return ['Instanz deaktiviert', false, null]; // if instance is turned off
|
|
2052
|
+
if (isDeviceConnected === undefined) isDeviceConnected = true;
|
|
1875
2053
|
// In case of (re)start, connection may take some time. We take 3 attempts.
|
|
1876
2054
|
// Attempt 1/3 - immediately
|
|
1877
|
-
if (
|
|
1878
|
-
isAlive = true;
|
|
2055
|
+
if (isHostConnected && isDeviceConnected) {
|
|
1879
2056
|
isHealthy = true;
|
|
1880
|
-
instanceStatusString = '
|
|
2057
|
+
instanceStatusString = 'Instanz okay';
|
|
1881
2058
|
} else {
|
|
1882
2059
|
// Attempt 2/3 - after 10 seconds
|
|
1883
2060
|
await this.wait(10000);
|
|
1884
|
-
|
|
1885
|
-
|
|
2061
|
+
isDeviceConnected = await this.getInitValue(isDeviceConnctedPath);
|
|
2062
|
+
isHostConnected = await this.getInitValue(hostConnectedPath);
|
|
2063
|
+
|
|
2064
|
+
if (isHostConnected && isDeviceConnected) {
|
|
1886
2065
|
isHealthy = true;
|
|
1887
|
-
instanceStatusString = '
|
|
2066
|
+
instanceStatusString = 'Instanz okay';
|
|
1888
2067
|
} else {
|
|
1889
2068
|
// Attempt 3/3 - after 20 seconds in total
|
|
1890
2069
|
await this.wait(10000);
|
|
1891
|
-
|
|
1892
|
-
|
|
2070
|
+
isDeviceConnected = await this.getInitValue(isDeviceConnctedPath);
|
|
2071
|
+
isHostConnected = await this.getInitValue(hostConnectedPath);
|
|
2072
|
+
|
|
2073
|
+
if (isHostConnected && isDeviceConnected) {
|
|
1893
2074
|
isHealthy = true;
|
|
1894
|
-
instanceStatusString = '
|
|
2075
|
+
instanceStatusString = 'Instanz okay';
|
|
1895
2076
|
} else {
|
|
1896
|
-
if (!
|
|
1897
|
-
instanceStatusString = '
|
|
1898
|
-
isAlive = true;
|
|
2077
|
+
if (!isDeviceConnected) {
|
|
2078
|
+
instanceStatusString = 'Nicht verbunden mit Gerät oder Dienst';
|
|
1899
2079
|
isHealthy = false;
|
|
1900
|
-
} else if (!
|
|
1901
|
-
instanceStatusString = '
|
|
1902
|
-
isAlive = true;
|
|
2080
|
+
} else if (!isHostConnected) {
|
|
2081
|
+
instanceStatusString = 'Nicht verbunden mit Host';
|
|
1903
2082
|
isHealthy = false;
|
|
1904
2083
|
}
|
|
1905
2084
|
}
|
|
@@ -1911,27 +2090,44 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1911
2090
|
return [instanceStatusString, isAlive, isHealthy];
|
|
1912
2091
|
}
|
|
1913
2092
|
|
|
1914
|
-
|
|
1915
|
-
|
|
2093
|
+
/**
|
|
2094
|
+
* create adapter update data
|
|
2095
|
+
*/
|
|
2096
|
+
async createAdapterUpdateData() {
|
|
2097
|
+
const adapterUpdateListDP = `admin.*.info.updatesJson`;
|
|
2098
|
+
|
|
2099
|
+
// subscribe to datapoint
|
|
2100
|
+
this.subscribeForeignStates(adapterUpdateListDP);
|
|
2101
|
+
|
|
2102
|
+
await this.getAdapterUpdateData(adapterUpdateListDP);
|
|
2103
|
+
|
|
2104
|
+
await this.createAdapterUpdateList();
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
/**
|
|
2108
|
+
* create adapter update raw lists
|
|
2109
|
+
* @param {string} adapterUpdateListDP
|
|
2110
|
+
*/
|
|
2111
|
+
async getAdapterUpdateData(adapterUpdateListDP) {
|
|
2112
|
+
this.adapterUpdatesJsonRaw.clear();
|
|
1916
2113
|
const adapterUpdatesListVal = await this.getForeignStatesAsync(adapterUpdateListDP);
|
|
1917
2114
|
|
|
1918
|
-
// subscribe to datapoint
|
|
1919
|
-
this.subscribeForeignStates(adapterUpdateListDP);
|
|
1920
2115
|
let adapterJsonList;
|
|
2116
|
+
let adapterUpdatesJsonPath;
|
|
1921
2117
|
|
|
1922
2118
|
for (const [id] of Object.entries(adapterUpdatesListVal)) {
|
|
1923
|
-
adapterJsonList =
|
|
2119
|
+
adapterJsonList = this.parseData(adapterUpdatesListVal[id].val);
|
|
2120
|
+
adapterUpdatesJsonPath = id;
|
|
1924
2121
|
}
|
|
1925
2122
|
|
|
1926
2123
|
for (const [id] of Object.entries(adapterJsonList)) {
|
|
1927
|
-
this.adapterUpdatesJsonRaw.
|
|
1928
|
-
Path:
|
|
1929
|
-
Adapter: this.capitalize(id),
|
|
2124
|
+
this.adapterUpdatesJsonRaw.set(this.capitalize(id), {
|
|
2125
|
+
Path: adapterUpdatesJsonPath,
|
|
1930
2126
|
newVersion: adapterJsonList[id].availableVersion,
|
|
1931
2127
|
oldVersion: adapterJsonList[id].installedVersion,
|
|
1932
2128
|
});
|
|
1933
2129
|
}
|
|
1934
|
-
|
|
2130
|
+
return this.adapterUpdatesJsonRaw;
|
|
1935
2131
|
}
|
|
1936
2132
|
|
|
1937
2133
|
/**
|
|
@@ -1941,11 +2137,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1941
2137
|
this.listAdapterUpdates = [];
|
|
1942
2138
|
this.countAdapterUpdates = 0;
|
|
1943
2139
|
|
|
1944
|
-
for (const adapter of this.adapterUpdatesJsonRaw) {
|
|
2140
|
+
for (const [adapter, updateData] of this.adapterUpdatesJsonRaw) {
|
|
1945
2141
|
this.listAdapterUpdates.push({
|
|
1946
|
-
Adapter: adapter
|
|
1947
|
-
'Available Version':
|
|
1948
|
-
'Installed Version':
|
|
2142
|
+
Adapter: adapter,
|
|
2143
|
+
'Available Version': updateData.newVersion,
|
|
2144
|
+
'Installed Version': updateData.oldVersion,
|
|
1949
2145
|
});
|
|
1950
2146
|
}
|
|
1951
2147
|
this.countAdapterUpdates = this.listAdapterUpdates.length;
|
|
@@ -1957,13 +2153,13 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1957
2153
|
*/
|
|
1958
2154
|
async writeAdapterUpdatesDPs() {
|
|
1959
2155
|
// Write Datapoints for counts
|
|
1960
|
-
await this.
|
|
2156
|
+
await this.setStateChangedAsync(`adapterAndInstances.countAdapterUpdates`, { val: this.countAdapterUpdates, ack: true });
|
|
1961
2157
|
|
|
1962
2158
|
// list deactivated instances
|
|
1963
2159
|
if (this.countAdapterUpdates === 0) {
|
|
1964
2160
|
this.listAdapterUpdates = [{ Adapter: '--none--', 'Available Version': '', 'Installed Version': '' }];
|
|
1965
2161
|
}
|
|
1966
|
-
await this.
|
|
2162
|
+
await this.setStateChangedAsync(`adapterAndInstances.listAdapterUpdates`, { val: JSON.stringify(this.listAdapterUpdates), ack: true });
|
|
1967
2163
|
}
|
|
1968
2164
|
|
|
1969
2165
|
/**
|
|
@@ -1975,7 +2171,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1975
2171
|
this.listErrorInstanceRaw = [];
|
|
1976
2172
|
this.listErrorInstance = [];
|
|
1977
2173
|
|
|
1978
|
-
for (const instance of this.listInstanceRaw) {
|
|
2174
|
+
for (const instance of this.listInstanceRaw.values()) {
|
|
1979
2175
|
// fill raw list
|
|
1980
2176
|
if (instance.isAlive && !instance.isHealthy) {
|
|
1981
2177
|
this.listErrorInstanceRaw.push({
|
|
@@ -1993,6 +2189,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
1993
2189
|
Mode: instance.instanceMode,
|
|
1994
2190
|
Schedule: instance.schedule,
|
|
1995
2191
|
Version: instance.adapterVersion,
|
|
2192
|
+
Updateable: instance.updateAvailable,
|
|
1996
2193
|
Status: instance.status,
|
|
1997
2194
|
});
|
|
1998
2195
|
if (!instance.isAlive) {
|
|
@@ -2034,25 +2231,25 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2034
2231
|
*/
|
|
2035
2232
|
async writeInstanceDPs() {
|
|
2036
2233
|
// Write Datapoints for counts
|
|
2037
|
-
await this.
|
|
2038
|
-
await this.
|
|
2234
|
+
await this.setStateChangedAsync(`adapterAndInstances.countAllInstances`, { val: this.countAllInstances, ack: true });
|
|
2235
|
+
await this.setStateChangedAsync(`adapterAndInstances.countDeactivatedInstances`, { val: this.countDeactivatedInstances, ack: true });
|
|
2039
2236
|
|
|
2040
2237
|
// List all instances
|
|
2041
|
-
await this.
|
|
2238
|
+
await this.setStateChangedAsync(`adapterAndInstances.listAllInstances`, { val: JSON.stringify(this.listAllInstances), ack: true });
|
|
2042
2239
|
|
|
2043
2240
|
// list deactivated instances
|
|
2044
2241
|
if (this.countDeactivatedInstances === 0) {
|
|
2045
2242
|
this.listDeactivatedInstances = [{ Instance: '--none--', Version: '', Status: '' }];
|
|
2046
2243
|
}
|
|
2047
|
-
await this.
|
|
2048
|
-
await this.
|
|
2244
|
+
await this.setStateChangedAsync(`adapterAndInstances.listDeactivatedInstances`, { val: JSON.stringify(this.listDeactivatedInstances), ack: true });
|
|
2245
|
+
await this.setStateChangedAsync(`adapterAndInstances.countDeactivatedInstances`, { val: this.countDeactivatedInstances, ack: true });
|
|
2049
2246
|
|
|
2050
2247
|
// list error instances
|
|
2051
2248
|
if (this.countErrorInstance === 0) {
|
|
2052
2249
|
this.listErrorInstance = [{ Instance: '--none--', Mode: '', Status: '' }];
|
|
2053
2250
|
}
|
|
2054
|
-
await this.
|
|
2055
|
-
await this.
|
|
2251
|
+
await this.setStateChangedAsync(`adapterAndInstances.listInstancesError`, { val: JSON.stringify(this.listErrorInstance), ack: true });
|
|
2252
|
+
await this.setStateChangedAsync(`adapterAndInstances.countInstancesError`, { val: this.countErrorInstance, ack: true });
|
|
2056
2253
|
}
|
|
2057
2254
|
|
|
2058
2255
|
/**
|
|
@@ -2268,6 +2465,21 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2268
2465
|
});
|
|
2269
2466
|
}
|
|
2270
2467
|
|
|
2468
|
+
/**
|
|
2469
|
+
* delete Datapoints for Instances
|
|
2470
|
+
*/
|
|
2471
|
+
async deleteDPsForInstances() {
|
|
2472
|
+
await this.delObjectAsync(`adapterAndInstances`);
|
|
2473
|
+
await this.delObjectAsync(`adapterAndInstances.listAllInstances`);
|
|
2474
|
+
await this.delObjectAsync(`adapterAndInstances.countAllInstances`);
|
|
2475
|
+
await this.delObjectAsync(`adapterAndInstances.listDeactivatedInstances`);
|
|
2476
|
+
await this.delObjectAsync(`adapterAndInstances.countDeactivatedInstances`);
|
|
2477
|
+
await this.delObjectAsync(`adapterAndInstances.listInstancesError`);
|
|
2478
|
+
await this.delObjectAsync(`adapterAndInstances.countInstancesError`);
|
|
2479
|
+
await this.delObjectAsync(`adapterAndInstances.listAdapterUpdates`);
|
|
2480
|
+
await this.delObjectAsync(`adapterAndInstances.countAdapterUpdates`);
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2271
2483
|
/*=============================================
|
|
2272
2484
|
= functions to send notifications =
|
|
2273
2485
|
=============================================*/
|
|
@@ -2337,6 +2549,25 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2337
2549
|
this.errorReporting('[sendNotification Whatsapp]', error);
|
|
2338
2550
|
}
|
|
2339
2551
|
|
|
2552
|
+
// Signal
|
|
2553
|
+
try {
|
|
2554
|
+
if (this.config.instanceSignal) {
|
|
2555
|
+
//first check if instance is living
|
|
2556
|
+
const signalAliveState = await this.getInitValue('system.adapter.' + this.config.instanceSignal + '.alive');
|
|
2557
|
+
|
|
2558
|
+
if (!signalAliveState) {
|
|
2559
|
+
this.log.warn('Signal instance is not running. Message could not be sent. Please check your instance configuration.');
|
|
2560
|
+
} else {
|
|
2561
|
+
await this.sendToAsync(this.config.instanceSignal, 'send', {
|
|
2562
|
+
text: text,
|
|
2563
|
+
phone: this.config.phoneSignal,
|
|
2564
|
+
});
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
} catch (error) {
|
|
2568
|
+
this.errorReporting('[sendNotification Signal]', error);
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2340
2571
|
// Email
|
|
2341
2572
|
try {
|
|
2342
2573
|
if (this.config.instanceEmail) {
|
|
@@ -2418,539 +2649,378 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
2418
2649
|
}
|
|
2419
2650
|
} // <-- End of sendNotification function
|
|
2420
2651
|
|
|
2421
|
-
/*----------
|
|
2652
|
+
/*---------- Notifications ----------*/
|
|
2422
2653
|
/**
|
|
2423
|
-
*
|
|
2654
|
+
* Notifications on state changes
|
|
2655
|
+
* @param {string} type
|
|
2656
|
+
* @param {object} id
|
|
2424
2657
|
*/
|
|
2425
|
-
async
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
if (!this.blacklistNotify.includes(id.Path)) {
|
|
2455
|
-
if (!this.config.showAdapterNameinMsg) {
|
|
2456
|
-
deviceList = `${deviceList}\n${id.Device} (${id.Battery})`;
|
|
2457
|
-
} else {
|
|
2458
|
-
// Add adaptername if checkbox is checked true in options by user
|
|
2459
|
-
deviceList = `${deviceList}\n${id.Adapter}: ${id.Device} (${id.Battery})`;
|
|
2460
|
-
}
|
|
2658
|
+
async sendStateNotifications(type, id) {
|
|
2659
|
+
if (isUnloaded) return;
|
|
2660
|
+
let objectData;
|
|
2661
|
+
let list = '';
|
|
2662
|
+
let message = '';
|
|
2663
|
+
const setMessage = async (message) => {
|
|
2664
|
+
this.log.info(`${message}`);
|
|
2665
|
+
await this.setStateAsync('lastNotification', `${message}`, true);
|
|
2666
|
+
await this.sendNotification(`${message}`);
|
|
2667
|
+
return (message = '');
|
|
2668
|
+
};
|
|
2669
|
+
switch (type) {
|
|
2670
|
+
case 'lowBatDevice':
|
|
2671
|
+
objectData = this.listAllDevicesRaw.get(id);
|
|
2672
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2673
|
+
message = `Gerät mit geringer Batterie erkannt: \n${objectData.Device} (${objectData.Battery})`;
|
|
2674
|
+
} else {
|
|
2675
|
+
message = `Gerät mit geringer Batterie erkannt: \n${objectData.Adapter}: ${objectData.Device} (${objectData.Battery})`;
|
|
2676
|
+
}
|
|
2677
|
+
setMessage(message);
|
|
2678
|
+
break;
|
|
2679
|
+
case 'onlineStateDevice':
|
|
2680
|
+
objectData = this.listAllDevicesRaw.get(id);
|
|
2681
|
+
switch (objectData.Status) {
|
|
2682
|
+
case 'Online':
|
|
2683
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2684
|
+
message = `Folgendes Gerät ist wieder erreichbar: \n${objectData.Device} (${objectData.LastContact})`;
|
|
2685
|
+
} else {
|
|
2686
|
+
message = `Folgendes Gerät ist wieder erreichbar: \n${objectData.Adapter}: ${objectData.Device} (${objectData.LastContact})`;
|
|
2461
2687
|
}
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
this.
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
this.errorReporting('[sendBatteryNotifyShedule]', error);
|
|
2688
|
+
break;
|
|
2689
|
+
case 'Offline':
|
|
2690
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2691
|
+
message = `Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n${objectData.Device} (${objectData.LastContact})`;
|
|
2692
|
+
} else {
|
|
2693
|
+
message = `Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n${objectData.Adapter}: ${objectData.Device} (${objectData.LastContact})`;
|
|
2694
|
+
}
|
|
2695
|
+
break;
|
|
2471
2696
|
}
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
await this.sendNotification(msg + deviceList);
|
|
2499
|
-
} catch (error) {
|
|
2500
|
-
this.errorReporting('[sendLowBatNoticiation]', error);
|
|
2697
|
+
setMessage(message);
|
|
2698
|
+
break;
|
|
2699
|
+
case 'updateDevice':
|
|
2700
|
+
objectData = this.listAllDevicesRaw.get(id);
|
|
2701
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2702
|
+
message = `Neue Geräte Updates vorhanden: \n${objectData.Device}`;
|
|
2703
|
+
} else {
|
|
2704
|
+
message = `Neue Geräte Updates vorhanden: \n${objectData.Adapter}: ${objectData.Device}`;
|
|
2705
|
+
}
|
|
2706
|
+
setMessage(message);
|
|
2707
|
+
break;
|
|
2708
|
+
case 'updateAdapter':
|
|
2709
|
+
if (this.countAdapterUpdates === 0) return;
|
|
2710
|
+
objectData = this.listAdapterUpdates;
|
|
2711
|
+
list = '';
|
|
2712
|
+
for (const id of objectData) {
|
|
2713
|
+
list = `${list}\n${id.Adapter}: v${id['Available Version']}`;
|
|
2714
|
+
}
|
|
2715
|
+
message = `Neue Adapter Updates vorhanden: ${list}`;
|
|
2716
|
+
setMessage(message);
|
|
2717
|
+
break;
|
|
2718
|
+
case 'errorInstance':
|
|
2719
|
+
objectData = this.listInstanceRaw.get(id);
|
|
2720
|
+
message = `Instanz Watchdog:\n${objectData.InstanceName}: ${objectData.status}`;
|
|
2721
|
+
setMessage(message);
|
|
2722
|
+
break;
|
|
2501
2723
|
}
|
|
2502
|
-
this.log.debug(`Finished the function: ${this.sendLowBatNoticiation.name}`);
|
|
2503
2724
|
}
|
|
2504
2725
|
|
|
2505
|
-
/*---------- Offline/Online notifications ----------*/
|
|
2506
|
-
/**
|
|
2507
|
-
* send message if an device is offline
|
|
2508
|
-
* @param {string} deviceName
|
|
2509
|
-
* @param {string} adapter
|
|
2510
|
-
* @param {string} status
|
|
2511
|
-
* @param {string} lastContact
|
|
2512
|
-
*/
|
|
2513
|
-
async sendOfflineNotifications(deviceName, adapter, status, lastContact) {
|
|
2514
|
-
this.log.debug(`Start the function: ${this.sendOfflineNotifications.name}`);
|
|
2515
|
-
|
|
2516
|
-
try {
|
|
2517
|
-
let msg = '';
|
|
2518
|
-
let deviceList = '';
|
|
2519
|
-
|
|
2520
|
-
if (!this.config.showAdapterNameinMsg) {
|
|
2521
|
-
deviceList = `${deviceList}\n${deviceName} (${lastContact})`;
|
|
2522
|
-
} else {
|
|
2523
|
-
deviceList = `${deviceList}\n${adapter}: ${deviceName} (${lastContact})`;
|
|
2524
|
-
}
|
|
2525
|
-
|
|
2526
|
-
if (status === 'Online') {
|
|
2527
|
-
// make singular if it is only one device
|
|
2528
|
-
msg = 'Folgendes Gerät ist wieder erreichbar: \n';
|
|
2529
|
-
} else if (status === 'Offline') {
|
|
2530
|
-
//make plural if it is more than one device
|
|
2531
|
-
msg = `Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n`;
|
|
2532
|
-
}
|
|
2533
|
-
|
|
2534
|
-
this.log.info(msg + deviceList);
|
|
2535
|
-
await this.setStateAsync('lastNotification', msg + deviceList, true);
|
|
2536
|
-
await this.sendNotification(msg + deviceList);
|
|
2537
|
-
} catch (error) {
|
|
2538
|
-
this.errorReporting('[sendOfflineMessage]', error);
|
|
2539
|
-
}
|
|
2540
|
-
this.log.debug(`Finished the function: ${this.sendOfflineNotifications.name}`);
|
|
2541
|
-
} //<--End of offline notification
|
|
2542
|
-
|
|
2543
2726
|
/**
|
|
2544
|
-
*
|
|
2727
|
+
* Notifications per user defined schedule
|
|
2728
|
+
* @param {string} type
|
|
2545
2729
|
*/
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2730
|
+
sendScheduleNotifications(type) {
|
|
2731
|
+
if (isUnloaded) return;
|
|
2732
|
+
|
|
2733
|
+
let time;
|
|
2734
|
+
let cron;
|
|
2735
|
+
let list = '';
|
|
2736
|
+
let message = '';
|
|
2737
|
+
const checkDays = [];
|
|
2738
|
+
const setMessage = async (message) => {
|
|
2739
|
+
this.log.info(`${message}`);
|
|
2740
|
+
await this.setStateAsync('lastNotification', `${message}`, true);
|
|
2741
|
+
await this.sendNotification(`${message}`);
|
|
2742
|
+
return (message = '');
|
|
2743
|
+
};
|
|
2744
|
+
|
|
2745
|
+
switch (type) {
|
|
2746
|
+
case 'lowBatteryDevices':
|
|
2747
|
+
// push the selected days in list
|
|
2748
|
+
if (this.config.checkMonday) checkDays.push(1);
|
|
2749
|
+
if (this.config.checkTuesday) checkDays.push(2);
|
|
2750
|
+
if (this.config.checkWednesday) checkDays.push(3);
|
|
2751
|
+
if (this.config.checkThursday) checkDays.push(4);
|
|
2752
|
+
if (this.config.checkFriday) checkDays.push(5);
|
|
2753
|
+
if (this.config.checkSaturday) checkDays.push(6);
|
|
2754
|
+
if (this.config.checkSunday) checkDays.push(0);
|
|
2755
|
+
|
|
2756
|
+
time = this.config.checkSendBatteryTime.split(':');
|
|
2757
|
+
|
|
2758
|
+
if (checkDays.length === 0) {
|
|
2759
|
+
this.log.warn(`No days selected for daily low battery devices message. Please check the instance configuration!`);
|
|
2760
|
+
return; // cancel function if no day is selected
|
|
2761
|
+
}
|
|
2762
|
+
this.log.debug(`Number of selected days for daily low battery devices message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2573
2763
|
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
}
|
|
2764
|
+
cron = '1 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2765
|
+
schedule.scheduleJob(cron, () => {
|
|
2766
|
+
list = '';
|
|
2767
|
+
for (const id of this.batteryLowPoweredRaw) {
|
|
2768
|
+
if (this.blacklistNotify.includes(id.Path)) continue;
|
|
2769
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2770
|
+
list = `${list}\n${id.Device} (${id.Battery})`;
|
|
2771
|
+
} else {
|
|
2772
|
+
// Add adaptername if checkbox is checked true in options by user
|
|
2773
|
+
list = `${list}\n${id.Adapter}: ${id.Device} (${id.Battery})`;
|
|
2581
2774
|
}
|
|
2582
2775
|
}
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2776
|
+
if (list.length === 0) return;
|
|
2777
|
+
message = `Tägliche Meldung über Geräte mit niedrigen Batteriezuständen: ${list}`;
|
|
2778
|
+
setMessage(message);
|
|
2779
|
+
});
|
|
2780
|
+
break;
|
|
2781
|
+
case 'offlineDevices':
|
|
2782
|
+
// push the selected days in list
|
|
2783
|
+
if (this.config.checkOfflineMonday) checkDays.push(1);
|
|
2784
|
+
if (this.config.checkOfflineTuesday) checkDays.push(2);
|
|
2785
|
+
if (this.config.checkOfflineWednesday) checkDays.push(3);
|
|
2786
|
+
if (this.config.checkOfflineThursday) checkDays.push(4);
|
|
2787
|
+
if (this.config.checkOfflineFriday) checkDays.push(5);
|
|
2788
|
+
if (this.config.checkOfflineSaturday) checkDays.push(6);
|
|
2789
|
+
if (this.config.checkOfflineSunday) checkDays.push(0);
|
|
2790
|
+
|
|
2791
|
+
time = this.config.checkSendOfflineTime.split(':');
|
|
2792
|
+
|
|
2793
|
+
if (checkDays.length === 0) {
|
|
2794
|
+
this.log.warn(`No days selected for daily offline devices message. Please check the instance configuration!`);
|
|
2795
|
+
return; // cancel function if no day is selected
|
|
2592
2796
|
}
|
|
2593
|
-
|
|
2594
|
-
}
|
|
2595
|
-
} //<--End of daily offline notification
|
|
2596
|
-
|
|
2597
|
-
/*---------- Device Updates notifications ----------*/
|
|
2598
|
-
/**
|
|
2599
|
-
* check if device updates are available and send notification
|
|
2600
|
-
* @param {string} deviceName
|
|
2601
|
-
* @param {string} adapter
|
|
2602
|
-
**/
|
|
2603
|
-
async sendDeviceUpdatesNotification(deviceName, adapter) {
|
|
2604
|
-
this.log.debug(`Start the function: ${this.sendDeviceUpdatesNotification.name}`);
|
|
2797
|
+
this.log.debug(`Number of selected days for daily offline devices message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2605
2798
|
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
if (!this.config.showAdapterNameinMsg) {
|
|
2611
|
-
deviceList = `${deviceList}\n${deviceName}`;
|
|
2612
|
-
} else {
|
|
2613
|
-
deviceList = `${deviceList}\n${adapter}: ${deviceName}`;
|
|
2614
|
-
}
|
|
2615
|
-
|
|
2616
|
-
msg = `Neue Geräte Updates vorhanden: \n`;
|
|
2617
|
-
|
|
2618
|
-
this.log.info(msg + deviceList);
|
|
2619
|
-
await this.setStateAsync('lastNotification', msg + deviceList, true);
|
|
2620
|
-
await this.sendNotification(msg + deviceList);
|
|
2621
|
-
} catch (error) {
|
|
2622
|
-
this.errorReporting('[sendDeviceUpdatesNotification]', error);
|
|
2623
|
-
}
|
|
2624
|
-
this.log.debug(`Finished the function: ${this.sendDeviceUpdatesNotification.name}`);
|
|
2625
|
-
}
|
|
2626
|
-
|
|
2627
|
-
/**
|
|
2628
|
-
* send shedule message with offline devices
|
|
2629
|
-
*/
|
|
2630
|
-
async sendDeviceUpdateNotificationsShedule() {
|
|
2631
|
-
const time = this.config.checkSendUpgradeTime.split(':');
|
|
2632
|
-
|
|
2633
|
-
const checkDays = []; // list of selected days
|
|
2634
|
-
|
|
2635
|
-
// push the selected days in list
|
|
2636
|
-
if (this.config.checkUpgradeMonday) checkDays.push(1);
|
|
2637
|
-
if (this.config.checkUpgradeTuesday) checkDays.push(2);
|
|
2638
|
-
if (this.config.checkUpgradeWednesday) checkDays.push(3);
|
|
2639
|
-
if (this.config.checkUpgradeThursday) checkDays.push(4);
|
|
2640
|
-
if (this.config.checkUpgradeFriday) checkDays.push(5);
|
|
2641
|
-
if (this.config.checkUpgradeSaturday) checkDays.push(6);
|
|
2642
|
-
if (this.config.checkUpgradeSunday) checkDays.push(0);
|
|
2643
|
-
|
|
2644
|
-
if (checkDays.length >= 1) {
|
|
2645
|
-
// check if an day is selected
|
|
2646
|
-
this.log.debug(`Number of selected days for daily Upgrade message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2647
|
-
} else {
|
|
2648
|
-
this.log.warn(`No days selected for daily Upgrade message. Please check the instance configuration!`);
|
|
2649
|
-
return; // cancel function if no day is selected
|
|
2650
|
-
}
|
|
2651
|
-
|
|
2652
|
-
if (!isUnloaded) {
|
|
2653
|
-
const cron = '10 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2654
|
-
schedule.scheduleJob(cron, () => {
|
|
2655
|
-
try {
|
|
2656
|
-
let deviceList = '';
|
|
2799
|
+
cron = '2 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2800
|
+
schedule.scheduleJob(cron, () => {
|
|
2801
|
+
list = '';
|
|
2657
2802
|
|
|
2658
|
-
for (const id of this.
|
|
2659
|
-
if (
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
}
|
|
2803
|
+
for (const id of this.offlineDevicesRaw) {
|
|
2804
|
+
if (this.blacklistNotify.includes(id.Path)) continue;
|
|
2805
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2806
|
+
list = `${list}\n${id.Device} (${id.LastContact})`;
|
|
2807
|
+
} else {
|
|
2808
|
+
list = `${list}\n${id.Adapter}: ${id.Device} (${id.LastContact})`;
|
|
2665
2809
|
}
|
|
2666
2810
|
}
|
|
2667
|
-
if (deviceList.length > 0) {
|
|
2668
|
-
this.log.info(`Geräte Upgrade: ${deviceList}`);
|
|
2669
|
-
this.setStateAsync('lastNotification', `Geräte Upgrade: ${deviceList}`, true);
|
|
2670
|
-
|
|
2671
|
-
this.sendNotification(`Geräte Upgrade:\n${deviceList}`);
|
|
2672
|
-
}
|
|
2673
|
-
} catch (error) {
|
|
2674
|
-
this.errorReporting('[sendUpgradeNotificationsShedule]', error);
|
|
2675
|
-
}
|
|
2676
|
-
});
|
|
2677
|
-
}
|
|
2678
|
-
} //<--End of daily device updates notification
|
|
2679
|
-
|
|
2680
|
-
/*---------- Adapter Updates notifications ----------*/
|
|
2681
|
-
/**
|
|
2682
|
-
* check if adapter updates are available and send notification
|
|
2683
|
-
* @param {string} id
|
|
2684
|
-
* @param {ioBroker.State | null | undefined} state
|
|
2685
|
-
*/
|
|
2686
|
-
async sendAdapterUpdatesNotification(id, state) {
|
|
2687
|
-
this.log.debug(`Start the function: ${this.sendAdapterUpdatesNotification.name}`);
|
|
2688
2811
|
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
if (
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2812
|
+
if (list.length === 0) return;
|
|
2813
|
+
message = `Tägliche Meldung über offline Geräte: ${list}`;
|
|
2814
|
+
setMessage(message);
|
|
2815
|
+
});
|
|
2816
|
+
break;
|
|
2817
|
+
case 'updateDevices':
|
|
2818
|
+
// push the selected days in list
|
|
2819
|
+
if (this.config.checkUpgradeMonday) checkDays.push(1);
|
|
2820
|
+
if (this.config.checkUpgradeTuesday) checkDays.push(2);
|
|
2821
|
+
if (this.config.checkUpgradeWednesday) checkDays.push(3);
|
|
2822
|
+
if (this.config.checkUpgradeThursday) checkDays.push(4);
|
|
2823
|
+
if (this.config.checkUpgradeFriday) checkDays.push(5);
|
|
2824
|
+
if (this.config.checkUpgradeSaturday) checkDays.push(6);
|
|
2825
|
+
if (this.config.checkUpgradeSunday) checkDays.push(0);
|
|
2826
|
+
|
|
2827
|
+
time = this.config.checkSendUpgradeTime.split(':');
|
|
2828
|
+
|
|
2829
|
+
if (checkDays.length === 0) {
|
|
2830
|
+
this.log.warn(`No days selected for daily updatable devices message. Please check the instance configuration!`);
|
|
2831
|
+
return; // cancel function if no day is selected
|
|
2704
2832
|
}
|
|
2705
|
-
|
|
2706
|
-
} catch (error) {
|
|
2707
|
-
this.errorReporting('[sendAdapterUpdatesNotification]', error);
|
|
2708
|
-
}
|
|
2709
|
-
this.log.debug(`Finished the function: ${this.sendAdapterUpdatesNotification.name}`);
|
|
2710
|
-
}
|
|
2711
|
-
|
|
2712
|
-
/**
|
|
2713
|
-
* send shedule message with list of updatable adapters
|
|
2714
|
-
*/
|
|
2715
|
-
async sendAdapterUpdatesNotificatioShedule() {
|
|
2716
|
-
const time = this.config.checkSendAdapterUpdateTime.split(':');
|
|
2717
|
-
|
|
2718
|
-
const checkDays = []; // list of selected days
|
|
2719
|
-
|
|
2720
|
-
// push the selected days in list
|
|
2721
|
-
if (this.config.checkAdapterUpdateMonday) checkDays.push(1);
|
|
2722
|
-
if (this.config.checkAdapterUpdateTuesday) checkDays.push(2);
|
|
2723
|
-
if (this.config.checkAdapterUpdateWednesday) checkDays.push(3);
|
|
2724
|
-
if (this.config.checkAdapterUpdateThursday) checkDays.push(4);
|
|
2725
|
-
if (this.config.checkAdapterUpdateFriday) checkDays.push(5);
|
|
2726
|
-
if (this.config.checkAdapterUpdateSaturday) checkDays.push(6);
|
|
2727
|
-
if (this.config.checkAdapterUpdateSunday) checkDays.push(0);
|
|
2728
|
-
|
|
2729
|
-
if (checkDays.length >= 1) {
|
|
2730
|
-
// check if an day is selected
|
|
2731
|
-
this.log.debug(`Number of selected days for daily adapter update message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2732
|
-
} else {
|
|
2733
|
-
this.log.warn(`No days selected for daily adapter update message. Please check the instance configuration!`);
|
|
2734
|
-
return; // cancel function if no day is selected
|
|
2735
|
-
}
|
|
2833
|
+
this.log.debug(`Number of selected days for daily updatable devices message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2736
2834
|
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
try {
|
|
2741
|
-
let deviceList = '';
|
|
2835
|
+
cron = '3 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2836
|
+
schedule.scheduleJob(cron, () => {
|
|
2837
|
+
list = '';
|
|
2742
2838
|
|
|
2743
2839
|
for (const id of this.upgradableDevicesRaw) {
|
|
2744
|
-
if (
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
}
|
|
2840
|
+
if (this.blacklistNotify.includes(id.Path)) continue;
|
|
2841
|
+
if (!this.config.showAdapterNameinMsg) {
|
|
2842
|
+
list = `${list}\n${id.Device}`;
|
|
2843
|
+
} else {
|
|
2844
|
+
list = `${list}\n${id.Adapter}: ${id.Device}`;
|
|
2750
2845
|
}
|
|
2751
2846
|
}
|
|
2752
|
-
if (
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2847
|
+
if (list.length === 0) return;
|
|
2848
|
+
message = `Tägliche Meldung über verfügbare Geräte Updates: ${list}`;
|
|
2849
|
+
setMessage(message);
|
|
2850
|
+
});
|
|
2851
|
+
break;
|
|
2852
|
+
case 'updateAdapter':
|
|
2853
|
+
// push the selected days in list
|
|
2854
|
+
if (this.config.checkAdapterUpdateMonday) checkDays.push(1);
|
|
2855
|
+
if (this.config.checkAdapterUpdateTuesday) checkDays.push(2);
|
|
2856
|
+
if (this.config.checkAdapterUpdateWednesday) checkDays.push(3);
|
|
2857
|
+
if (this.config.checkAdapterUpdateThursday) checkDays.push(4);
|
|
2858
|
+
if (this.config.checkAdapterUpdateFriday) checkDays.push(5);
|
|
2859
|
+
if (this.config.checkAdapterUpdateSaturday) checkDays.push(6);
|
|
2860
|
+
if (this.config.checkAdapterUpdateSunday) checkDays.push(0);
|
|
2861
|
+
|
|
2862
|
+
time = this.config.checkSendAdapterUpdateTime.split(':');
|
|
2863
|
+
|
|
2864
|
+
if (checkDays.length === 0) {
|
|
2865
|
+
this.log.warn(`No days selected for daily adapter update message. Please check the instance configuration!`);
|
|
2866
|
+
return; // cancel function if no day is selected
|
|
2760
2867
|
}
|
|
2761
|
-
|
|
2762
|
-
}
|
|
2763
|
-
} //<--End of daily offline notification
|
|
2764
|
-
|
|
2765
|
-
/*---------- Instance error notifications ----------*/
|
|
2766
|
-
/**
|
|
2767
|
-
* check if device updates are available and send notification
|
|
2768
|
-
* @param {string} instanceName
|
|
2769
|
-
* @param {string} error
|
|
2770
|
-
**/
|
|
2771
|
-
async sendInstanceErrorNotification(instanceName, error) {
|
|
2772
|
-
this.log.debug(`Start the function: ${this.sendInstanceErrorNotification.name}`);
|
|
2773
|
-
|
|
2774
|
-
try {
|
|
2775
|
-
let msg = '';
|
|
2776
|
-
let instanceList = '';
|
|
2777
|
-
|
|
2778
|
-
instanceList = `${instanceList}\n${instanceName}: ${error}`;
|
|
2868
|
+
this.log.debug(`Number of selected days for daily adapter update message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2779
2869
|
|
|
2780
|
-
|
|
2870
|
+
cron = '4 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2871
|
+
schedule.scheduleJob(cron, () => {
|
|
2872
|
+
list = '';
|
|
2781
2873
|
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
await this.sendNotification(msg + instanceList);
|
|
2785
|
-
} catch (error) {
|
|
2786
|
-
this.errorReporting('[sendInstanceErrorNotification]', error);
|
|
2787
|
-
}
|
|
2788
|
-
this.log.debug(`Finished the function: ${this.sendInstanceErrorNotification.name}`);
|
|
2789
|
-
}
|
|
2790
|
-
|
|
2791
|
-
/**
|
|
2792
|
-
* send shedule message with offline devices
|
|
2793
|
-
*/
|
|
2794
|
-
async sendInstanceErrorNotificationShedule() {
|
|
2795
|
-
const time = this.config.checkSendInstanceFailedTime.split(':');
|
|
2796
|
-
|
|
2797
|
-
const checkDays = []; // list of selected days
|
|
2798
|
-
|
|
2799
|
-
// push the selected days in list
|
|
2800
|
-
if (this.config.checkFailedInstancesMonday) checkDays.push(1);
|
|
2801
|
-
if (this.config.checkFailedInstancesTuesday) checkDays.push(2);
|
|
2802
|
-
if (this.config.checkFailedInstancesWednesday) checkDays.push(3);
|
|
2803
|
-
if (this.config.checkFailedInstancesThursday) checkDays.push(4);
|
|
2804
|
-
if (this.config.checkFailedInstancesFriday) checkDays.push(5);
|
|
2805
|
-
if (this.config.checkFailedInstancesSaturday) checkDays.push(6);
|
|
2806
|
-
if (this.config.checkFailedInstancesSunday) checkDays.push(0);
|
|
2807
|
-
|
|
2808
|
-
if (checkDays.length >= 1) {
|
|
2809
|
-
// check if an day is selected
|
|
2810
|
-
this.log.debug(`Number of selected days for daily instance error message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2811
|
-
} else {
|
|
2812
|
-
this.log.warn(`No days selected for daily instance error message. Please check the instance configuration!`);
|
|
2813
|
-
return; // cancel function if no day is selected
|
|
2814
|
-
}
|
|
2815
|
-
|
|
2816
|
-
if (!isUnloaded) {
|
|
2817
|
-
const cron = '10 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2818
|
-
schedule.scheduleJob(cron, () => {
|
|
2819
|
-
try {
|
|
2820
|
-
let instanceList = '';
|
|
2821
|
-
|
|
2822
|
-
for (const id of this.listErrorInstanceRaw) {
|
|
2823
|
-
if (!this.blacklistInstancesNotify.includes(id.instanceAlivePath)) {
|
|
2824
|
-
instanceList = `${instanceList}\n${id.Instance}: ${id.Status}`;
|
|
2825
|
-
}
|
|
2874
|
+
for (const id of this.listAdapterUpdates) {
|
|
2875
|
+
list = `${list}\n${id.Adapter}: v${id['Available Version']}`;
|
|
2826
2876
|
}
|
|
2827
|
-
if (
|
|
2828
|
-
|
|
2829
|
-
|
|
2877
|
+
if (list.length === 0) return;
|
|
2878
|
+
message = `Tägliche Meldung über verfügbare Adapter Updates: ${list}`;
|
|
2879
|
+
setMessage(message);
|
|
2880
|
+
});
|
|
2881
|
+
break;
|
|
2882
|
+
case 'errorInstance':
|
|
2883
|
+
// push the selected days in list
|
|
2884
|
+
if (this.config.checkFailedInstancesMonday) checkDays.push(1);
|
|
2885
|
+
if (this.config.checkFailedInstancesTuesday) checkDays.push(2);
|
|
2886
|
+
if (this.config.checkFailedInstancesWednesday) checkDays.push(3);
|
|
2887
|
+
if (this.config.checkFailedInstancesThursday) checkDays.push(4);
|
|
2888
|
+
if (this.config.checkFailedInstancesFriday) checkDays.push(5);
|
|
2889
|
+
if (this.config.checkFailedInstancesSaturday) checkDays.push(6);
|
|
2890
|
+
if (this.config.checkFailedInstancesSunday) checkDays.push(0);
|
|
2891
|
+
|
|
2892
|
+
time = this.config.checkSendInstanceFailedTime.split(':');
|
|
2893
|
+
|
|
2894
|
+
if (checkDays.length === 0) {
|
|
2895
|
+
this.log.warn(`No days selected for daily instance error message. Please check the instance configuration!`);
|
|
2896
|
+
return; // cancel function if no day is selected
|
|
2897
|
+
}
|
|
2898
|
+
this.log.debug(`Number of selected days for daily instance error message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
|
|
2899
|
+
cron = '5 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
|
|
2900
|
+
schedule.scheduleJob(cron, () => {
|
|
2901
|
+
list = '';
|
|
2830
2902
|
|
|
2831
|
-
|
|
2903
|
+
for (const id of this.listErrorInstanceRaw) {
|
|
2904
|
+
if (this.blacklistInstancesNotify.includes(id.instanceAlivePath)) continue;
|
|
2905
|
+
list = `${list}\n${id.Instance}: ${id.Status}`;
|
|
2832
2906
|
}
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2907
|
+
if (list.length === 0) return;
|
|
2908
|
+
message = `Tägliche Meldung über fehlerhafte Instanzen: ${list}`;
|
|
2909
|
+
setMessage(message);
|
|
2910
|
+
});
|
|
2911
|
+
break;
|
|
2837
2912
|
}
|
|
2838
|
-
}
|
|
2913
|
+
}
|
|
2839
2914
|
|
|
2840
2915
|
/*=============================================
|
|
2841
2916
|
= functions to create html lists =
|
|
2842
2917
|
=============================================*/
|
|
2843
|
-
|
|
2844
2918
|
/**
|
|
2919
|
+
* @param {string} type - type of list
|
|
2845
2920
|
* @param {object} devices - Device
|
|
2846
2921
|
* @param {number} deviceCount - Counted devices
|
|
2922
|
+
* @param {object} isLowBatteryList - list Low Battery Devices
|
|
2847
2923
|
*/
|
|
2848
|
-
async
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
html += `<tr>
|
|
2870
|
-
<td><font>${device.Device}</font></td>
|
|
2871
|
-
<td align=center><font>${device.Adapter}</font></td>
|
|
2872
|
-
<td align=right><font>${device['Signal strength']}</font></td>
|
|
2924
|
+
async createListHTML(type, devices, deviceCount, isLowBatteryList) {
|
|
2925
|
+
let html;
|
|
2926
|
+
switch (type) {
|
|
2927
|
+
case 'linkQualityList':
|
|
2928
|
+
devices = devices.sort((a, b) => {
|
|
2929
|
+
a = a.Device || '';
|
|
2930
|
+
b = b.Device || '';
|
|
2931
|
+
return a.localeCompare(b);
|
|
2932
|
+
});
|
|
2933
|
+
html = `<center>
|
|
2934
|
+
<b>Link Quality Devices:<font> ${deviceCount}</b><small></small></font>
|
|
2935
|
+
<p></p>
|
|
2936
|
+
</center>
|
|
2937
|
+
<table width=100%>
|
|
2938
|
+
<tr>
|
|
2939
|
+
<th align=left>Device</th>
|
|
2940
|
+
<th align=center width=120>Adapter</th>
|
|
2941
|
+
<th align=right>Link Quality</th>
|
|
2942
|
+
</tr>
|
|
2943
|
+
<tr>
|
|
2944
|
+
<td colspan="5"><hr></td>
|
|
2873
2945
|
</tr>`;
|
|
2874
|
-
}
|
|
2875
2946
|
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2947
|
+
for (const device of devices) {
|
|
2948
|
+
html += `<tr>
|
|
2949
|
+
<td><font>${device.Device}</font></td>
|
|
2950
|
+
<td align=center><font>${device.Adapter}</font></td>
|
|
2951
|
+
<td align=right><font>${device['Signal strength']}</font></td>
|
|
2952
|
+
</tr>`;
|
|
2953
|
+
}
|
|
2879
2954
|
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
<td colspan="5"><hr></td>
|
|
2902
|
-
</tr>`;
|
|
2903
|
-
|
|
2904
|
-
for (const device of devices) {
|
|
2905
|
-
html += `<tr>
|
|
2906
|
-
<td><font>${device.Device}</font></td>
|
|
2907
|
-
<td align=center><font>${device.Adapter}</font></td>
|
|
2908
|
-
<td align=center><font color=orange>${device['Last contact']}</font></td>
|
|
2955
|
+
html += '</table>';
|
|
2956
|
+
break;
|
|
2957
|
+
|
|
2958
|
+
case 'offlineList':
|
|
2959
|
+
devices = devices.sort((a, b) => {
|
|
2960
|
+
a = a.Device || '';
|
|
2961
|
+
b = b.Device || '';
|
|
2962
|
+
return a.localeCompare(b);
|
|
2963
|
+
});
|
|
2964
|
+
html = `<center>
|
|
2965
|
+
<b>Offline Devices: <font color=${deviceCount === 0 ? '#3bcf0e' : 'orange'}>${deviceCount}</b><small></small></font>
|
|
2966
|
+
<p></p>
|
|
2967
|
+
</center>
|
|
2968
|
+
<table width=100%>
|
|
2969
|
+
<tr>
|
|
2970
|
+
<th align=left>Device</th>
|
|
2971
|
+
<th align=center width=120>Adapter</th>
|
|
2972
|
+
<th align=center>Letzter Kontakt</th>
|
|
2973
|
+
</tr>
|
|
2974
|
+
<tr>
|
|
2975
|
+
<td colspan="5"><hr></td>
|
|
2909
2976
|
</tr>`;
|
|
2910
|
-
}
|
|
2911
2977
|
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2978
|
+
for (const device of devices) {
|
|
2979
|
+
html += `<tr>
|
|
2980
|
+
<td><font>${device.Device}</font></td>
|
|
2981
|
+
<td align=center><font>${device.Adapter}</font></td>
|
|
2982
|
+
<td align=center><font color=orange>${device['Last contact']}</font></td>
|
|
2983
|
+
</tr>`;
|
|
2984
|
+
}
|
|
2915
2985
|
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
html += `</tr>`;
|
|
2951
|
-
}
|
|
2986
|
+
html += '</table>';
|
|
2987
|
+
break;
|
|
2988
|
+
|
|
2989
|
+
case 'batteryList':
|
|
2990
|
+
devices = devices.sort((a, b) => {
|
|
2991
|
+
a = a.Device || '';
|
|
2992
|
+
b = b.Device || '';
|
|
2993
|
+
return a.localeCompare(b);
|
|
2994
|
+
});
|
|
2995
|
+
html = `<center>
|
|
2996
|
+
<b>${isLowBatteryList === true ? 'Schwache ' : ''}Batterie Devices: <font color=${isLowBatteryList === true ? (deviceCount > 0 ? 'orange' : '#3bcf0e') : ''}>${deviceCount}</b></font>
|
|
2997
|
+
<p></p>
|
|
2998
|
+
</center>
|
|
2999
|
+
<table width=100%>
|
|
3000
|
+
<tr>
|
|
3001
|
+
<th align=left>Device</th>
|
|
3002
|
+
<th align=center width=120>Adapter</th>
|
|
3003
|
+
<th align=${isLowBatteryList ? 'center' : 'right'}>Batterie</th>
|
|
3004
|
+
</tr>
|
|
3005
|
+
<tr>
|
|
3006
|
+
<td colspan="5"><hr></td>
|
|
3007
|
+
</tr>`;
|
|
3008
|
+
for (const device of devices) {
|
|
3009
|
+
html += `<tr>
|
|
3010
|
+
<td><font>${device.Device}</font></td>
|
|
3011
|
+
<td align=center><font>${device.Adapter}</font></td>`;
|
|
3012
|
+
|
|
3013
|
+
if (isLowBatteryList) {
|
|
3014
|
+
html += `<td align=center><font color=orange>${device.Battery}</font></td>`;
|
|
3015
|
+
} else {
|
|
3016
|
+
html += `<td align=right><font color=#3bcf0e>${device.Battery}</font></td>`;
|
|
3017
|
+
}
|
|
3018
|
+
html += `</tr>`;
|
|
3019
|
+
}
|
|
2952
3020
|
|
|
2953
|
-
|
|
3021
|
+
html += '</table>';
|
|
3022
|
+
break;
|
|
3023
|
+
}
|
|
2954
3024
|
return html;
|
|
2955
3025
|
}
|
|
2956
3026
|
|
|
@@ -3041,6 +3111,30 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
3041
3111
|
native: {},
|
|
3042
3112
|
});
|
|
3043
3113
|
|
|
3114
|
+
await this.setObjectNotExistsAsync(`devices.${adptName}.listAllRawJSON`, {
|
|
3115
|
+
type: 'state',
|
|
3116
|
+
common: {
|
|
3117
|
+
name: {
|
|
3118
|
+
en: 'JSON RAW List of all devices',
|
|
3119
|
+
de: 'JSON RAW Liste aller Geräte',
|
|
3120
|
+
ru: 'ДЖСОН РАВ Список всех устройств',
|
|
3121
|
+
pt: 'JSON RAW Lista de todos os dispositivos',
|
|
3122
|
+
nl: 'JSON RAW List van alle apparaten',
|
|
3123
|
+
fr: 'JSON RAW Liste de tous les dispositifs',
|
|
3124
|
+
it: 'JSON RAW Elenco di tutti i dispositivi',
|
|
3125
|
+
es: 'JSON RAW Lista de todos los dispositivos',
|
|
3126
|
+
pl: 'JSON RAW Lista wszystkich urządzeń',
|
|
3127
|
+
uk: 'ДЖСОН РАВ Список всіх пристроїв',
|
|
3128
|
+
'zh-cn': 'JSONRAW 所有装置清单',
|
|
3129
|
+
},
|
|
3130
|
+
type: 'array',
|
|
3131
|
+
role: 'json',
|
|
3132
|
+
read: true,
|
|
3133
|
+
write: false,
|
|
3134
|
+
},
|
|
3135
|
+
native: {},
|
|
3136
|
+
});
|
|
3137
|
+
|
|
3044
3138
|
await this.setObjectNotExistsAsync(`devices.${adptName}.listAll`, {
|
|
3045
3139
|
type: 'state',
|
|
3046
3140
|
common: {
|
|
@@ -3302,6 +3396,30 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
3302
3396
|
}
|
|
3303
3397
|
|
|
3304
3398
|
/**
|
|
3399
|
+
* delete datapoints for each adapter
|
|
3400
|
+
* @param {object} adptName - Adaptername of devices
|
|
3401
|
+
*/
|
|
3402
|
+
async deleteDPsForEachAdapter(adptName) {
|
|
3403
|
+
await this.delObjectAsync(`devices.${adptName}`);
|
|
3404
|
+
await this.delObjectAsync(`devices.${adptName}.offlineCount`);
|
|
3405
|
+
await this.delObjectAsync(`devices.${adptName}.offlineList`);
|
|
3406
|
+
await this.delObjectAsync(`devices.${adptName}.oneDeviceOffline`);
|
|
3407
|
+
await this.delObjectAsync(`devices.${adptName}.listAllRawJSON`);
|
|
3408
|
+
await this.delObjectAsync(`devices.${adptName}.listAll`);
|
|
3409
|
+
await this.delObjectAsync(`devices.${adptName}.linkQualityList`);
|
|
3410
|
+
await this.delObjectAsync(`devices.${adptName}.countAll`);
|
|
3411
|
+
await this.delObjectAsync(`devices.${adptName}.batteryList`);
|
|
3412
|
+
await this.delObjectAsync(`devices.${adptName}.lowBatteryList`);
|
|
3413
|
+
await this.delObjectAsync(`devices.${adptName}.lowBatteryCount`);
|
|
3414
|
+
await this.delObjectAsync(`devices.${adptName}.oneDeviceLowBat`);
|
|
3415
|
+
await this.delObjectAsync(`devices.${adptName}.batteryCount`);
|
|
3416
|
+
await this.delObjectAsync(`devices.${adptName}.upgradableCount`);
|
|
3417
|
+
await this.delObjectAsync(`devices.${adptName}.upgradableList`);
|
|
3418
|
+
await this.delObjectAsync(`devices.${adptName}.oneDeviceUpdatable`);
|
|
3419
|
+
}
|
|
3420
|
+
|
|
3421
|
+
/**
|
|
3422
|
+
* create HTML list datapoints
|
|
3305
3423
|
* @param {object} [adptName] - Adaptername of devices
|
|
3306
3424
|
**/
|
|
3307
3425
|
async createHtmlListDatapoints(adptName) {
|
|
@@ -3406,6 +3524,25 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
3406
3524
|
});
|
|
3407
3525
|
}
|
|
3408
3526
|
|
|
3527
|
+
/**
|
|
3528
|
+
* delete html datapoints
|
|
3529
|
+
* @param {object} [adptName] - Adaptername of devices
|
|
3530
|
+
**/
|
|
3531
|
+
async deleteHtmlListDatapoints(adptName) {
|
|
3532
|
+
// delete the datapoints in subfolders with the adaptername otherwise delete the dP's in the root folder
|
|
3533
|
+
let dpSubFolder;
|
|
3534
|
+
if (adptName) {
|
|
3535
|
+
dpSubFolder = `${adptName}.`;
|
|
3536
|
+
} else {
|
|
3537
|
+
dpSubFolder = '';
|
|
3538
|
+
}
|
|
3539
|
+
|
|
3540
|
+
await this.delObjectAsync(`devices.${dpSubFolder}offlineListHTML`);
|
|
3541
|
+
await this.delObjectAsync(`devices.${dpSubFolder}linkQualityListHTML`);
|
|
3542
|
+
await this.delObjectAsync(`devices.${dpSubFolder}batteryListHTML`);
|
|
3543
|
+
await this.delObjectAsync(`devices.${dpSubFolder}lowBatteryListHTML`);
|
|
3544
|
+
}
|
|
3545
|
+
|
|
3409
3546
|
/*=============================================
|
|
3410
3547
|
= help functions =
|
|
3411
3548
|
=============================================*/
|
|
@@ -3421,20 +3558,27 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
3421
3558
|
/**
|
|
3422
3559
|
* @param {number} dpValue - get Time of this datapoint
|
|
3423
3560
|
*/
|
|
3424
|
-
|
|
3561
|
+
getTimestamp(dpValue) {
|
|
3425
3562
|
const time = new Date();
|
|
3426
3563
|
return (dpValue = Math.round((time.getTime() - dpValue) / 1000 / 60));
|
|
3427
3564
|
}
|
|
3428
3565
|
|
|
3429
3566
|
/**
|
|
3430
3567
|
* @param {string} dp - get Time of this datapoint
|
|
3568
|
+
* @param {number} ms - milliseconds
|
|
3431
3569
|
*/
|
|
3432
|
-
async getTimestampConnectionDP(dp) {
|
|
3570
|
+
async getTimestampConnectionDP(dp, ms) {
|
|
3433
3571
|
const time = new Date();
|
|
3434
3572
|
const dpValue = await this.getForeignStateAsync(dp);
|
|
3435
|
-
if (dpValue
|
|
3436
|
-
|
|
3437
|
-
|
|
3573
|
+
if (dpValue) {
|
|
3574
|
+
if (!dpValue.val) return false;
|
|
3575
|
+
|
|
3576
|
+
const dpLastStateChange = Math.round(time.getTime() - dpValue.lc); // calculate in ms
|
|
3577
|
+
if (dpLastStateChange >= ms) {
|
|
3578
|
+
return true;
|
|
3579
|
+
} else {
|
|
3580
|
+
return false;
|
|
3581
|
+
}
|
|
3438
3582
|
}
|
|
3439
3583
|
}
|
|
3440
3584
|
|
|
@@ -3459,7 +3603,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
3459
3603
|
/**
|
|
3460
3604
|
* @param {object} data - object
|
|
3461
3605
|
*/
|
|
3462
|
-
|
|
3606
|
+
parseData(data) {
|
|
3463
3607
|
if (!data) return {};
|
|
3464
3608
|
if (typeof data === 'object') return data;
|
|
3465
3609
|
if (typeof data === 'string') return JSON.parse(data);
|
|
@@ -3467,12 +3611,11 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
3467
3611
|
}
|
|
3468
3612
|
|
|
3469
3613
|
/**
|
|
3470
|
-
* @param {number}
|
|
3614
|
+
* @param {number} ms
|
|
3471
3615
|
*/
|
|
3472
|
-
async wait(
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
});
|
|
3616
|
+
async wait(ms) {
|
|
3617
|
+
if (isUnloaded) return;
|
|
3618
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3476
3619
|
}
|
|
3477
3620
|
|
|
3478
3621
|
/**
|
|
@@ -3481,7 +3624,7 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
3481
3624
|
* Inspired by https://stackoverflow.com/questions/68134104/
|
|
3482
3625
|
* @param {string} lastCronRun
|
|
3483
3626
|
*/
|
|
3484
|
-
|
|
3627
|
+
getPreviousCronRun(lastCronRun) {
|
|
3485
3628
|
try {
|
|
3486
3629
|
const interval = cronParser.parseExpression(lastCronRun);
|
|
3487
3630
|
const previous = interval.prev();
|
|
@@ -3516,11 +3659,14 @@ class DeviceWatcher extends utils.Adapter {
|
|
|
3516
3659
|
*/
|
|
3517
3660
|
onUnload(callback) {
|
|
3518
3661
|
try {
|
|
3662
|
+
this.log.debug('clearing timeouts');
|
|
3663
|
+
|
|
3664
|
+
isUnloaded = true;
|
|
3665
|
+
|
|
3519
3666
|
if (this.refreshDataTimeout) {
|
|
3520
|
-
this.
|
|
3521
|
-
this.
|
|
3667
|
+
clearTimeout(this.refreshDataTimeout);
|
|
3668
|
+
this.refreshDataTimeout = null;
|
|
3522
3669
|
}
|
|
3523
|
-
isUnloaded = true;
|
|
3524
3670
|
|
|
3525
3671
|
this.log.info('cleaned everything up...');
|
|
3526
3672
|
|