iobroker.device-watcher 2.9.13 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/main.js CHANGED
@@ -4,6 +4,7 @@ const utils = require('@iobroker/adapter-core');
4
4
  const adapterName = require('./package.json').name.split('.').pop();
5
5
  const schedule = require('node-schedule');
6
6
  const arrApart = require('./lib/arrApart.js'); // list of supported adapters
7
+ const translations = require('./lib/translations.js');
7
8
  const cronParser = require('cron-parser');
8
9
 
9
10
  // indicator if the adapter is running or not (for intervall/shedule)
@@ -687,10 +688,10 @@ class DeviceWatcher extends utils.Adapter {
687
688
 
688
689
  const instanceDeviceConnectionDP = `${instance}.info.connection`;
689
690
  const instancedeviceConnected = await this.getInitValue(instanceDeviceConnectionDP);
690
- // this.subscribeForeignStates(instanceDeviceConnectionDP);
691
+ this.subscribeForeignStates(instanceDeviceConnectionDP);
691
692
  this.subscribeForeignObjects(`${this.selAdapter[i].Selektor}`);
692
693
  // this.subscribeForeignObjects('*');
693
- this.subscribeForeignStates('*');
694
+ //this.subscribeForeignStates('*');
694
695
  /*=============================================
695
696
  = Get device name =
696
697
  =============================================*/
@@ -708,7 +709,7 @@ class DeviceWatcher extends utils.Adapter {
708
709
  const shortCurrDeviceString = currDeviceString.slice(0, currDeviceString.lastIndexOf('.') + 1 - 1);
709
710
 
710
711
  // subscribe to object device path
711
- // this.subscribeForeignStates(currDeviceString);
712
+ this.subscribeForeignStates(currDeviceString);
712
713
 
713
714
  /*=============================================
714
715
  = Get signal strength =
@@ -735,7 +736,7 @@ class DeviceWatcher extends utils.Adapter {
735
736
  break;
736
737
  }
737
738
  //subscribe to states
738
- // this.subscribeForeignStates(deviceQualityDP);
739
+ this.subscribeForeignStates(deviceQualityDP);
739
740
 
740
741
  const signalData = await this.calculateSignalStrength(deviceQualityState, adapterID);
741
742
  let linkQuality = signalData[0];
@@ -764,6 +765,7 @@ class DeviceWatcher extends utils.Adapter {
764
765
  case 'hmrpc':
765
766
  deviceBatteryStateDP = currDeviceString + this.selAdapter[i].battery;
766
767
  deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
768
+
767
769
  if (deviceBatteryState === undefined) {
768
770
  deviceBatteryStateDP = shortCurrDeviceString + this.selAdapter[i].hmDNBattery;
769
771
  deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
@@ -775,6 +777,7 @@ class DeviceWatcher extends utils.Adapter {
775
777
  case 'loqedSmartLock':
776
778
  deviceBatteryStateDP = shortCurrDeviceString + this.selAdapter[i].battery;
777
779
  deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
780
+
778
781
  if (deviceBatteryState === undefined) {
779
782
  deviceBatteryStateDP = shortCurrDeviceString + this.selAdapter[i].battery2;
780
783
  deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
@@ -783,9 +786,15 @@ class DeviceWatcher extends utils.Adapter {
783
786
  default:
784
787
  deviceBatteryStateDP = currDeviceString + this.selAdapter[i].battery;
785
788
  deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
789
+
786
790
  if (deviceBatteryState === undefined) {
787
791
  deviceBatteryStateDP = currDeviceString + this.selAdapter[i].battery2;
788
792
  deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
793
+
794
+ if (deviceBatteryState === undefined) {
795
+ deviceBatteryStateDP = currDeviceString + this.selAdapter[i].battery3;
796
+ deviceBatteryState = await this.getInitValue(deviceBatteryStateDP);
797
+ }
789
798
  }
790
799
  break;
791
800
  }
@@ -793,9 +802,11 @@ class DeviceWatcher extends utils.Adapter {
793
802
  // Get low bat states
794
803
  isLowBatDP = currDeviceString + this.selAdapter[i].isLowBat;
795
804
  let deviceLowBatState = await this.getInitValue(isLowBatDP);
805
+
796
806
  if (deviceLowBatState === undefined) {
797
807
  isLowBatDP = currDeviceString + this.selAdapter[i].isLowBat2;
798
808
  deviceLowBatState = await this.getInitValue(isLowBatDP);
809
+
799
810
  if (deviceLowBatState === undefined) {
800
811
  isLowBatDP = currDeviceString + this.selAdapter[i].isLowBat3;
801
812
  deviceLowBatState = await this.getInitValue(isLowBatDP);
@@ -807,9 +818,9 @@ class DeviceWatcher extends utils.Adapter {
807
818
  faultReportingState = await this.getInitValue(faultReportingDP);
808
819
 
809
820
  //subscribe to states
810
- // this.subscribeForeignStates(deviceBatteryStateDP);
811
- // this.subscribeForeignStates(isLowBatDP);
812
- // this.subscribeForeignStates(faultReportingDP);
821
+ this.subscribeForeignStates(deviceBatteryStateDP);
822
+ this.subscribeForeignStates(isLowBatDP);
823
+ this.subscribeForeignStates(faultReportingDP);
813
824
 
814
825
  const batteryData = await this.getBatteryData(deviceBatteryState, deviceLowBatState, faultReportingState, adapterID);
815
826
  batteryHealth = batteryData[0];
@@ -842,10 +853,10 @@ class DeviceWatcher extends utils.Adapter {
842
853
  }
843
854
 
844
855
  // subscribe to states
845
- // this.subscribeForeignStates(timeSelector);
846
- // this.subscribeForeignStates(unreachDP);
847
- // this.subscribeForeignStates(deviceStateSelectorDP);
848
- // this.subscribeForeignStates(rssiPeerSelectorDP);
856
+ this.subscribeForeignStates(timeSelector);
857
+ this.subscribeForeignStates(unreachDP);
858
+ this.subscribeForeignStates(deviceStateSelectorDP);
859
+ this.subscribeForeignStates(rssiPeerSelectorDP);
849
860
 
850
861
  const onlineState = await this.getOnlineState(timeSelector, adapterID, unreachDP, linkQuality, deviceUnreachState, deviceStateSelectorDP, rssiPeerSelectorDP);
851
862
  let deviceState;
@@ -883,8 +894,8 @@ class DeviceWatcher extends utils.Adapter {
883
894
  }
884
895
 
885
896
  // subscribe to states
886
- // this.subscribeForeignStates(deviceUpdateDP);
887
- this.subscribeForeignStates('*');
897
+ this.subscribeForeignStates(deviceUpdateDP);
898
+ // this.subscribeForeignStates('*');
888
899
  }
889
900
 
890
901
  /*=============================================
@@ -1048,61 +1059,55 @@ class DeviceWatcher extends utils.Adapter {
1048
1059
  let mqttNukiValue;
1049
1060
 
1050
1061
  if (deviceQualityState != null) {
1051
- switch (typeof deviceQualityState.val) {
1052
- case 'number':
1053
- if (this.config.trueState) {
1054
- linkQuality = deviceQualityState.val;
1055
- } else {
1056
- switch (adapterID) {
1057
- case 'roomba':
1058
- case 'sonoff':
1059
- case 'smartgarden':
1060
- linkQuality = deviceQualityState.val + '%'; // If quality state is already an percent value
1061
- linkQualityRaw = deviceQualityState.val;
1062
- break;
1063
- case 'lupusec':
1064
- case 'fullybrowserV3':
1065
- linkQuality = deviceQualityState.val; // use real state
1066
- break;
1067
-
1068
- default:
1069
- // If quality state is an RSSI value calculate in percent:
1070
- if (deviceQualityState.val == -255) {
1071
- linkQuality = ' - ';
1072
- } else if (deviceQualityState.val < 0) {
1073
- linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
1074
- linkQualityRaw = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100);
1075
-
1076
- // If Quality State is an value between 0-255 (zigbee) calculate in percent:
1077
- } else if (deviceQualityState.val >= 0) {
1078
- linkQuality = parseFloat(((100 / 255) * deviceQualityState.val).toFixed(0)) + '%';
1079
- linkQualityRaw = parseFloat(((100 / 255) * deviceQualityState.val).toFixed(0));
1080
- }
1081
- break;
1082
- }
1083
- }
1084
- break;
1062
+ const { val } = deviceQualityState;
1085
1063
 
1086
- case 'string':
1064
+ if (typeof val === 'number') {
1065
+ if (this.config.trueState) {
1066
+ linkQuality = val;
1067
+ } else {
1087
1068
  switch (adapterID) {
1088
- case 'netatmo':
1089
- // for Netatmo devices
1090
- linkQuality = deviceQualityState.val;
1069
+ case 'roomba':
1070
+ case 'sonoff':
1071
+ case 'smartgarden':
1072
+ linkQuality = `${val}%`;
1073
+ linkQualityRaw = val;
1091
1074
  break;
1092
- case 'nukiExt':
1093
- linkQuality = ' - ';
1075
+ case 'lupusec':
1076
+ case 'fullybrowserV3':
1077
+ linkQuality = val;
1094
1078
  break;
1095
- case 'mqttNuki':
1096
- linkQuality = deviceQualityState.val;
1097
- mqttNukiValue = parseInt(linkQuality);
1098
- if (this.config.trueState) {
1099
- linkQuality = deviceQualityState.val;
1100
- } else if (mqttNukiValue < 0) {
1101
- linkQuality = Math.min(Math.max(2 * (mqttNukiValue + 100), 0), 100) + '%';
1102
- linkQualityRaw = Math.min(Math.max(2 * (mqttNukiValue + 100), 0), 100);
1079
+ default:
1080
+ if (val <= -255) {
1081
+ linkQuality = ' - ';
1082
+ } else if (val < 0) {
1083
+ linkQualityRaw = Math.min(Math.max(2 * (val + 100), 0), 100);
1084
+ linkQuality = `${linkQualityRaw}%`;
1085
+ } else if (val >= 0) {
1086
+ linkQualityRaw = parseFloat(((100 / 255) * val).toFixed(0));
1087
+ linkQuality = `${linkQualityRaw}%`;
1103
1088
  }
1089
+ break;
1104
1090
  }
1105
- break;
1091
+ }
1092
+ } else if (typeof val === 'string') {
1093
+ switch (adapterID) {
1094
+ case 'netatmo':
1095
+ linkQuality = val;
1096
+ break;
1097
+ case 'nukiExt':
1098
+ linkQuality = ' - ';
1099
+ break;
1100
+ case 'mqttNuki':
1101
+ linkQuality = val;
1102
+ mqttNukiValue = parseInt(linkQuality);
1103
+ if (this.config.trueState) {
1104
+ linkQuality = val;
1105
+ } else if (mqttNukiValue < 0) {
1106
+ linkQualityRaw = Math.min(Math.max(2 * (mqttNukiValue + 100), 0), 100);
1107
+ linkQuality = `${linkQualityRaw}%`;
1108
+ }
1109
+ break;
1110
+ }
1106
1111
  }
1107
1112
  } else {
1108
1113
  linkQuality = ' - ';
@@ -1118,61 +1123,46 @@ class DeviceWatcher extends utils.Adapter {
1118
1123
  * @param {object} adapterID - adapter name
1119
1124
  */
1120
1125
  async getBatteryData(deviceBatteryState, deviceLowBatState, faultReportingState, adapterID) {
1126
+ let batteryHealth = '-';
1127
+ let isBatteryDevice = false;
1121
1128
  let batteryHealthRaw;
1122
1129
  let batteryHealthUnitRaw;
1123
- let batteryHealth;
1124
- let isBatteryDevice;
1125
1130
 
1126
- switch (adapterID) {
1127
- case 'hmrpc':
1128
- if (deviceBatteryState === undefined) {
1129
- if (faultReportingState !== undefined) {
1130
- if (faultReportingState !== 6) {
1131
- batteryHealth = 'ok';
1132
- } else {
1133
- batteryHealth = 'low';
1134
- }
1135
- isBatteryDevice = true;
1136
- } else if (deviceLowBatState !== undefined) {
1137
- if (deviceLowBatState !== 1) {
1138
- batteryHealth = 'ok';
1139
- } else {
1140
- batteryHealth = 'low';
1141
- }
1142
- isBatteryDevice = true;
1143
- } else {
1144
- batteryHealth = ' - ';
1145
- }
1146
- } else {
1147
- if (deviceBatteryState === 0 || deviceBatteryState >= 6) {
1148
- batteryHealth = ' - ';
1149
- } else {
1150
- batteryHealth = deviceBatteryState + 'V';
1151
- batteryHealthRaw = deviceBatteryState;
1152
- batteryHealthUnitRaw = 'V';
1153
- isBatteryDevice = true;
1154
- }
1131
+ if (adapterID === 'hmrpc') {
1132
+ if (deviceBatteryState === undefined) {
1133
+ if (faultReportingState !== undefined && faultReportingState !== 6) {
1134
+ batteryHealth = 'ok';
1135
+ isBatteryDevice = true;
1136
+ } else if (deviceLowBatState !== undefined && deviceLowBatState !== 1) {
1137
+ batteryHealth = 'ok';
1138
+ isBatteryDevice = true;
1139
+ } else if (deviceLowBatState !== undefined) {
1140
+ batteryHealth = 'low';
1141
+ isBatteryDevice = true;
1155
1142
  }
1156
- break;
1157
- default:
1158
- if (deviceBatteryState === undefined) {
1159
- if (deviceLowBatState !== undefined) {
1160
- if (deviceLowBatState !== true || deviceLowBatState === 'NORMAL' || deviceLowBatState === 1) {
1161
- batteryHealth = 'ok';
1162
- } else {
1163
- batteryHealth = 'low';
1164
- }
1143
+ } else if (deviceBatteryState !== 0 && deviceBatteryState < 6) {
1144
+ batteryHealth = `${deviceBatteryState}V`;
1145
+ batteryHealthRaw = deviceBatteryState;
1146
+ batteryHealthUnitRaw = 'V';
1147
+ isBatteryDevice = true;
1148
+ }
1149
+ } else {
1150
+ if (deviceBatteryState === undefined) {
1151
+ if (deviceLowBatState !== undefined) {
1152
+ if (deviceLowBatState !== true && deviceLowBatState !== 'NORMAL' && deviceLowBatState !== 1) {
1153
+ batteryHealth = 'ok';
1154
+ isBatteryDevice = true;
1155
+ } else if (deviceLowBatState !== true) {
1156
+ batteryHealth = 'low';
1165
1157
  isBatteryDevice = true;
1166
- } else {
1167
- batteryHealth = ' - ';
1168
1158
  }
1169
- } else {
1170
- batteryHealth = deviceBatteryState + '%';
1171
- batteryHealthRaw = deviceBatteryState;
1172
- batteryHealthUnitRaw = '%';
1173
- isBatteryDevice = true;
1174
1159
  }
1175
- break;
1160
+ } else {
1161
+ batteryHealth = `${deviceBatteryState}%`;
1162
+ batteryHealthRaw = deviceBatteryState;
1163
+ batteryHealthUnitRaw = '%';
1164
+ isBatteryDevice = true;
1165
+ }
1176
1166
  }
1177
1167
 
1178
1168
  return [batteryHealth, isBatteryDevice, batteryHealthRaw, batteryHealthUnitRaw];
@@ -1188,9 +1178,7 @@ class DeviceWatcher extends utils.Adapter {
1188
1178
 
1189
1179
  async setLowbatIndicator(deviceBatteryState, deviceLowBatState, faultReportState, adapterID) {
1190
1180
  let lowBatIndicator = false;
1191
- /*=============================================
1192
- = Set Lowbat indicator =
1193
- =============================================*/
1181
+
1194
1182
  if (deviceLowBatState !== undefined || faultReportState !== undefined) {
1195
1183
  switch (adapterID) {
1196
1184
  case 'hmrpc':
@@ -1199,32 +1187,18 @@ class DeviceWatcher extends utils.Adapter {
1199
1187
  }
1200
1188
  break;
1201
1189
  default:
1202
- switch (typeof deviceLowBatState) {
1203
- case 'number':
1204
- if (deviceLowBatState === 0) {
1205
- lowBatIndicator = true;
1206
- }
1207
- break;
1208
-
1209
- case 'string':
1210
- if (deviceLowBatState !== 'NORMAL') {
1211
- // Tado devices
1212
- lowBatIndicator = true;
1213
- }
1214
- break;
1215
-
1216
- case 'boolean':
1217
- if (deviceLowBatState) {
1218
- lowBatIndicator = true;
1219
- }
1220
- break;
1190
+ if (typeof deviceLowBatState === 'number' && deviceLowBatState === 0) {
1191
+ lowBatIndicator = true;
1192
+ } else if (typeof deviceLowBatState === 'string' && deviceLowBatState !== 'NORMAL') {
1193
+ lowBatIndicator = true;
1194
+ } else if (typeof deviceLowBatState === 'boolean' && deviceLowBatState) {
1195
+ lowBatIndicator = true;
1221
1196
  }
1222
1197
  }
1223
- } else {
1224
- if (deviceBatteryState < this.config.minWarnBatterie) {
1225
- lowBatIndicator = true;
1226
- }
1198
+ } else if (deviceBatteryState < this.config.minWarnBatterie) {
1199
+ lowBatIndicator = true;
1227
1200
  }
1201
+
1228
1202
  return lowBatIndicator;
1229
1203
  }
1230
1204
 
@@ -1236,13 +1210,14 @@ class DeviceWatcher extends utils.Adapter {
1236
1210
  const lastContact = this.getTimestamp(selector);
1237
1211
  let lastContactString;
1238
1212
 
1239
- lastContactString = this.formatDate(new Date(selector), 'hh:mm') + ' Uhr';
1240
1213
  if (Math.round(lastContact) > 100) {
1241
- lastContactString = Math.round(lastContact / 60) + ' Stunden';
1242
- }
1243
- if (Math.round(lastContact / 60) > 48) {
1244
- lastContactString = Math.round(lastContact / 60 / 24) + ' Tagen';
1214
+ lastContactString = `${Math.round(lastContact / 60 / 24)} ${translations.days[this.language]}`;
1215
+ } else if (Math.round(lastContact) > 48) {
1216
+ lastContactString = `${Math.round(lastContact / 60)} ${translations.hours[this.language]}`;
1217
+ } else {
1218
+ lastContactString = `${this.formatDate(new Date(selector), 'hh:mm')}`;
1245
1219
  }
1220
+
1246
1221
  return lastContactString;
1247
1222
  }
1248
1223
 
@@ -1265,37 +1240,35 @@ class DeviceWatcher extends utils.Adapter {
1265
1240
  const deviceUnreachSelector = await this.getForeignStateAsync(unreachDP);
1266
1241
  const deviceStateSelector = await this.getForeignStateAsync(deviceStateSelectorDP); // for hmrpc devices
1267
1242
  const rssiPeerSelector = await this.getForeignStateAsync(rssiPeerSelectorDP);
1268
- const lastDeviceUnreachStateChange = deviceUnreachSelector != undefined ? this.getTimestamp(deviceUnreachSelector.lc) : this.getTimestamp(timeSelector.ts);
1269
- // If there is no contact since user sets minutes add device in offline list
1270
- // calculate to days after 48 hours
1243
+ const lastDeviceUnreachStateChange = deviceUnreachSelector !== undefined ? this.getTimestamp(deviceUnreachSelector.lc) : this.getTimestamp(timeSelector.ts);
1244
+
1245
+ // If there is no contact since the user sets minutes, add the device to the offline list and calculate to days after 48 hours
1271
1246
  switch (unreachDP) {
1272
1247
  case 'none':
1273
- if (deviceTimeSelector) lastContactString = await this.getLastContact(deviceTimeSelector.ts);
1248
+ if (deviceTimeSelector) {
1249
+ lastContactString = await this.getLastContact(deviceTimeSelector.ts);
1250
+ }
1274
1251
  break;
1275
1252
 
1276
1253
  default:
1277
- //State changed
1254
+ // State changed
1278
1255
  if (adapterID === 'hmrpc') {
1279
1256
  if (linkQuality !== ' - ' && deviceTimeSelector) {
1280
- if (deviceUnreachState === 1) {
1281
- lastContactString = await this.getLastContact(deviceTimeSelector.lc);
1282
- } else {
1283
- lastContactString = await this.getLastContact(deviceTimeSelector.ts);
1284
- }
1257
+ lastContactString = deviceUnreachState === 1 ? await this.getLastContact(deviceTimeSelector.lc) : await this.getLastContact(deviceTimeSelector.ts);
1285
1258
  } else {
1286
1259
  if (deviceStateSelector) {
1287
- // because old hm devices don't send rssi states
1260
+ // Because old hm devices don't send rssi states
1288
1261
  lastContactString = await this.getLastContact(deviceStateSelector.ts);
1289
1262
  } else if (rssiPeerSelector) {
1290
- // because old hm sensors don't send rssi/state values
1263
+ // Because old hm sensors don't send rssi/state values
1291
1264
  lastContactString = await this.getLastContact(rssiPeerSelector.ts);
1292
1265
  }
1293
1266
  }
1294
1267
  } else {
1295
1268
  if ((!deviceUnreachState || deviceUnreachState === 0) && deviceTimeSelector) {
1296
1269
  lastContactString = await this.getLastContact(deviceTimeSelector.lc);
1297
- } else {
1298
- if (deviceTimeSelector) lastContactString = await this.getLastContact(deviceTimeSelector.ts);
1270
+ } else if (deviceTimeSelector) {
1271
+ lastContactString = await this.getLastContact(deviceTimeSelector.ts);
1299
1272
  }
1300
1273
  break;
1301
1274
  }
@@ -1305,43 +1278,25 @@ class DeviceWatcher extends utils.Adapter {
1305
1278
  = Set Online Status =
1306
1279
  =============================================*/
1307
1280
  let lastContact;
1281
+
1308
1282
  if (deviceTimeSelector) lastContact = this.getTimestamp(deviceTimeSelector.ts);
1309
1283
 
1310
1284
  if (this.configMaxMinutes !== undefined) {
1285
+ let setOfflineState = false;
1286
+
1311
1287
  switch (adapterID) {
1312
1288
  case 'hmrpc':
1313
- if (this.configMaxMinutes[adapterID] <= 0) {
1314
- if (deviceUnreachState === 1) {
1315
- deviceState = 'Offline'; //set online state to offline
1316
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1317
- }
1318
- } else if (lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID] && deviceUnreachState === 1) {
1319
- deviceState = 'Offline'; //set online state to offline
1320
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1321
- }
1289
+ setOfflineState =
1290
+ (this.configMaxMinutes[adapterID] <= 0 && deviceUnreachState === 1) || (lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID] && deviceUnreachState === 1);
1322
1291
  break;
1323
1292
  case 'proxmox':
1324
- if (this.configMaxMinutes[adapterID] <= 0) {
1325
- if (deviceUnreachState !== 'running' && deviceUnreachState !== 'online') {
1326
- deviceState = 'Offline'; //set online state to offline
1327
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1328
- }
1329
- } else if (lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID] && deviceUnreachState !== 'running' && deviceUnreachState !== 'online') {
1330
- deviceState = 'Offline'; //set online state to offline
1331
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1332
- }
1293
+ setOfflineState =
1294
+ (this.configMaxMinutes[adapterID] <= 0 && deviceUnreachState !== 'running' && deviceUnreachState !== 'online') ||
1295
+ (lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID] && deviceUnreachState !== 'running' && deviceUnreachState !== 'online');
1333
1296
  break;
1334
1297
  case 'hmiP':
1335
1298
  case 'maxcube':
1336
- if (this.configMaxMinutes[adapterID] <= 0) {
1337
- if (deviceUnreachState) {
1338
- deviceState = 'Offline'; //set online state to offline
1339
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1340
- }
1341
- } else if (lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID] && deviceUnreachState) {
1342
- deviceState = 'Offline'; //set online state to offline
1343
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1344
- }
1299
+ setOfflineState = (this.configMaxMinutes[adapterID] <= 0 && deviceUnreachState) || (lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID] && deviceUnreachState);
1345
1300
  break;
1346
1301
  case 'apcups':
1347
1302
  case 'hue':
@@ -1354,74 +1309,36 @@ class DeviceWatcher extends utils.Adapter {
1354
1309
  case 'unifi':
1355
1310
  case 'zigbee':
1356
1311
  case 'zigbee2MQTT':
1357
- if (this.configMaxMinutes[adapterID] <= 0) {
1358
- if (!deviceUnreachState) {
1359
- deviceState = 'Offline'; //set online state to offline
1360
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1361
- }
1362
- } else if (!deviceUnreachState && lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID]) {
1363
- deviceState = 'Offline'; //set online state to offline
1364
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1365
- }
1312
+ setOfflineState = (this.configMaxMinutes[adapterID] <= 0 && !deviceUnreachState) || (!deviceUnreachState && lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID]);
1366
1313
  break;
1367
1314
  case 'mqttClientZigbee2Mqtt':
1368
- if (this.configMaxMinutes[adapterID] <= 0) {
1369
- if (deviceUnreachState !== 'online') {
1370
- deviceState = 'Offline'; //set online state to offline
1371
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1372
- }
1373
- } else if (deviceUnreachState !== 'online' && lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID]) {
1374
- deviceState = 'Offline'; //set online state to offline
1375
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1376
- }
1315
+ setOfflineState =
1316
+ (this.configMaxMinutes[adapterID] <= 0 && deviceUnreachState !== 'online') ||
1317
+ (deviceUnreachState !== 'online' && lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID]);
1377
1318
  break;
1378
1319
  case 'mihome':
1379
1320
  if (deviceUnreachState !== undefined) {
1380
- if (this.configMaxMinutes[adapterID] <= 0) {
1381
- if (!deviceUnreachState) {
1382
- deviceState = 'Offline'; //set online state to offline
1383
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1384
- }
1385
- } else if (lastContact && lastContact > this.configMaxMinutes[adapterID]) {
1386
- deviceState = 'Offline'; //set online state to offline
1387
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1388
- }
1321
+ setOfflineState = (this.configMaxMinutes[adapterID] <= 0 && !deviceUnreachState) || (lastContact && lastContact > this.configMaxMinutes[adapterID]);
1389
1322
  } else {
1390
- if (this.config.mihomeMaxMinutes <= 0) {
1391
- if (this.configMaxMinutes[adapterID] <= 0) {
1392
- deviceState = 'Offline'; //set online state to offline
1393
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1394
- }
1395
- } else if (lastContact && lastContact > this.configMaxMinutes[adapterID]) {
1396
- deviceState = 'Offline'; //set online state to offline
1397
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1398
- }
1323
+ setOfflineState = (this.config.mihomeMaxMinutes <= 0 && this.configMaxMinutes[adapterID] <= 0) || (lastContact && lastContact > this.configMaxMinutes[adapterID]);
1399
1324
  }
1400
1325
  break;
1401
1326
  case 'smartgarden':
1402
- if (this.configMaxMinutes[adapterID] <= 0) {
1403
- if (deviceUnreachState === 'OFFLINE') {
1404
- deviceState = 'Offline'; //set online state to offline
1405
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1406
- }
1407
- } else if (deviceUnreachState === 'OFFLINE' && lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID]) {
1408
- deviceState = 'Offline'; //set online state to offline
1409
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1410
- }
1327
+ setOfflineState =
1328
+ (this.configMaxMinutes[adapterID] <= 0 && deviceUnreachState === 'OFFLINE') ||
1329
+ (deviceUnreachState === 'OFFLINE' && lastDeviceUnreachStateChange > this.configMaxMinutes[adapterID]);
1411
1330
  break;
1412
1331
  default:
1413
- if (this.configMaxMinutes[adapterID] <= 0) {
1414
- if (!deviceUnreachState) {
1415
- deviceState = 'Offline'; //set online state to offline
1416
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1417
- }
1418
- } else if (lastContact && lastContact > this.configMaxMinutes[adapterID]) {
1419
- deviceState = 'Offline'; //set online state to offline
1420
- if (linkQuality !== ' - ') linkQuality = '0%'; // set linkQuality to nothing
1421
- }
1332
+ setOfflineState = (this.configMaxMinutes[adapterID] <= 0 && !deviceUnreachState) || (lastContact && lastContact > this.configMaxMinutes[adapterID]);
1422
1333
  break;
1423
1334
  }
1335
+
1336
+ if (setOfflineState) {
1337
+ deviceState = 'Offline';
1338
+ if (linkQuality !== ' - ' && !this.config.showLastSignal) linkQuality = '0%';
1339
+ }
1424
1340
  }
1341
+
1425
1342
  return [lastContactString, deviceState, linkQuality];
1426
1343
  } catch (error) {
1427
1344
  this.log.error(`[getLastContact] - ${error}`);
@@ -1432,7 +1349,7 @@ class DeviceWatcher extends utils.Adapter {
1432
1349
  * when was last contact of device
1433
1350
  */
1434
1351
  async checkLastContact() {
1435
- for (const [device, deviceData] of this.listAllDevicesRaw) {
1352
+ for (const [device, deviceData] of this.listAllDevicesRaw.entries()) {
1436
1353
  if (deviceData.instancedeviceConnected !== false) {
1437
1354
  const oldContactState = deviceData.Status;
1438
1355
  deviceData.UnreachState = await this.getInitValue(deviceData.UnreachDP);
@@ -1556,74 +1473,74 @@ class DeviceWatcher extends utils.Adapter {
1556
1473
  async theLists(device) {
1557
1474
  // Raw List with all devices for user
1558
1475
  this.listAllDevicesUserRaw.push({
1559
- Device: device.Device,
1560
- Adapter: device.Adapter,
1561
- Instance: device.instance,
1562
- 'Instance connected': device.instancedeviceConnected,
1563
- isBatteryDevice: device.isBatteryDevice,
1564
- Battery: device.Battery,
1565
- BatteryRaw: device.BatteryRaw,
1566
- BatteryUnitRaw: device.BatteryUnitRaw,
1567
- isLowBat: device.LowBat,
1568
- 'Signal strength': device.SignalStrength,
1569
- 'Signal strength Raw': device.SignalStrengthRaw,
1570
- 'Last contact': device.LastContact,
1571
- 'Update Available': device.Upgradable,
1572
- Status: device.Status,
1476
+ [translations.Device[this.language]]: device.Device,
1477
+ [translations.Adapter[this.language]]: device.Adapter,
1478
+ [translations.Instance[this.language]]: device.instance,
1479
+ [translations.Instance_connected[this.language]]: device.instancedeviceConnected,
1480
+ [translations.isBatteryDevice[this.language]]: device.isBatteryDevice,
1481
+ [translations.Battery[this.language]]: device.Battery,
1482
+ [translations.BatteryRaw[this.language]]: device.BatteryRaw,
1483
+ [translations.BatteryUnitRaw[this.language]]: device.BatteryUnitRaw,
1484
+ [translations.isLowBat[this.language]]: device.LowBat,
1485
+ [translations.Signal_strength[this.language]]: device.SignalStrength,
1486
+ [translations.Signal_strength_Raw[this.language]]: device.SignalStrengthRaw,
1487
+ [translations.Last_Contact[this.language]]: device.LastContact,
1488
+ [translations.Update_Available[this.language]]: device.Upgradable,
1489
+ [translations.Status[this.language]]: device.Status,
1573
1490
  });
1574
1491
 
1575
1492
  // List with all devices
1576
1493
  this.listAllDevices.push({
1577
- Device: device.Device,
1578
- Adapter: device.Adapter,
1579
- Battery: device.Battery,
1580
- 'Signal strength': device.SignalStrength,
1581
- 'Last contact': device.LastContact,
1582
- Status: device.Status,
1494
+ [translations.Device[this.language]]: device.Device,
1495
+ [translations.Adapter[this.language]]: device.Adapter,
1496
+ [translations.Battery[this.language]]: device.Battery,
1497
+ [translations.Signal_strength[this.language]]: device.SignalStrength,
1498
+ [translations.Last_Contact[this.language]]: device.LastContact,
1499
+ [translations.Status[this.language]]: device.Status,
1583
1500
  });
1584
1501
 
1585
1502
  // LinkQuality lists
1586
1503
  if (device.SignalStrength != ' - ') {
1587
1504
  this.linkQualityDevices.push({
1588
- Device: device.Device,
1589
- Adapter: device.Adapter,
1590
- 'Signal strength': device.SignalStrength,
1505
+ [translations.Device[this.language]]: device.Device,
1506
+ [translations.Adapter[this.language]]: device.Adapter,
1507
+ [translations.Signal_strength[this.language]]: device.SignalStrength,
1591
1508
  });
1592
1509
  }
1593
1510
 
1594
1511
  // Battery lists
1595
1512
  if (device.isBatteryDevice) {
1596
1513
  this.batteryPowered.push({
1597
- Device: device.Device,
1598
- Adapter: device.Adapter,
1599
- Battery: device.Battery,
1600
- Status: device.Status,
1514
+ [translations.Device[this.language]]: device.Device,
1515
+ [translations.Adapter[this.language]]: device.Adapter,
1516
+ [translations.Battery[this.language]]: device.Battery,
1517
+ [translations.Status[this.language]]: device.Status,
1601
1518
  });
1602
1519
  }
1603
1520
 
1604
1521
  // Low Bat lists
1605
1522
  if (device.LowBat && device.Status !== 'Offline') {
1606
1523
  this.batteryLowPowered.push({
1607
- Device: device.Device,
1608
- Adapter: device.Adapter,
1609
- Battery: device.Battery,
1524
+ [translations.Device[this.language]]: device.Device,
1525
+ [translations.Adapter[this.language]]: device.Adapter,
1526
+ [translations.Battery[this.language]]: device.Battery,
1610
1527
  });
1611
1528
  }
1612
1529
 
1613
1530
  // Offline List
1614
1531
  if (device.Status === 'Offline') {
1615
1532
  this.offlineDevices.push({
1616
- Device: device.Device,
1617
- Adapter: device.Adapter,
1618
- 'Last contact': device.LastContact,
1533
+ [translations.Device[this.language]]: device.Device,
1534
+ [translations.Adapter[this.language]]: device.Adapter,
1535
+ [translations.Last_Contact[this.language]]: device.LastContact,
1619
1536
  });
1620
1537
  }
1621
1538
 
1622
1539
  // Device update List
1623
1540
  if (device.Upgradable === true || device.Upgradable === 1) {
1624
1541
  this.upgradableList.push({
1625
- Device: device.Device,
1626
- Adapter: device.Adapter,
1542
+ [translations.Device[this.language]]: device.Device,
1543
+ [translations.Adapter[this.language]]: device.Adapter,
1627
1544
  });
1628
1545
  }
1629
1546
  }
@@ -1656,7 +1573,6 @@ class DeviceWatcher extends utils.Adapter {
1656
1573
  */
1657
1574
  async writeDatapoints(adptName) {
1658
1575
  // fill the datapoints
1659
-
1660
1576
  this.log.debug(`Start the function: ${this.writeDatapoints.name}`);
1661
1577
 
1662
1578
  try {
@@ -1674,34 +1590,33 @@ class DeviceWatcher extends utils.Adapter {
1674
1590
  await this.setStateChangedAsync(`devices.${dpSubFolder}batteryCount`, { val: this.batteryPoweredCount, ack: true });
1675
1591
  await this.setStateChangedAsync(`devices.${dpSubFolder}lowBatteryCount`, { val: this.lowBatteryPoweredCount, ack: true });
1676
1592
  await this.setStateChangedAsync(`devices.${dpSubFolder}upgradableCount`, { val: this.upgradableDevicesCount, ack: true });
1677
-
1678
1593
  // List all devices
1679
1594
  if (this.deviceCounter === 0) {
1680
1595
  // if no device is count, write the JSON List with default value
1681
1596
  this.listAllDevices = [
1682
1597
  {
1683
- Device: '--none--',
1684
- Adapter: '',
1685
- Battery: '',
1686
- 'Signal strength': '',
1687
- 'Last contact': '',
1688
- Status: '',
1598
+ [translations.Device[this.language]]: '--none--',
1599
+ [translations.Adapter[this.language]]: '',
1600
+ [translations.Battery[this.language]]: '',
1601
+ [translations.Signal_strength[this.language]]: '',
1602
+ [translations.Last_Contact[this.language]]: '',
1603
+ [translations.Status[this.language]]: '',
1689
1604
  },
1690
1605
  ];
1691
1606
  this.listAllDevicesUserRaw = [
1692
1607
  {
1693
- Device: '--none--',
1694
- Adapter: '',
1695
- Instance: '',
1696
- 'Instance connected': '',
1697
- isBatteryDevice: '',
1698
- Battery: '',
1699
- BatteryRaw: '',
1700
- isLowBat: '',
1701
- 'Signal strength': '',
1702
- 'Last contact': '',
1703
- UpdateAvailable: '',
1704
- Status: '',
1608
+ [translations.Device[this.language]]: '--none--',
1609
+ [translations.Adapter[this.language]]: '',
1610
+ [translations.Instance[this.language]]: '',
1611
+ [translations.Instance_connected[this.language]]: '',
1612
+ [translations.isBatteryDevice[this.language]]: '',
1613
+ [translations.Battery[this.language]]: '',
1614
+ [translations.BatteryRaw[this.language]]: '',
1615
+ [translations.isLowBat[this.language]]: '',
1616
+ [translations.Signal_strength[this.language]]: '',
1617
+ [translations.Last_Contact[this.language]]: '',
1618
+ [translations.Update_Available[this.language]]: '',
1619
+ [translations.Status[this.language]]: '',
1705
1620
  },
1706
1621
  ];
1707
1622
  }
@@ -1713,9 +1628,9 @@ class DeviceWatcher extends utils.Adapter {
1713
1628
  // if no device is count, write the JSON List with default value
1714
1629
  this.linkQualityDevices = [
1715
1630
  {
1716
- Device: '--none--',
1717
- Adapter: '',
1718
- 'Signal strength': '',
1631
+ [translations.Device[this.language]]: '--none--',
1632
+ [translations.Adapter[this.language]]: '',
1633
+ [translations.Signal_strength[this.language]]: '',
1719
1634
  },
1720
1635
  ];
1721
1636
  }
@@ -1730,9 +1645,9 @@ class DeviceWatcher extends utils.Adapter {
1730
1645
  // if no device is count, write the JSON List with default value
1731
1646
  this.offlineDevices = [
1732
1647
  {
1733
- Device: '--none--',
1734
- Adapter: '',
1735
- 'Last contact': '',
1648
+ [translations.Device[this.language]]: '--none--',
1649
+ [translations.Adapter[this.language]]: '',
1650
+ [translations.Last_Contact[this.language]]: '',
1736
1651
  },
1737
1652
  ];
1738
1653
  }
@@ -1747,9 +1662,9 @@ class DeviceWatcher extends utils.Adapter {
1747
1662
  // if no device is count, write the JSON List with default value
1748
1663
  this.upgradableList = [
1749
1664
  {
1750
- Device: '--none--',
1751
- Adapter: '',
1752
- 'Last contact': '',
1665
+ [translations.Device[this.language]]: '--none--',
1666
+ [translations.Adapter[this.language]]: '',
1667
+ [translations.Last_Contact[this.language]]: '',
1753
1668
  },
1754
1669
  ];
1755
1670
  }
@@ -1762,7 +1677,7 @@ class DeviceWatcher extends utils.Adapter {
1762
1677
  // List battery powered
1763
1678
  if (this.batteryPoweredCount === 0) {
1764
1679
  // if no device is count, write the JSON List with default value
1765
- this.batteryPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
1680
+ this.batteryPowered = [{ [translations.Device[this.language]]: '--none--', [translations.Adapter[this.language]]: '', [translations.Battery[this.language]]: '' }];
1766
1681
  }
1767
1682
  //write JSON list
1768
1683
  await this.setStateChangedAsync(`devices.${dpSubFolder}batteryList`, {
@@ -1773,7 +1688,7 @@ class DeviceWatcher extends utils.Adapter {
1773
1688
  // list battery low powered
1774
1689
  if (this.lowBatteryPoweredCount === 0) {
1775
1690
  // if no device is count, write the JSON List with default value
1776
- this.batteryLowPowered = [{ Device: '--none--', Adapter: '', Battery: '' }];
1691
+ this.batteryLowPowered = [{ [translations.Device[this.language]]: '--none--', [translations.Adapter[this.language]]: '', [translations.Battery[this.language]]: '' }];
1777
1692
  }
1778
1693
  //write JSON list
1779
1694
  await this.setStateChangedAsync(`devices.${dpSubFolder}lowBatteryList`, {
@@ -1825,7 +1740,7 @@ class DeviceWatcher extends utils.Adapter {
1825
1740
  ack: true,
1826
1741
  });
1827
1742
  await this.setStateChangedAsync(`devices.${dpSubFolder}offlineListHTML`, {
1828
- val: await this.createListHTML('offlineList', this.offlineDevices, this.offlineDevicesCount, null),
1743
+ val: await this.createListHTML('offlineList', this.offlineDevicesRaw, this.offlineDevicesCount, null),
1829
1744
  ack: true,
1830
1745
  });
1831
1746
  await this.setStateChangedAsync(`devices.${dpSubFolder}batteryListHTML`, {
@@ -1838,23 +1753,23 @@ class DeviceWatcher extends utils.Adapter {
1838
1753
  });
1839
1754
  if (this.config.checkAdapterInstances) {
1840
1755
  await this.setStateChangedAsync(`adapterAndInstances.HTML_Lists.listAllInstancesHTML`, {
1841
- val: await this.createListHTMLInstances('allInstancesList', this.listAllInstances, this.countAllInstances),
1756
+ val: await this.createListHTMLInstances('allInstancesList', this.listInstanceRaw, this.countAllInstances),
1842
1757
  ack: true,
1843
1758
  });
1844
1759
  await this.setStateChangedAsync(`adapterAndInstances.HTML_Lists.listAllActiveInstancesHTML`, {
1845
- val: await this.createListHTMLInstances('allActiveInstancesList', this.listAllActiveInstances, this.countAllActiveInstances),
1760
+ val: await this.createListHTMLInstances('allActiveInstancesList', this.listInstanceRaw, this.countAllActiveInstances),
1846
1761
  ack: true,
1847
1762
  });
1848
1763
  await this.setStateChangedAsync(`adapterAndInstances.HTML_Lists.listInstancesErrorHTML`, {
1849
- val: await this.createListHTMLInstances('errorInstanceList', this.listErrorInstance, this.countErrorInstance),
1764
+ val: await this.createListHTMLInstances('errorInstanceList', this.listErrorInstanceRaw, this.countErrorInstance),
1850
1765
  ack: true,
1851
1766
  });
1852
1767
  await this.setStateChangedAsync(`adapterAndInstances.HTML_Lists.listDeactivatedInstancesHTML`, {
1853
- val: await this.createListHTMLInstances('deactivatedInstanceList', this.listDeactivatedInstances, this.countDeactivatedInstances),
1768
+ val: await this.createListHTMLInstances('deactivatedInstanceList', this.listInstanceRaw, this.countDeactivatedInstances),
1854
1769
  ack: true,
1855
1770
  });
1856
1771
  await this.setStateChangedAsync(`adapterAndInstances.HTML_Lists.listAdapterUpdatesHTML`, {
1857
- val: await this.createListHTMLInstances('updateAdapterList', this.listAdapterUpdates, this.countAdapterUpdates),
1772
+ val: await this.createListHTMLInstances('updateAdapterList', this.listInstanceRaw, this.countAdapterUpdates),
1858
1773
  ack: true,
1859
1774
  });
1860
1775
  }
@@ -2096,11 +2011,11 @@ class DeviceWatcher extends utils.Adapter {
2096
2011
  }
2097
2012
 
2098
2013
  //subscribe to statechanges
2099
- // this.subscribeForeignStates(id);
2100
- // this.subscribeForeignStates(instanceConnectedHostDP);
2101
- // this.subscribeForeignStates(instanceConnectedDeviceDP);
2014
+ this.subscribeForeignStates(id);
2015
+ this.subscribeForeignStates(instanceConnectedHostDP);
2016
+ this.subscribeForeignStates(instanceConnectedDeviceDP);
2102
2017
  this.subscribeForeignObjects(`system.adapter.*`);
2103
- this.subscribeForeignStates('*');
2018
+ // this.subscribeForeignStates('*');
2104
2019
  // this.subscribeForeignObjects('*');
2105
2020
 
2106
2021
  // create raw list
@@ -2145,36 +2060,29 @@ class DeviceWatcher extends utils.Adapter {
2145
2060
  * @param {string} instanceID
2146
2061
  */
2147
2062
  async checkDaemonIsHealthy(instanceID) {
2148
- const aliveState = await this.getInitValue(`system.adapter.${instanceID}.alive`);
2149
2063
  const connectedHostState = await this.getInitValue(`system.adapter.${instanceID}.connected`);
2064
+ const isAlive = await this.getInitValue(`system.adapter.${instanceID}.alive`);
2150
2065
  let connectedDeviceState = await this.getInitValue(`${instanceID}.info.connection`);
2151
- if (connectedDeviceState === undefined) connectedDeviceState = true;
2152
2066
 
2153
- let isAlive = aliveState;
2067
+ if (connectedDeviceState === undefined) {
2068
+ connectedDeviceState = true;
2069
+ }
2070
+
2154
2071
  let isHealthy = false;
2155
- let instanceStatusString = aliveState ? 'Instanz aktiviert' : 'Instanz deaktiviert';
2072
+ let instanceStatusString = 'Instanz deaktiviert';
2156
2073
 
2157
- if (!aliveState) {
2158
- isAlive = false;
2159
- isHealthy = false;
2160
- instanceStatusString = 'Instanz deaktiviert';
2161
- } else {
2074
+ if (isAlive) {
2162
2075
  if (connectedHostState && connectedDeviceState) {
2163
- isAlive = true;
2164
2076
  isHealthy = true;
2165
2077
  instanceStatusString = 'Instanz okay';
2166
2078
  } else if (!connectedHostState) {
2167
- isAlive = true;
2168
- isHealthy = false;
2169
2079
  instanceStatusString = 'Nicht verbunden mit Host';
2170
2080
  } else if (!connectedDeviceState) {
2171
- isAlive = true;
2172
- isHealthy = false;
2173
2081
  instanceStatusString = 'Nicht verbunden mit Gerät oder Dienst';
2174
2082
  }
2175
2083
  }
2176
2084
 
2177
- return [isAlive, isHealthy, instanceStatusString];
2085
+ return [Boolean(isAlive), Boolean(isHealthy), String(instanceStatusString)];
2178
2086
  }
2179
2087
 
2180
2088
  /**
@@ -2183,40 +2091,26 @@ class DeviceWatcher extends utils.Adapter {
2183
2091
  * @param {number} instanceDeactivationTime
2184
2092
  */
2185
2093
  async checkDaemonIsAlive(instanceID, instanceDeactivationTime) {
2186
- const aliveState = await this.getInitValue(`system.adapter.${instanceID}.alive`);
2094
+ let isAlive = await this.getInitValue(`system.adapter.${instanceID}.alive`);
2187
2095
  let daemonIsAlive;
2188
-
2189
- let isAlive = false;
2190
2096
  let isHealthy = false;
2191
- let instanceStatusString = aliveState ? 'Instanz aktiviert' : 'Instanz deaktiviert';
2097
+ let instanceStatusString = isAlive ? 'Instanz aktiviert' : 'Instanz deaktiviert';
2192
2098
 
2193
- if (aliveState) {
2099
+ if (isAlive) {
2194
2100
  daemonIsAlive = await this.checkDaemonIsHealthy(instanceID);
2195
- isAlive = Boolean(daemonIsAlive[0]);
2196
- isHealthy = Boolean(daemonIsAlive[1]);
2197
- instanceStatusString = String(daemonIsAlive[2]);
2198
- } else if (!aliveState) {
2101
+ } else {
2199
2102
  await this.delay(instanceDeactivationTime);
2200
2103
  daemonIsAlive = await this.checkDaemonIsHealthy(instanceID);
2201
2104
  if (!daemonIsAlive[0]) {
2202
2105
  await this.delay(instanceDeactivationTime);
2203
2106
  daemonIsAlive = await this.checkDaemonIsHealthy(instanceID);
2204
- if (!daemonIsAlive[0]) {
2205
- isAlive = Boolean(daemonIsAlive[0]);
2206
- isHealthy = Boolean(daemonIsAlive[1]);
2207
- instanceStatusString = String(daemonIsAlive[2]);
2208
- } else {
2209
- isAlive = Boolean(daemonIsAlive[0]);
2210
- isHealthy = Boolean(daemonIsAlive[1]);
2211
- instanceStatusString = String(daemonIsAlive[2]);
2212
- }
2213
- } else {
2214
- isAlive = Boolean(daemonIsAlive[0]);
2215
- isHealthy = Boolean(daemonIsAlive[1]);
2216
- instanceStatusString = String(daemonIsAlive[2]);
2217
2107
  }
2218
2108
  }
2219
2109
 
2110
+ isAlive = Boolean(daemonIsAlive[0]);
2111
+ isHealthy = Boolean(daemonIsAlive[1]);
2112
+ instanceStatusString = String(daemonIsAlive[2]);
2113
+
2220
2114
  return [isAlive, isHealthy, instanceStatusString];
2221
2115
  }
2222
2116
 
@@ -2228,7 +2122,6 @@ class DeviceWatcher extends utils.Adapter {
2228
2122
  let isAlive = false;
2229
2123
  let isHealthy = false;
2230
2124
  let instanceStatusString = 'Instanz deaktiviert';
2231
-
2232
2125
  const isAliveSchedule = await this.getForeignStateAsync(`system.adapter.${instanceID}.alive`);
2233
2126
 
2234
2127
  if (isAliveSchedule) {
@@ -2256,75 +2149,64 @@ class DeviceWatcher extends utils.Adapter {
2256
2149
  * @param {any} instanceID
2257
2150
  */
2258
2151
  async setInstanceStatus(instanceMode, scheduleTime, instanceID) {
2259
- let instanceStatusString = 'Instanz deaktiviert';
2260
- let isAlive = false;
2261
- let isHealthy = false;
2262
- let scheduleIsAlive;
2263
- let daemonIsAlive;
2264
- let daemonIsNotAlive;
2265
2152
  let instanceDeactivationTime = (this.config.offlineTimeInstances * 1000) / 2;
2266
2153
  let instanceErrorTime = (this.config.errorTimeInstances * 1000) / 2;
2154
+
2155
+ const checkScheduleIsHealthy = async () => {
2156
+ const scheduleIsAlive = await this.checkScheduleisHealty(instanceID, scheduleTime);
2157
+ return {
2158
+ isAlive: Boolean(scheduleIsAlive[0]),
2159
+ isHealthy: Boolean(scheduleIsAlive[1]),
2160
+ instanceStatusString: String(scheduleIsAlive[2]),
2161
+ };
2162
+ };
2163
+
2164
+ const checkDaemonIsHealthy = async () => {
2165
+ const daemonIsAlive = await this.checkDaemonIsHealthy(instanceID);
2166
+
2167
+ if (daemonIsAlive[0] && !daemonIsAlive[1]) {
2168
+ await this.delay(instanceErrorTime);
2169
+ const daemonIsAliveAfterDelay = await this.checkDaemonIsHealthy(instanceID);
2170
+
2171
+ if (daemonIsAliveAfterDelay[0] && !daemonIsAliveAfterDelay[1]) {
2172
+ await this.delay(instanceErrorTime);
2173
+ const daemonIsAliveAfterSecondDelay = await this.checkDaemonIsHealthy(instanceID);
2174
+
2175
+ if (daemonIsAliveAfterSecondDelay[0] && !daemonIsAliveAfterSecondDelay[1]) {
2176
+ return {
2177
+ isAlive: Boolean(daemonIsAliveAfterSecondDelay[0]),
2178
+ isHealthy: Boolean(daemonIsAliveAfterSecondDelay[1]),
2179
+ instanceStatusString: String(daemonIsAliveAfterSecondDelay[2]),
2180
+ };
2181
+ }
2182
+ }
2183
+ }
2184
+
2185
+ const daemonIsNotAlive = await this.checkDaemonIsAlive(instanceID, instanceDeactivationTime);
2186
+ return {
2187
+ isAlive: Boolean(daemonIsNotAlive[0]),
2188
+ isHealthy: Boolean(daemonIsNotAlive[1]),
2189
+ instanceStatusString: String(daemonIsNotAlive[2]),
2190
+ };
2191
+ };
2192
+
2193
+ let isAlive = false;
2194
+ let isHealthy = false;
2195
+ let instanceStatusString = 'Instanz deaktiviert';
2196
+
2267
2197
  switch (instanceMode) {
2268
2198
  case 'schedule':
2269
- scheduleIsAlive = await this.checkScheduleisHealty(instanceID, scheduleTime);
2270
- isAlive = Boolean(scheduleIsAlive[0]);
2271
- isHealthy = Boolean(scheduleIsAlive[1]);
2272
- instanceStatusString = String(scheduleIsAlive[2]);
2199
+ ({ isAlive, isHealthy, instanceStatusString } = await checkScheduleIsHealthy());
2273
2200
  break;
2274
2201
  case 'daemon':
2275
2202
  // check with time the user did define for error and deactivation
2276
2203
  if (this.userTimeInstancesList.has(instanceID)) {
2277
- // User set own setting for deactivation time
2278
- instanceDeactivationTime = this.userTimeInstancesList.get(instanceID).deactivationTime;
2279
- instanceDeactivationTime = (instanceDeactivationTime * 1000) / 2; // calculate sec to ms and divide into two
2280
-
2281
- // User set own setting for error time
2282
- instanceErrorTime = this.userTimeInstancesList.get(instanceID).errorTime;
2283
- instanceErrorTime = (instanceErrorTime * 1000) / 2; // calculate sec to ms and divide into two
2284
- }
2285
- daemonIsAlive = await this.checkDaemonIsHealthy(instanceID);
2286
- if (daemonIsAlive[0]) {
2287
- if (daemonIsAlive[1]) {
2288
- isAlive = Boolean(daemonIsAlive[0]);
2289
- isHealthy = Boolean(daemonIsAlive[1]);
2290
- instanceStatusString = String(daemonIsAlive[2]);
2291
- } else if (daemonIsAlive[0] && !daemonIsAlive[1]) {
2292
- // wait first time
2293
- await this.delay(instanceErrorTime);
2294
- daemonIsAlive = await this.checkDaemonIsHealthy(instanceID);
2295
- if (daemonIsAlive[0] && !daemonIsAlive[1]) {
2296
- // wait second time
2297
- await this.delay(instanceErrorTime);
2298
- daemonIsAlive = await this.checkDaemonIsHealthy(instanceID);
2299
- if (daemonIsAlive[0] && !daemonIsAlive[1]) {
2300
- // finally
2301
- isAlive = Boolean(daemonIsAlive[0]);
2302
- isHealthy = Boolean(daemonIsAlive[1]);
2303
- instanceStatusString = String(daemonIsAlive[2]);
2304
- } else if (!daemonIsAlive[0]) {
2305
- daemonIsNotAlive = await this.checkDaemonIsAlive(instanceID, instanceDeactivationTime);
2306
- isAlive = Boolean(daemonIsNotAlive[0]);
2307
- isHealthy = Boolean(daemonIsNotAlive[1]);
2308
- instanceStatusString = String(daemonIsNotAlive[2]);
2309
- }
2310
- } else if (!daemonIsAlive[0]) {
2311
- daemonIsNotAlive = await this.checkDaemonIsAlive(instanceID, instanceDeactivationTime);
2312
- isAlive = Boolean(daemonIsNotAlive[0]);
2313
- isHealthy = Boolean(daemonIsNotAlive[1]);
2314
- instanceStatusString = String(daemonIsNotAlive[2]);
2315
- }
2316
- } else if (!daemonIsAlive[0]) {
2317
- daemonIsNotAlive = await this.checkDaemonIsAlive(instanceID, instanceDeactivationTime);
2318
- isAlive = Boolean(daemonIsNotAlive[0]);
2319
- isHealthy = Boolean(daemonIsNotAlive[1]);
2320
- instanceStatusString = String(daemonIsNotAlive[2]);
2321
- }
2322
- } else if (!daemonIsAlive[0]) {
2323
- daemonIsNotAlive = await this.checkDaemonIsAlive(instanceID, instanceDeactivationTime);
2324
- isAlive = Boolean(daemonIsNotAlive[0]);
2325
- isHealthy = Boolean(daemonIsNotAlive[1]);
2326
- instanceStatusString = String(daemonIsNotAlive[2]);
2204
+ const userTimeInstances = this.userTimeInstancesList.get(instanceID);
2205
+ instanceDeactivationTime = (userTimeInstances.deactivationTime * 1000) / 2;
2206
+ instanceErrorTime = (userTimeInstances.errorTime * 1000) / 2;
2327
2207
  }
2208
+
2209
+ ({ isAlive, isHealthy, instanceStatusString } = await checkDaemonIsHealthy());
2328
2210
  break;
2329
2211
  }
2330
2212
 
@@ -2335,10 +2217,9 @@ class DeviceWatcher extends utils.Adapter {
2335
2217
  * create adapter update data
2336
2218
  */
2337
2219
  async createAdapterUpdateData() {
2338
- const adapterUpdateListDP = `admin.*.info.updatesJson`;
2339
-
2220
+ const adapterUpdateListDP = 'admin.*.info.updatesJson';
2340
2221
  // subscribe to datapoint
2341
- // this.subscribeForeignStates(adapterUpdateListDP);
2222
+ this.subscribeForeignStates(adapterUpdateListDP);
2342
2223
 
2343
2224
  await this.getAdapterUpdateData(adapterUpdateListDP);
2344
2225
 
@@ -2350,24 +2231,30 @@ class DeviceWatcher extends utils.Adapter {
2350
2231
  * @param {string} adapterUpdateListDP
2351
2232
  */
2352
2233
  async getAdapterUpdateData(adapterUpdateListDP) {
2234
+ // Clear the existing adapter updates data
2353
2235
  this.adapterUpdatesJsonRaw.clear();
2236
+
2237
+ // Fetch the adapter updates list
2354
2238
  const adapterUpdatesListVal = await this.getForeignStatesAsync(adapterUpdateListDP);
2355
2239
 
2356
2240
  let adapterJsonList;
2357
2241
  let adapterUpdatesJsonPath;
2358
2242
 
2359
- for (const [id] of Object.entries(adapterUpdatesListVal)) {
2360
- adapterJsonList = this.parseData(adapterUpdatesListVal[id].val);
2243
+ // Extract adapter data from the list
2244
+ for (const [id, value] of Object.entries(adapterUpdatesListVal)) {
2245
+ adapterJsonList = this.parseData(value.val);
2361
2246
  adapterUpdatesJsonPath = id;
2362
2247
  }
2363
2248
 
2364
- for (const [id] of Object.entries(adapterJsonList)) {
2249
+ // Populate the adapter updates data
2250
+ for (const [id, adapterData] of Object.entries(adapterJsonList)) {
2365
2251
  this.adapterUpdatesJsonRaw.set(this.capitalize(id), {
2366
2252
  Path: adapterUpdatesJsonPath,
2367
- newVersion: adapterJsonList[id].availableVersion,
2368
- oldVersion: adapterJsonList[id].installedVersion,
2253
+ newVersion: adapterData.availableVersion,
2254
+ oldVersion: adapterData.installedVersion,
2369
2255
  });
2370
2256
  }
2257
+
2371
2258
  return this.adapterUpdatesJsonRaw;
2372
2259
  }
2373
2260
 
@@ -2380,7 +2267,7 @@ class DeviceWatcher extends utils.Adapter {
2380
2267
 
2381
2268
  for (const [adapter, updateData] of this.adapterUpdatesJsonRaw) {
2382
2269
  this.listAdapterUpdates.push({
2383
- Adapter: adapter,
2270
+ [translations.Adapter[this.language]]: adapter,
2384
2271
  'Available Version': updateData.newVersion,
2385
2272
  'Installed Version': updateData.oldVersion,
2386
2273
  });
@@ -2398,7 +2285,7 @@ class DeviceWatcher extends utils.Adapter {
2398
2285
 
2399
2286
  // list deactivated instances
2400
2287
  if (this.countAdapterUpdates === 0) {
2401
- this.listAdapterUpdates = [{ Adapter: '--none--', 'Available Version': '', 'Installed Version': '' }];
2288
+ this.listAdapterUpdates = [{ [translations.Adapter[this.language]]: '--none--', 'Available Version': '', 'Installed Version': '' }];
2402
2289
  }
2403
2290
  await this.setStateChangedAsync(`adapterAndInstances.listAdapterUpdates`, { val: JSON.stringify(this.listAdapterUpdates), ack: true });
2404
2291
  }
@@ -2427,40 +2314,40 @@ class DeviceWatcher extends utils.Adapter {
2427
2314
  if (this.blacklistInstancesLists.includes(instance)) continue;
2428
2315
  // all instances
2429
2316
  this.listAllInstances.push({
2430
- Adapter: instanceData.Adapter,
2431
- Instance: instance,
2432
- Mode: instanceData.instanceMode,
2433
- Schedule: instanceData.schedule,
2434
- Version: instanceData.adapterVersion,
2435
- Updateable: instanceData.updateAvailable,
2436
- Status: instanceData.status,
2317
+ [translations.Adapter[this.language]]: instanceData.Adapter,
2318
+ [translations.Instance[this.language]]: instance,
2319
+ [translations.Mode[this.language]]: instanceData.instanceMode,
2320
+ [translations.Schedule[this.language]]: instanceData.schedule,
2321
+ [translations.Version[this.language]]: instanceData.adapterVersion,
2322
+ [translations.Updateable[this.language]]: instanceData.updateAvailable,
2323
+ [translations.Status[this.language]]: instanceData.status,
2437
2324
  });
2438
2325
 
2439
2326
  if (!instanceData.isAlive) {
2440
2327
  // list with deactivated instances
2441
2328
  this.listDeactivatedInstances.push({
2442
- Adapter: instanceData.Adapter,
2443
- Instance: instance,
2444
- Status: instanceData.status,
2329
+ [translations.Adapter[this.language]]: instanceData.Adapter,
2330
+ [translations.Instance[this.language]]: instance,
2331
+ [translations.Status[this.language]]: instanceData.status,
2445
2332
  });
2446
2333
  } else {
2447
2334
  // list with active instances
2448
2335
  this.listAllActiveInstances.push({
2449
- Adapter: instanceData.Adapter,
2450
- Instance: instance,
2451
- Mode: instanceData.instanceMode,
2452
- Schedule: instanceData.schedule,
2453
- Status: instanceData.status,
2336
+ [translations.Adapter[this.language]]: instanceData.Adapter,
2337
+ [translations.Instance[this.language]]: instance,
2338
+ [translations.Mode[this.language]]: instanceData.instanceMode,
2339
+ [translations.Schedule[this.language]]: instanceData.schedule,
2340
+ [translations.Status[this.language]]: instanceData.status,
2454
2341
  });
2455
2342
  }
2456
2343
 
2457
2344
  // list with error instances
2458
2345
  if (instanceData.isAlive && !instanceData.isHealthy) {
2459
2346
  this.listErrorInstance.push({
2460
- Adapter: instanceData.Adapter,
2461
- Instance: instance,
2462
- Mode: instanceData.instanceMode,
2463
- Status: instanceData.status,
2347
+ [translations.Adapter[this.language]]: instanceData.Adapter,
2348
+ [translations.Instance[this.language]]: instance,
2349
+ [translations.Mode[this.language]]: instanceData.instanceMode,
2350
+ [translations.Status[this.language]]: instanceData.status,
2464
2351
  });
2465
2352
  }
2466
2353
  }
@@ -2496,14 +2383,18 @@ class DeviceWatcher extends utils.Adapter {
2496
2383
 
2497
2384
  // list deactivated instances
2498
2385
  if (this.countDeactivatedInstances === 0) {
2499
- this.listDeactivatedInstances = [{ Adapter: '--none--', Instance: '', Version: '', Status: '' }];
2386
+ this.listDeactivatedInstances = [
2387
+ { [translations.Adapter[this.language]]: '--none--', [translations.Instance[this.language]]: '', [translations.Version[this.language]]: '', [translations.Status[this.language]]: '' },
2388
+ ];
2500
2389
  }
2501
2390
  await this.setStateChangedAsync(`adapterAndInstances.listDeactivatedInstances`, { val: JSON.stringify(this.listDeactivatedInstances), ack: true });
2502
2391
  await this.setStateChangedAsync(`adapterAndInstances.countDeactivatedInstances`, { val: this.countDeactivatedInstances, ack: true });
2503
2392
 
2504
2393
  // list error instances
2505
2394
  if (this.countErrorInstance === 0) {
2506
- this.listErrorInstance = [{ Adapter: '--none--', Instance: '', Mode: '', Status: '' }];
2395
+ this.listErrorInstance = [
2396
+ { [translations.Adapter[this.language]]: '--none--', [translations.Instance[this.language]]: '', [translations.Mode[this.language]]: '', [translations.Status[this.language]]: '' },
2397
+ ];
2507
2398
  }
2508
2399
  await this.setStateChangedAsync(`adapterAndInstances.listInstancesError`, { val: JSON.stringify(this.listErrorInstance), ack: true });
2509
2400
  await this.setStateChangedAsync(`adapterAndInstances.countInstancesError`, { val: this.countErrorInstance, ack: true });
@@ -2513,16 +2404,26 @@ class DeviceWatcher extends utils.Adapter {
2513
2404
  * @param {string} id
2514
2405
  */
2515
2406
  async renewAdapterUpdateData(id) {
2516
- const oldAdapterUpdatesCounts = this.countAdapterUpdates;
2407
+ const previousAdapterUpdatesCount = this.countAdapterUpdates;
2408
+
2409
+ // Fetch and process adapter update data
2517
2410
  await this.getAdapterUpdateData(id);
2518
2411
  await this.createAdapterUpdateList();
2519
- if (this.config.checkSendAdapterUpdateMsg && this.countAdapterUpdates > oldAdapterUpdatesCounts) {
2412
+
2413
+ // Check and send update notification if required
2414
+ if (this.config.checkSendAdapterUpdateMsg && this.countAdapterUpdates > previousAdapterUpdatesCount) {
2520
2415
  await this.sendStateNotifications('updateAdapter', null);
2521
2416
  }
2522
- this.listInstanceRaw.forEach((instance) => {
2523
- const adapterUpdate = this.adapterUpdatesJsonRaw.get(instance.Adapter);
2524
- instance.updateAvailable = adapterUpdate ? adapterUpdate.newVersion : ' - ';
2525
- });
2417
+
2418
+ // Update instances with available adapter updates
2419
+ for (const instance of this.listInstanceRaw.values()) {
2420
+ if (this.adapterUpdatesJsonRaw.has(instance.Adapter)) {
2421
+ const adapterUpdate = this.adapterUpdatesJsonRaw.get(instance.Adapter);
2422
+ instance.updateAvailable = adapterUpdate.newVersion;
2423
+ } else {
2424
+ instance.updateAvailable = ' - ';
2425
+ }
2426
+ }
2526
2427
  }
2527
2428
  /**
2528
2429
  * call function on state change, renew data and send messages
@@ -3069,72 +2970,54 @@ class DeviceWatcher extends utils.Adapter {
3069
2970
  */
3070
2971
  async sendStateNotifications(type, id) {
3071
2972
  if (isUnloaded) return;
3072
- let objectData;
2973
+
2974
+ let objectData = this.listAllDevicesRaw.get(id);
2975
+ const adapterName = this.config.showAdapterNameinMsg ? `${objectData.Adapter}: ` : '';
3073
2976
  let list = '';
3074
2977
  let message = '';
3075
- const setMessage = async (/** @type {string} */ message) => {
3076
- this.log.info(`${message}`);
3077
- await this.setStateAsync('lastNotification', `${message}`, true);
3078
- await this.sendNotification(`${message}`);
3079
- return (message = '');
2978
+
2979
+ const setMessage = async (message) => {
2980
+ this.log.info(message);
2981
+ await this.setStateAsync('lastNotification', message, true);
2982
+ await this.sendNotification(message);
3080
2983
  };
2984
+
3081
2985
  switch (type) {
3082
2986
  case 'lowBatDevice':
3083
- objectData = this.listAllDevicesRaw.get(id);
3084
- if (!this.config.showAdapterNameinMsg) {
3085
- message = `Gerät mit geringer Batterie erkannt: \n${objectData.Device} (${objectData.Battery})`;
3086
- } else {
3087
- message = `Gerät mit geringer Batterie erkannt: \n${objectData.Adapter}: ${objectData.Device} (${objectData.Battery})`;
3088
- }
2987
+ message = `${translations.Device_low_bat_detected[this.language]}: \n${adapterName} ${objectData.Device} (${objectData.Battery})`;
3089
2988
  setMessage(message);
3090
2989
  break;
2990
+
3091
2991
  case 'onlineStateDevice':
3092
- objectData = this.listAllDevicesRaw.get(id);
3093
2992
  switch (objectData.Status) {
3094
2993
  case 'Online':
3095
- if (!this.config.showAdapterNameinMsg) {
3096
- message = `Folgendes Gerät ist wieder erreichbar: \n${objectData.Device} (${objectData.LastContact})`;
3097
- } else {
3098
- message = `Folgendes Gerät ist wieder erreichbar: \n${objectData.Adapter}: ${objectData.Device} (${objectData.LastContact})`;
3099
- }
2994
+ message = `${translations.Device_available_again[this.language]}: \n${adapterName} ${objectData.Device} (${objectData.LastContact})`;
3100
2995
  break;
2996
+
3101
2997
  case 'Offline':
3102
- if (!this.config.showAdapterNameinMsg) {
3103
- message = `Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n${objectData.Device} (${objectData.LastContact})`;
3104
- } else {
3105
- message = `Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n${objectData.Adapter}: ${objectData.Device} (${objectData.LastContact})`;
3106
- }
2998
+ message = `${translations.Device_not_reachable[this.language]}: \n${adapterName} ${objectData.Device} (${objectData.LastContact})`;
3107
2999
  break;
3108
3000
  }
3109
3001
  setMessage(message);
3110
3002
  break;
3003
+
3111
3004
  case 'updateDevice':
3112
- objectData = this.listAllDevicesRaw.get(id);
3113
- if (!this.config.showAdapterNameinMsg) {
3114
- message = `Neue Geräte Updates vorhanden: \n${objectData.Device}`;
3115
- } else {
3116
- message = `Neue Geräte Updates vorhanden: \n${objectData.Adapter}: ${objectData.Device}`;
3117
- }
3005
+ message = `${translations.Device_new_updates[this.language]}: \n${adapterName} ${objectData.Device}`;
3118
3006
  setMessage(message);
3119
3007
  break;
3008
+
3120
3009
  case 'updateAdapter':
3121
3010
  if (this.countAdapterUpdates === 0) return;
3122
- objectData = this.listAdapterUpdates;
3123
- list = '';
3124
- for (const id of objectData) {
3125
- list = `${list}\n${id.Adapter}: v${id['Available Version']}`;
3126
- }
3127
- message = `Neue Adapter Updates vorhanden: ${list}`;
3011
+
3012
+ list = objectData.map((id) => `${id.Adapter}: v${id['Available Version']}`).join('\n');
3013
+ message = `${translations.Adapter_new_updates[this.language]}: ${list}`;
3128
3014
  setMessage(message);
3129
3015
  break;
3016
+
3130
3017
  case 'errorInstance':
3131
- objectData = this.listInstanceRaw.get(id);
3132
- message = `Instanz Watchdog:\n${id}: ${objectData.status}`;
3133
- setMessage(message);
3134
- break;
3135
3018
  case 'deactivatedInstance':
3136
3019
  objectData = this.listInstanceRaw.get(id);
3137
- message = `Instanz Watchdog:\n${id}: ${objectData.status}`;
3020
+ message = `${translations.Instance_Watchdog[this.language]}:\n${id}: ${objectData.status}`;
3138
3021
  setMessage(message);
3139
3022
  break;
3140
3023
  }
@@ -3144,275 +3027,146 @@ class DeviceWatcher extends utils.Adapter {
3144
3027
  * Notifications per user defined schedule
3145
3028
  * @param {string} type
3146
3029
  */
3147
- sendScheduleNotifications(type) {
3030
+ async sendScheduleNotifications(type) {
3148
3031
  if (isUnloaded) return;
3149
3032
 
3150
- let time;
3151
- let cron;
3033
+ const checkDays = [];
3034
+ const dayConfigKeys = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
3152
3035
  let list = '';
3153
3036
  let message = '';
3154
- const checkDays = [];
3037
+
3155
3038
  const setMessage = async (message) => {
3156
- this.log.info(`${message}`);
3157
- await this.setStateAsync('lastNotification', `${message}`, true);
3158
- await this.sendNotification(`${message}`);
3159
- return (message = '');
3039
+ this.log.info(message);
3040
+ await this.setStateAsync('lastNotification', message, true);
3041
+ await this.sendNotification(message);
3042
+ };
3043
+
3044
+ const processDeviceList = (deviceList, property1, property2) => {
3045
+ for (const id of deviceList) {
3046
+ if (this.blacklistNotify.includes(id.Path)) continue;
3047
+ list += `\n${!this.config.showAdapterNameinMsg ? '' : id.Adapter + ': '}${id[property1]}${property2 ? ` (${id[property2]})` : ''}`;
3048
+ }
3049
+ };
3050
+
3051
+ const processInstanceList = (instanceList, property) => {
3052
+ for (const id of instanceList) {
3053
+ if (this.blacklistInstancesNotify.includes(id[translations['Instance'][this.language]])) continue;
3054
+ list += `\n${id[translations['Instance'][this.language]]}${property ? `: ${id[property]}` : ''}`;
3055
+ }
3056
+ };
3057
+
3058
+ const processNotification = (list, messageType) => {
3059
+ if (list.length === 0) return;
3060
+
3061
+ switch (checkDays.length) {
3062
+ case 1:
3063
+ message = `${translations.Weekly_overview[this.language]} ${translations[messageType][this.language]}: ${list}`;
3064
+ break;
3065
+ case 7:
3066
+ message = `${translations.Daily_overview[this.language]} ${translations[messageType][this.language]}: ${list}`;
3067
+ break;
3068
+ default:
3069
+ message = `${translations.Overview_of[this.language]} ${translations[messageType][this.language]}: ${list}`;
3070
+ break;
3071
+ }
3072
+
3073
+ setMessage(message);
3160
3074
  };
3161
3075
 
3162
3076
  switch (type) {
3163
3077
  case 'lowBatteryDevices':
3164
- // push the selected days in list
3165
- if (this.config.checkMonday) checkDays.push(1);
3166
- if (this.config.checkTuesday) checkDays.push(2);
3167
- if (this.config.checkWednesday) checkDays.push(3);
3168
- if (this.config.checkThursday) checkDays.push(4);
3169
- if (this.config.checkFriday) checkDays.push(5);
3170
- if (this.config.checkSaturday) checkDays.push(6);
3171
- if (this.config.checkSunday) checkDays.push(0);
3172
-
3173
- time = this.config.checkSendBatteryTime.split(':');
3078
+ checkDays.push(...dayConfigKeys.map((day, index) => (this.config['check' + day] ? index : null)).filter((day) => day !== null));
3174
3079
 
3175
3080
  if (checkDays.length === 0) {
3176
3081
  this.log.warn(`No days selected for daily low battery devices message. Please check the instance configuration!`);
3177
- return; // cancel function if no day is selected
3082
+ return;
3178
3083
  }
3179
3084
  this.log.debug(`Number of selected days for daily low battery devices message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
3180
3085
 
3181
- cron = '1 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
3182
- schedule.scheduleJob(cron, () => {
3183
- list = '';
3184
- for (const id of this.batteryLowPoweredRaw) {
3185
- if (this.blacklistNotify.includes(id.Path)) continue;
3186
- if (!this.config.showAdapterNameinMsg) {
3187
- list = `${list}\n${id.Device} (${id.Battery})`;
3188
- } else {
3189
- // Add adaptername if checkbox is checked true in options by user
3190
- list = `${list}\n${id.Adapter}: ${id.Device} (${id.Battery})`;
3191
- }
3192
- }
3193
- if (list.length === 0) return;
3086
+ schedule.scheduleJob(`1 ${this.config.checkSendBatteryTime.split(':').reverse().join(' ')} * * ${checkDays.join(',')}`, () => {
3087
+ processDeviceList(this.batteryLowPoweredRaw, 'Device', 'Battery');
3194
3088
 
3195
- switch (checkDays.length) {
3196
- case 1:
3197
- message = `Wöchentliche Übersicht über Geräte mit niedrigen Batteriezuständen: ${list}`;
3198
- break;
3199
- case 7:
3200
- message = `Tägliche Übersicht über Geräte mit niedrigen Batteriezuständen: ${list}`;
3201
- break;
3202
- default:
3203
- message = `Übersicht über Geräte mit niedrigen Batteriezuständen: ${list}`;
3204
- break;
3205
- }
3206
- setMessage(message);
3089
+ processNotification(list, 'devices_low_bat');
3207
3090
  });
3208
3091
  break;
3209
3092
 
3210
3093
  case 'offlineDevices':
3211
- // push the selected days in list
3212
- if (this.config.checkOfflineMonday) checkDays.push(1);
3213
- if (this.config.checkOfflineTuesday) checkDays.push(2);
3214
- if (this.config.checkOfflineWednesday) checkDays.push(3);
3215
- if (this.config.checkOfflineThursday) checkDays.push(4);
3216
- if (this.config.checkOfflineFriday) checkDays.push(5);
3217
- if (this.config.checkOfflineSaturday) checkDays.push(6);
3218
- if (this.config.checkOfflineSunday) checkDays.push(0);
3219
-
3220
- time = this.config.checkSendOfflineTime.split(':');
3094
+ checkDays.push(...dayConfigKeys.map((day, index) => (this.config['checkOffline' + day] ? index : null)).filter((day) => day !== null));
3221
3095
 
3222
3096
  if (checkDays.length === 0) {
3223
3097
  this.log.warn(`No days selected for daily offline devices message. Please check the instance configuration!`);
3224
- return; // cancel function if no day is selected
3098
+ return;
3225
3099
  }
3226
3100
  this.log.debug(`Number of selected days for daily offline devices message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
3227
3101
 
3228
- cron = '2 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
3229
- schedule.scheduleJob(cron, () => {
3230
- list = '';
3231
-
3232
- for (const id of this.offlineDevicesRaw) {
3233
- if (this.blacklistNotify.includes(id.Path)) continue;
3234
- if (!this.config.showAdapterNameinMsg) {
3235
- list = `${list}\n${id.Device} (${id.LastContact})`;
3236
- } else {
3237
- list = `${list}\n${id.Adapter}: ${id.Device} (${id.LastContact})`;
3238
- }
3239
- }
3102
+ schedule.scheduleJob(`2 ${this.config.checkSendOfflineTime.split(':').reverse().join(' ')} * * ${checkDays.join(',')}`, () => {
3103
+ processDeviceList(this.offlineDevicesRaw, `Device`, 'LastContact');
3240
3104
 
3241
- if (list.length === 0) return;
3242
-
3243
- switch (checkDays.length) {
3244
- case 1:
3245
- message = `Wöchentliche Übersicht über offline Geräte: ${list}`;
3246
- break;
3247
- case 7:
3248
- message = `Tägliche Übersicht über offline Geräte: ${list}`;
3249
- break;
3250
- default:
3251
- message = `Übersicht über offline Geräte: ${list}`;
3252
- break;
3253
- }
3254
- setMessage(message);
3105
+ processNotification(list, 'offline_devices');
3255
3106
  });
3256
3107
  break;
3257
3108
 
3258
3109
  case 'updateDevices':
3259
- // push the selected days in list
3260
- if (this.config.checkUpgradeMonday) checkDays.push(1);
3261
- if (this.config.checkUpgradeTuesday) checkDays.push(2);
3262
- if (this.config.checkUpgradeWednesday) checkDays.push(3);
3263
- if (this.config.checkUpgradeThursday) checkDays.push(4);
3264
- if (this.config.checkUpgradeFriday) checkDays.push(5);
3265
- if (this.config.checkUpgradeSaturday) checkDays.push(6);
3266
- if (this.config.checkUpgradeSunday) checkDays.push(0);
3267
-
3268
- time = this.config.checkSendUpgradeTime.split(':');
3110
+ checkDays.push(...dayConfigKeys.map((day, index) => (this.config['checkUpgrade' + day] ? index : null)).filter((day) => day !== null));
3269
3111
 
3270
3112
  if (checkDays.length === 0) {
3271
3113
  this.log.warn(`No days selected for daily updatable devices message. Please check the instance configuration!`);
3272
- return; // cancel function if no day is selected
3114
+ return;
3273
3115
  }
3274
3116
  this.log.debug(`Number of selected days for daily updatable devices message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
3275
3117
 
3276
- cron = '3 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
3277
- schedule.scheduleJob(cron, () => {
3278
- list = '';
3118
+ schedule.scheduleJob(`3 ${this.config.checkSendUpgradeTime.split(':').reverse().join(' ')} * * ${checkDays.join(',')}`, () => {
3119
+ processDeviceList(this.upgradableDevicesRaw, 'Device');
3279
3120
 
3280
- for (const id of this.upgradableDevicesRaw) {
3281
- if (this.blacklistNotify.includes(id.Path)) continue;
3282
- if (!this.config.showAdapterNameinMsg) {
3283
- list = `${list}\n${id.Device}`;
3284
- } else {
3285
- list = `${list}\n${id.Adapter}: ${id.Device}`;
3286
- }
3287
- }
3288
- if (list.length === 0) return;
3289
-
3290
- switch (checkDays.length) {
3291
- case 1:
3292
- message = `Wöchentliche Übersicht über verfügbare Geräte Updates: ${list}`;
3293
- break;
3294
- case 7:
3295
- message = `Tägliche Übersicht über verfügbare Geräte Updates: ${list}`;
3296
- break;
3297
- default:
3298
- message = `Übersicht über verfügbare Geräte Updates: ${list}`;
3299
- break;
3300
- }
3301
- setMessage(message);
3121
+ processNotification(list, 'available_updatable_devices');
3302
3122
  });
3303
3123
  break;
3304
3124
 
3305
3125
  case 'updateAdapter':
3306
- // push the selected days in list
3307
- if (this.config.checkAdapterUpdateMonday) checkDays.push(1);
3308
- if (this.config.checkAdapterUpdateTuesday) checkDays.push(2);
3309
- if (this.config.checkAdapterUpdateWednesday) checkDays.push(3);
3310
- if (this.config.checkAdapterUpdateThursday) checkDays.push(4);
3311
- if (this.config.checkAdapterUpdateFriday) checkDays.push(5);
3312
- if (this.config.checkAdapterUpdateSaturday) checkDays.push(6);
3313
- if (this.config.checkAdapterUpdateSunday) checkDays.push(0);
3314
-
3315
- time = this.config.checkSendAdapterUpdateTime.split(':');
3126
+ checkDays.push(...dayConfigKeys.map((day, index) => (this.config['checkAdapterUpdate' + day] ? index : null)).filter((day) => day !== null));
3316
3127
 
3317
3128
  if (checkDays.length === 0) {
3318
3129
  this.log.warn(`No days selected for daily adapter update message. Please check the instance configuration!`);
3319
- return; // cancel function if no day is selected
3130
+ return;
3320
3131
  }
3321
3132
  this.log.debug(`Number of selected days for daily adapter update message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
3322
3133
 
3323
- cron = '4 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
3324
- schedule.scheduleJob(cron, () => {
3325
- list = '';
3134
+ schedule.scheduleJob(`4 ${this.config.checkSendAdapterUpdateTime.split(':').reverse().join(' ')} * * ${checkDays.join(',')}`, () => {
3135
+ processDeviceList(this.listAdapterUpdates, translations.Adapter[this.language], translations.Available_Version[this.language]);
3326
3136
 
3327
- for (const id of this.listAdapterUpdates) {
3328
- list = `${list}\n${id.Adapter}: v${id['Available Version']}`;
3329
- }
3330
- if (list.length === 0) return;
3331
-
3332
- switch (checkDays.length) {
3333
- case 1:
3334
- message = `Wöchentliche Übersicht über verfügbare Adapter Updates: ${list}`;
3335
- break;
3336
- case 7:
3337
- message = `Tägliche Übersicht über verfügbare Adapter Updates: ${list}`;
3338
- break;
3339
- default:
3340
- message = `Übersicht über verfügbare Adapter Updates: ${list}`;
3341
- break;
3342
- }
3343
- setMessage(message);
3137
+ processNotification(list, 'available_adapter_update');
3344
3138
  });
3345
3139
  break;
3346
3140
 
3347
3141
  case 'errorInstance':
3348
- // push the selected days in list
3349
- if (this.config.checkFailedInstancesMonday) checkDays.push(1);
3350
- if (this.config.checkFailedInstancesTuesday) checkDays.push(2);
3351
- if (this.config.checkFailedInstancesWednesday) checkDays.push(3);
3352
- if (this.config.checkFailedInstancesThursday) checkDays.push(4);
3353
- if (this.config.checkFailedInstancesFriday) checkDays.push(5);
3354
- if (this.config.checkFailedInstancesSaturday) checkDays.push(6);
3355
- if (this.config.checkFailedInstancesSunday) checkDays.push(0);
3356
-
3357
- time = this.config.checkSendInstanceFailedTime.split(':');
3142
+ checkDays.push(...dayConfigKeys.map((day, index) => (this.config['checkFailedInstances' + day] ? index : null)).filter((day) => day !== null));
3358
3143
 
3359
3144
  if (checkDays.length === 0) {
3360
3145
  this.log.warn(`No days selected for daily instance error message. Please check the instance configuration!`);
3361
- return; // cancel function if no day is selected
3146
+ return;
3362
3147
  }
3363
3148
  this.log.debug(`Number of selected days for daily instance error message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
3364
- cron = '5 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
3365
- schedule.scheduleJob(cron, () => {
3366
- list = '';
3367
3149
 
3368
- for (const id of this.listErrorInstanceRaw) {
3369
- if (this.blacklistInstancesNotify.includes(id)) continue;
3370
- list = `${list}\n${id.Instance}: ${id.Status}`;
3371
- }
3372
- if (list.length === 0) return;
3373
- message = `Tägliche Meldung über fehlerhafte Instanzen: ${list}`;
3374
- setMessage(message);
3150
+ schedule.scheduleJob(`5 ${this.config.checkSendInstanceFailedTime.split(':').reverse().join(' ')} * * ${checkDays.join(',')}`, () => {
3151
+ processInstanceList(this.listErrorInstanceRaw, 'Status');
3152
+
3153
+ processNotification(list, 'error_instances_msg');
3375
3154
  });
3376
3155
  break;
3377
- case 'deactivatedInstance':
3378
- // push the selected days in list
3379
- if (this.config.checkInstanceDeactivatedMonday) checkDays.push(1);
3380
- if (this.config.checkInstanceDeactivatedTuesday) checkDays.push(2);
3381
- if (this.config.checkInstanceDeactivatedWednesday) checkDays.push(3);
3382
- if (this.config.checkInstanceDeactivatedThursday) checkDays.push(4);
3383
- if (this.config.checkInstanceDeactivatedFriday) checkDays.push(5);
3384
- if (this.config.checkInstanceDeactivatedSaturday) checkDays.push(6);
3385
- if (this.config.checkInstanceDeactivatedSunday) checkDays.push(0);
3386
3156
 
3387
- time = this.config.checkSendInstanceDeactivatedTime.split(':');
3157
+ case 'deactivatedInstance':
3158
+ checkDays.push(...dayConfigKeys.map((day, index) => (this.config['checkInstanceDeactivated' + day] ? index : null)).filter((day) => day !== null));
3388
3159
 
3389
3160
  if (checkDays.length === 0) {
3390
3161
  this.log.warn(`No days selected for daily instance deactivated message. Please check the instance configuration!`);
3391
- return; // cancel function if no day is selected
3162
+ return;
3392
3163
  }
3393
3164
  this.log.debug(`Number of selected days for daily instance deactivated message: ${checkDays.length}. Send Message on: ${checkDays.join(', ')} ...`);
3394
- cron = '5 ' + time[1] + ' ' + time[0] + ' * * ' + checkDays;
3395
- schedule.scheduleJob(cron, () => {
3396
- list = '';
3397
- for (const id of this.listDeactivatedInstances) {
3398
- if (this.blacklistInstancesNotify.includes(id.Instance)) continue;
3399
- list = `${list}\n${id.Instance}`;
3400
- }
3401
3165
 
3402
- if (list.length === 0) return;
3166
+ schedule.scheduleJob(`5 ${this.config.checkSendInstanceDeactivatedTime.split(':').reverse().join(' ')} * * ${checkDays.join(',')}`, () => {
3167
+ processInstanceList(this.listDeactivatedInstances);
3403
3168
 
3404
- switch (checkDays.length) {
3405
- case 1:
3406
- message = `Wöchentliche Übersicht über deaktivierte Instanzen: ${list}`;
3407
- break;
3408
- case 7:
3409
- message = `Tägliche Übersicht über deaktivierte Instanzen: ${list}`;
3410
- break;
3411
- default:
3412
- message = `Übersicht über deaktivierte Instanzen: ${list}`;
3413
- break;
3414
- }
3415
- setMessage(message);
3169
+ processNotification(list, 'deactivated_instances_msg');
3416
3170
  });
3417
3171
  break;
3418
3172
  }
@@ -3437,14 +3191,14 @@ class DeviceWatcher extends utils.Adapter {
3437
3191
  return a.localeCompare(b);
3438
3192
  });
3439
3193
  html = `<center>
3440
- <b>Link Quality Devices:<font> ${deviceCount}</b><small></small></font>
3194
+ <b>${[translations.Link_quality_devices[this.language]]}:<font> ${deviceCount}</b><small></small></font>
3441
3195
  <p></p>
3442
3196
  </center>
3443
3197
  <table width=100%>
3444
3198
  <tr>
3445
- <th align=left>Device</th>
3446
- <th align=center width=120>Adapter</th>
3447
- <th align=right>Link Quality</th>
3199
+ <th align=left>${[translations.Device[this.language]]}</th>
3200
+ <th align=center width=120>${[translations.Adapter[this.language]]}</th>
3201
+ <th align=right>${[translations.Signal_strength[this.language]]}</th>
3448
3202
  </tr>
3449
3203
  <tr>
3450
3204
  <td colspan="5"><hr></td>
@@ -3452,9 +3206,9 @@ class DeviceWatcher extends utils.Adapter {
3452
3206
 
3453
3207
  for (const device of devices) {
3454
3208
  html += `<tr>
3455
- <td><font>${device.Device}</font></td>
3456
- <td align=center><font>${device.Adapter}</font></td>
3457
- <td align=right><font>${device['Signal strength']}</font></td>
3209
+ <td><font>${device[translations.Device[this.language]]}</font></td>
3210
+ <td align=center><font>${device[translations.Adapter[this.language]]}</font></td>
3211
+ <td align=right><font>${device[translations.Signal_strength[this.language]]}</font></td>
3458
3212
  </tr>`;
3459
3213
  }
3460
3214
 
@@ -3468,14 +3222,14 @@ class DeviceWatcher extends utils.Adapter {
3468
3222
  return a.localeCompare(b);
3469
3223
  });
3470
3224
  html = `<center>
3471
- <b>Offline Devices: <font color=${deviceCount === 0 ? '#3bcf0e' : 'orange'}>${deviceCount}</b><small></small></font>
3225
+ <b>${[translations.offline_devices[this.language]]}: <font color=${deviceCount === 0 ? '#3bcf0e' : 'orange'}>${deviceCount}</b><small></small></font>
3472
3226
  <p></p>
3473
3227
  </center>
3474
3228
  <table width=100%>
3475
3229
  <tr>
3476
- <th align=left>Device</th>
3477
- <th align=center width=120>Adapter</th>
3478
- <th align=center>Letzter Kontakt</th>
3230
+ <th align=left>${[translations.Device[this.language]]}</th>
3231
+ <th align=center width=120>${[translations.Adapter[this.language]]}</th>
3232
+ <th align=center>${[translations.Last_Contact[this.language]]}</th>
3479
3233
  </tr>
3480
3234
  <tr>
3481
3235
  <td colspan="5"><hr></td>
@@ -3485,7 +3239,7 @@ class DeviceWatcher extends utils.Adapter {
3485
3239
  html += `<tr>
3486
3240
  <td><font>${device.Device}</font></td>
3487
3241
  <td align=center><font>${device.Adapter}</font></td>
3488
- <td align=center><font color=orange>${device['Last contact']}</font></td>
3242
+ <td align=center><font color=orange>${device.LastContact}</font></td>
3489
3243
  </tr>`;
3490
3244
  }
3491
3245
 
@@ -3499,27 +3253,28 @@ class DeviceWatcher extends utils.Adapter {
3499
3253
  return a.localeCompare(b);
3500
3254
  });
3501
3255
  html = `<center>
3502
- <b>${isLowBatteryList === true ? 'Schwache ' : ''}Batterie Devices: <font color=${isLowBatteryList === true ? (deviceCount > 0 ? 'orange' : '#3bcf0e') : ''}>${deviceCount}</b></font>
3256
+ <b>${isLowBatteryList === true ? `${[translations.low[this.language]]} ` : ''}${[translations.battery_devices[this.language]]}:
3257
+ <font color=${isLowBatteryList === true ? (deviceCount > 0 ? 'orange' : '#3bcf0e') : ''}>${deviceCount}</b></font>
3503
3258
  <p></p>
3504
3259
  </center>
3505
3260
  <table width=100%>
3506
3261
  <tr>
3507
- <th align=left>Device</th>
3508
- <th align=center width=120>Adapter</th>
3509
- <th align=${isLowBatteryList ? 'center' : 'right'}>Batterie</th>
3262
+ <th align=left>${[translations.Device[this.language]]}</th>
3263
+ <th align=center width=120>${[translations.Adapter[this.language]]}</th>
3264
+ <th align=${isLowBatteryList ? 'center' : 'right'}>${[translations.Battery[this.language]]}</th>
3510
3265
  </tr>
3511
3266
  <tr>
3512
3267
  <td colspan="5"><hr></td>
3513
3268
  </tr>`;
3514
3269
  for (const device of devices) {
3515
3270
  html += `<tr>
3516
- <td><font>${device.Device}</font></td>
3517
- <td align=center><font>${device.Adapter}</font></td>`;
3271
+ <td><font>${device[translations.Device[this.language]]}</font></td>
3272
+ <td align=center><font>${device[translations.Adapter[this.language]]}</font></td>`;
3518
3273
 
3519
3274
  if (isLowBatteryList) {
3520
- html += `<td align=center><font color=orange>${device.Battery}</font></td>`;
3275
+ html += `<td align=center><font color=orange>${device[translations.Battery[this.language]]}</font></td>`;
3521
3276
  } else {
3522
- html += `<td align=right><font color=#3bcf0e>${device.Battery}</font></td>`;
3277
+ html += `<td align=right><font color=#3bcf0e>${device[translations.Battery[this.language]]}</font></td>`;
3523
3278
  }
3524
3279
  html += `</tr>`;
3525
3280
  }
@@ -3539,30 +3294,25 @@ class DeviceWatcher extends utils.Adapter {
3539
3294
  let html;
3540
3295
  switch (type) {
3541
3296
  case 'allInstancesList':
3542
- instances = instances.sort((a, b) => {
3543
- a = a.Instance || '';
3544
- b = b.Instance || '';
3545
- return a.localeCompare(b);
3546
- });
3547
3297
  html = `<center>
3548
- <b>All Instances:<font> ${instancesCount}</b><small></small></font>
3298
+ <b>${[translations.All_Instances[this.language]]}:<font> ${instancesCount}</b><small></small></font>
3549
3299
  <p></p>
3550
3300
  </center>
3551
3301
  <table width=100%>
3552
3302
  <tr>
3553
- <th align=left>Adapter</th>
3554
- <th align=center>Instance</th>
3555
- <th align=center width=180>Status</th>
3303
+ <th align=left>${[translations.Adapter[this.language]]}</th>
3304
+ <th align=center>${[translations.Instance[this.language]]}</th>
3305
+ <th align=center width=180>${[translations.Status[this.language]]}</th>
3556
3306
  </tr>
3557
3307
  <tr>
3558
3308
  <td colspan="5"><hr></td>
3559
3309
  </tr>`;
3560
3310
 
3561
- for (const instance of instances) {
3311
+ for (const [instance, instanceData] of instances) {
3562
3312
  html += `<tr>
3563
- <td><font>${instance.Adapter}</font></td>
3564
- <td align=center><font>${instance.Instance}</font></td>
3565
- <td align=center><font>${instance.Status}</font></td>
3313
+ <td><font>${instanceData.Adapter}</font></td>
3314
+ <td align=center><font>${instance}</font></td>
3315
+ <td align=center><font>${instanceData.status}</font></td>
3566
3316
  </tr>`;
3567
3317
  }
3568
3318
 
@@ -3570,61 +3320,53 @@ class DeviceWatcher extends utils.Adapter {
3570
3320
  break;
3571
3321
 
3572
3322
  case 'allActiveInstancesList':
3573
- instances = instances.sort((a, b) => {
3574
- a = a.Instance || '';
3575
- b = b.Instances || '';
3576
- return a.localeCompare(b);
3577
- });
3578
3323
  html = `<center>
3579
- <b>Active Devices: <font> ${instancesCount}</b><small></small></font>
3324
+ <b>${[translations.Active_Instances[this.language]]}: <font> ${instancesCount}</b><small></small></font>
3580
3325
  <p></p>
3581
3326
  </center>
3582
3327
  <table width=100%>
3583
3328
  <tr>
3584
- <th align=left>Adapter</th>
3585
- <th align=center>Instance</th>
3586
- <th align=center width=180>Status</th>
3329
+ <th align=left>${[translations.Adapter[this.language]]}</th>
3330
+ <th align=center>${[translations.Instance[this.language]]}</th>
3331
+ <th align=center width=180>${[translations.Status[this.language]]}</th>
3587
3332
  </tr>
3588
3333
  <tr>
3589
3334
  <td colspan="5"><hr></td>
3590
3335
  </tr>`;
3591
3336
 
3592
- for (const instance of instances) {
3593
- html += `<tr>
3594
- <td><font>${instance.Adapter}</font></td>
3595
- <td align=center><font>${instance.Instance}</font></td>
3596
- <td align=center><font color=orange>${instance.Status}</font></td>
3337
+ for (const [instance, instanceData] of instances) {
3338
+ if (instanceData.isAlive) {
3339
+ html += `<tr>
3340
+ <td><font>${instanceData.Adapter}</font></td>
3341
+ <td align=center><font>${instance}</font></td>
3342
+ <td align=center><font color=orange>${instanceData.status}</font></td>
3597
3343
  </tr>`;
3344
+ }
3598
3345
  }
3599
3346
 
3600
3347
  html += '</table>';
3601
3348
  break;
3602
3349
 
3603
3350
  case 'errorInstanceList':
3604
- instances = instances.sort((a, b) => {
3605
- a = a.Instance || '';
3606
- b = b.Instances || '';
3607
- return a.localeCompare(b);
3608
- });
3609
3351
  html = `<center>
3610
- <b>Error Instances: <font color=${instancesCount === 0 ? '#3bcf0e' : 'orange'}>${instancesCount}</b><small></small></font>
3352
+ <b>${[translations.Error_Instances[this.language]]}: <font color=${instancesCount === 0 ? '#3bcf0e' : 'orange'}>${instancesCount}</b><small></small></font>
3611
3353
  <p></p>
3612
3354
  </center>
3613
3355
  <table width=100%>
3614
3356
  <tr>
3615
- <th align=left>Adapter</th>
3616
- <th align=center width=120>Instance</th>
3617
- <th align=center>Status</th>
3357
+ <th align=left>${[translations.Adapter[this.language]]}</th>
3358
+ <th align=center>${[translations.Instance[this.language]]}</th>
3359
+ <th align=center width=180>${[translations.Status[this.language]]}</th>
3618
3360
  </tr>
3619
3361
  <tr>
3620
3362
  <td colspan="5"><hr></td>
3621
3363
  </tr>`;
3622
3364
 
3623
- for (const instance of instances) {
3365
+ for (const [instance, instanceData] of instances) {
3624
3366
  html += `<tr>
3625
- <td><font>${instance.Adapter}</font></td>
3626
- <td align=center><font>${instance.Instance}</font></td>
3627
- <td align=center><font color=orange>${instance.Status}</font></td>
3367
+ <td><font>${instanceData.Adapter}</font></td>
3368
+ <td align=center><font>${instance}</font></td>
3369
+ <td align=center><font color=orange>${instanceData.status}</font></td>
3628
3370
  </tr>`;
3629
3371
  }
3630
3372
 
@@ -3632,62 +3374,56 @@ class DeviceWatcher extends utils.Adapter {
3632
3374
  break;
3633
3375
 
3634
3376
  case 'deactivatedInstanceList':
3635
- instances = instances.sort((a, b) => {
3636
- a = a.Instance || '';
3637
- b = b.Instances || '';
3638
- return a.localeCompare(b);
3639
- });
3640
3377
  html = `<center>
3641
- <b>Deactivated Instances: <font color=${instancesCount === 0 ? '#3bcf0e' : 'orange'}>${instancesCount}</b><small></small></font>
3378
+ <b>${[translations.Deactivated_Instances[this.language]]}: <font color=${instancesCount === 0 ? '#3bcf0e' : 'orange'}>${instancesCount}</b><small></small></font>
3642
3379
  <p></p>
3643
3380
  </center>
3644
3381
  <table width=100%>
3645
3382
  <tr>
3646
- <th align=left>Adapter</th>
3647
- <th align=center width=120>Instance</th>
3648
- <th align=center>Status</th>
3383
+ <th align=left>${[translations.Adapter[this.language]]}</th>
3384
+ <th align=center>${[translations.Instance[this.language]]}</th>
3385
+ <th align=center width=180>${[translations.Status[this.language]]}</th>
3649
3386
  </tr>
3650
3387
  <tr>
3651
3388
  <td colspan="5"><hr></td>
3652
3389
  </tr>`;
3653
3390
 
3654
- for (const instance of instances) {
3655
- html += `<tr>
3656
- <td><font>${instance.Adapter}</font></td>
3657
- <td align=center><font>${instance.Instance}</font></td>
3658
- <td align=center><font color=orange>${instance.Status}</font></td>
3391
+ for (const [instance, instanceData] of instances) {
3392
+ if (!instanceData.isAlive) {
3393
+ html += `<tr>
3394
+ <td><font>${instanceData.Adapter}</font></td>
3395
+ <td align=center><font>${instance}</font></td>
3396
+ <td align=center><font color=orange>${instanceData.status}</font></td>
3659
3397
  </tr>`;
3398
+ }
3660
3399
  }
3661
3400
 
3662
3401
  html += '</table>';
3663
3402
  break;
3664
3403
 
3665
3404
  case 'updateAdapterList':
3666
- instances = instances.sort((a, b) => {
3667
- a = a.Instance || '';
3668
- b = b.Instances || '';
3669
- return a.localeCompare(b);
3670
- });
3671
3405
  html = `<center>
3672
- <b>Updatable Adapter: <font color=${instancesCount === 0 ? '#3bcf0e' : 'orange'}>${instancesCount}</b><small></small></font>
3406
+ <b>${[translations.Updatable_adapters[this.language]]}: <font color=${instancesCount === 0 ? '#3bcf0e' : 'orange'}>${instancesCount}</b><small></small></font>
3673
3407
  <p></p>
3674
3408
  </center>
3675
3409
  <table width=100%>
3676
3410
  <tr>
3677
- <th align=left>Adapter</th>
3678
- <th align=center>Installed Version</th>
3679
- <th align=center>Available Version</th>
3411
+ <th align=left>${[translations.Adapter[this.language]]}</th>
3412
+ <th align=center>${[translations.Installed_Version[this.language]]}</th>
3413
+ <th align=center>${[translations.Available_Version[this.language]]}</th>
3680
3414
  </tr>
3681
3415
  <tr>
3682
3416
  <td colspan="5"><hr></td>
3683
3417
  </tr>`;
3684
3418
 
3685
- for (const instance of instances) {
3686
- html += `<tr>
3687
- <td><font>${instance.Adapter}</font></td>
3688
- <td align=center><font>${instance['Installed Version']}</font></td>
3689
- <td align=center><font color=orange>${instance['Available Version']}</font></td>
3419
+ for (const instanceData of instances.values()) {
3420
+ if (instanceData.updateAvailable !== ' - ') {
3421
+ html += `<tr>
3422
+ <td><font>${instanceData.Adapter}</font></td>
3423
+ <td align=center><font>${instanceData.adapterVersion}</font></td>
3424
+ <td align=center><font color=orange>${instanceData.updateAvailable}</font></td>
3690
3425
  </tr>`;
3426
+ }
3691
3427
  }
3692
3428
 
3693
3429
  html += '</table>';