@switchbot/homebridge-switchbot 3.6.1-beta.9 → 3.7.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.
Files changed (118) hide show
  1. package/CHANGELOG.md +2 -1
  2. package/dist/device/blindtilt.js +3 -3
  3. package/dist/device/blindtilt.js.map +1 -1
  4. package/dist/device/bot.js +12 -12
  5. package/dist/device/bot.js.map +1 -1
  6. package/dist/device/ceilinglight.js +1 -1
  7. package/dist/device/ceilinglight.js.map +1 -1
  8. package/dist/device/colorbulb.js +1 -1
  9. package/dist/device/colorbulb.js.map +1 -1
  10. package/dist/device/contact.js +4 -4
  11. package/dist/device/contact.js.map +1 -1
  12. package/dist/device/curtain.js +3 -3
  13. package/dist/device/curtain.js.map +1 -1
  14. package/dist/device/device.d.ts +1 -9
  15. package/dist/device/device.d.ts.map +1 -1
  16. package/dist/device/device.js +14 -38
  17. package/dist/device/device.js.map +1 -1
  18. package/dist/device/fan.js +3 -3
  19. package/dist/device/fan.js.map +1 -1
  20. package/dist/device/hub.js +3 -3
  21. package/dist/device/hub.js.map +1 -1
  22. package/dist/device/humidifier.js +2 -2
  23. package/dist/device/humidifier.js.map +1 -1
  24. package/dist/device/iosensor.js +3 -3
  25. package/dist/device/iosensor.js.map +1 -1
  26. package/dist/device/lightstrip.js +1 -1
  27. package/dist/device/lightstrip.js.map +1 -1
  28. package/dist/device/lock.js +4 -4
  29. package/dist/device/lock.js.map +1 -1
  30. package/dist/device/meter.js +3 -3
  31. package/dist/device/meter.js.map +1 -1
  32. package/dist/device/meterplus.js +3 -3
  33. package/dist/device/meterplus.js.map +1 -1
  34. package/dist/device/motion.d.ts.map +1 -1
  35. package/dist/device/motion.js +4 -5
  36. package/dist/device/motion.js.map +1 -1
  37. package/dist/device/plug.js +2 -2
  38. package/dist/device/plug.js.map +1 -1
  39. package/dist/device/robotvacuumcleaner.js +3 -3
  40. package/dist/device/robotvacuumcleaner.js.map +1 -1
  41. package/dist/device/waterdetector.js +2 -2
  42. package/dist/device/waterdetector.js.map +1 -1
  43. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  44. package/dist/irdevice/airconditioner.js +4 -3
  45. package/dist/irdevice/airconditioner.js.map +1 -1
  46. package/dist/irdevice/airpurifier.js +2 -2
  47. package/dist/irdevice/airpurifier.js.map +1 -1
  48. package/dist/irdevice/camera.js +1 -1
  49. package/dist/irdevice/camera.js.map +1 -1
  50. package/dist/irdevice/fan.js +1 -1
  51. package/dist/irdevice/fan.js.map +1 -1
  52. package/dist/irdevice/irdevice.d.ts +1 -0
  53. package/dist/irdevice/irdevice.d.ts.map +1 -1
  54. package/dist/irdevice/irdevice.js +14 -11
  55. package/dist/irdevice/irdevice.js.map +1 -1
  56. package/dist/irdevice/light.js +3 -3
  57. package/dist/irdevice/light.js.map +1 -1
  58. package/dist/irdevice/other.d.ts +1 -1
  59. package/dist/irdevice/other.d.ts.map +1 -1
  60. package/dist/irdevice/other.js +26 -36
  61. package/dist/irdevice/other.js.map +1 -1
  62. package/dist/irdevice/tv.js +3 -3
  63. package/dist/irdevice/tv.js.map +1 -1
  64. package/dist/irdevice/vacuumcleaner.js +1 -1
  65. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  66. package/dist/irdevice/waterheater.js +2 -2
  67. package/dist/irdevice/waterheater.js.map +1 -1
  68. package/dist/platform.d.ts +9 -0
  69. package/dist/platform.d.ts.map +1 -1
  70. package/dist/platform.js +310 -91
  71. package/dist/platform.js.map +1 -1
  72. package/dist/settings.d.ts +1 -1
  73. package/dist/settings.d.ts.map +1 -1
  74. package/docs/.nojekyll +1 -0
  75. package/docs/assets/highlight.css +22 -0
  76. package/docs/assets/icons.js +18 -0
  77. package/docs/assets/icons.svg +1 -0
  78. package/docs/assets/main.js +60 -0
  79. package/docs/assets/navigation.js +1 -0
  80. package/docs/assets/search.js +1 -0
  81. package/docs/assets/style.css +1448 -0
  82. package/docs/functions/default.html +1 -0
  83. package/docs/index.html +368 -0
  84. package/docs/modules.html +2 -0
  85. package/package.json +10 -7
  86. package/src/device/blindtilt.ts +3 -3
  87. package/src/device/bot.ts +12 -12
  88. package/src/device/ceilinglight.ts +1 -1
  89. package/src/device/colorbulb.ts +1 -1
  90. package/src/device/contact.ts +4 -4
  91. package/src/device/curtain.ts +3 -3
  92. package/src/device/device.ts +15 -44
  93. package/src/device/fan.ts +3 -3
  94. package/src/device/hub.ts +3 -3
  95. package/src/device/humidifier.ts +2 -2
  96. package/src/device/iosensor.ts +3 -3
  97. package/src/device/lightstrip.ts +1 -1
  98. package/src/device/lock.ts +4 -4
  99. package/src/device/meter.ts +4 -4
  100. package/src/device/meterplus.ts +4 -4
  101. package/src/device/motion.ts +6 -7
  102. package/src/device/plug.ts +2 -2
  103. package/src/device/robotvacuumcleaner.ts +3 -3
  104. package/src/device/waterdetector.ts +2 -2
  105. package/src/irdevice/airconditioner.ts +5 -4
  106. package/src/irdevice/airpurifier.ts +2 -2
  107. package/src/irdevice/camera.ts +1 -1
  108. package/src/irdevice/fan.ts +1 -1
  109. package/src/irdevice/irdevice.ts +15 -11
  110. package/src/irdevice/light.ts +3 -3
  111. package/src/irdevice/other.ts +26 -34
  112. package/src/irdevice/tv.ts +3 -3
  113. package/src/irdevice/vacuumcleaner.ts +1 -1
  114. package/src/irdevice/waterheater.ts +2 -2
  115. package/src/platform.ts +315 -90
  116. package/src/settings.ts +1 -1
  117. package/typedoc.json +17 -0
  118. package/.github/npm-version-script.cjs +0 -81
package/src/platform.ts CHANGED
@@ -104,8 +104,8 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
104
104
  };
105
105
 
106
106
  // Plugin Configuration
107
- this.getPlatformConfigSettings();
108
107
  this.getPlatformLogSettings();
108
+ this.getPlatformConfigSettings();
109
109
  this.getVersion();
110
110
 
111
111
  // Finish initializing the platform
@@ -880,7 +880,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
880
880
  existingAccessory.context.deviceId = device.deviceId;
881
881
  existingAccessory.context.deviceType = device.deviceType;
882
882
  existingAccessory.context.model = SwitchBotModel.Humidifier;
883
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
883
+ existingAccessory.displayName = device.configDeviceName
884
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
885
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
884
886
  existingAccessory.context.connectionType = await this.connectionType(device);
885
887
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
886
888
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -894,7 +896,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
894
896
  }
895
897
  } else if (await this.registerDevice(device)) {
896
898
  // create a new accessory
897
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
899
+ const accessory = new this.api.platformAccessory(device.configDeviceName
900
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
901
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
898
902
 
899
903
  // store a copy of the device object in the `accessory.context`
900
904
  // the `context` property can be used to store any data about the accessory you may need
@@ -902,7 +906,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
902
906
  accessory.context.deviceId = device.deviceId;
903
907
  accessory.context.deviceType = device.deviceType;
904
908
  accessory.context.model = SwitchBotModel.Humidifier;
905
- accessory.displayName = device.configDeviceName ?? device.deviceName;
909
+ accessory.displayName = device.configDeviceName
910
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
911
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
906
912
  accessory.context.connectionType = await this.connectionType(device);
907
913
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
908
914
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -935,7 +941,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
935
941
  existingAccessory.context.deviceId = device.deviceId;
936
942
  existingAccessory.context.deviceType = device.deviceType;
937
943
  existingAccessory.context.model = SwitchBotModel.Bot;
938
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
944
+ existingAccessory.displayName = device.configDeviceName
945
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
946
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
939
947
  existingAccessory.context.connectionType = await this.connectionType(device);
940
948
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
941
949
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -949,7 +957,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
949
957
  }
950
958
  } else if (await this.registerDevice(device)) {
951
959
  // create a new accessory
952
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
960
+ const accessory = new this.api.platformAccessory(device.configDeviceName
961
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
962
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
953
963
 
954
964
  // store a copy of the device object in the `accessory.context`
955
965
  // the `context` property can be used to store any data about the accessory you may need
@@ -957,7 +967,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
957
967
  accessory.context.deviceId = device.deviceId;
958
968
  accessory.context.deviceType = device.deviceType;
959
969
  accessory.context.model = SwitchBotModel.Bot;
960
- accessory.displayName = device.configDeviceName ?? device.deviceName;
970
+ accessory.displayName = device.configDeviceName
971
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
972
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
973
+ accessory.context.connectionType = await this.connectionType(device);
961
974
  accessory.context.connectionType = await this.connectionType(device);
962
975
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
963
976
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -991,7 +1004,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
991
1004
  existingAccessory.context.model = SwitchBotModel.Meter;
992
1005
  existingAccessory.context.deviceId = device.deviceId;
993
1006
  existingAccessory.context.deviceType = device.deviceType;
994
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1007
+ existingAccessory.displayName = device.configDeviceName
1008
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1009
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
995
1010
  existingAccessory.context.connectionType = await this.connectionType(device);
996
1011
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
997
1012
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1005,7 +1020,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1005
1020
  }
1006
1021
  } else if (await this.registerDevice(device)) {
1007
1022
  // create a new accessory
1008
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1023
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1024
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1025
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1009
1026
 
1010
1027
  // store a copy of the device object in the `accessory.context`
1011
1028
  // the `context` property can be used to store any data about the accessory you may need
@@ -1013,7 +1030,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1013
1030
  accessory.context.model = SwitchBotModel.Meter;
1014
1031
  accessory.context.deviceId = device.deviceId;
1015
1032
  accessory.context.deviceType = device.deviceType;
1016
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1033
+ accessory.displayName = device.configDeviceName
1034
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1035
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1036
+ accessory.context.connectionType = await this.connectionType(device);
1017
1037
  accessory.context.connectionType = await this.connectionType(device);
1018
1038
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1019
1039
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1047,7 +1067,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1047
1067
  existingAccessory.context.model = SwitchBotModel.MeterPlusUS ?? SwitchBotModel.MeterPlusJP;
1048
1068
  existingAccessory.context.deviceId = device.deviceId;
1049
1069
  existingAccessory.context.deviceType = device.deviceType;
1050
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1070
+ existingAccessory.displayName = device.configDeviceName
1071
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1072
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1051
1073
  existingAccessory.context.connectionType = await this.connectionType(device);
1052
1074
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1053
1075
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1061,7 +1083,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1061
1083
  }
1062
1084
  } else if (await this.registerDevice(device)) {
1063
1085
  // create a new accessory
1064
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1086
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1087
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1088
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1065
1089
 
1066
1090
  // store a copy of the device object in the `accessory.context`
1067
1091
  // the `context` property can be used to store any data about the accessory you may need
@@ -1069,7 +1093,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1069
1093
  accessory.context.model = SwitchBotModel.MeterPlusUS ?? SwitchBotModel.MeterPlusJP;
1070
1094
  accessory.context.deviceId = device.deviceId;
1071
1095
  accessory.context.deviceType = device.deviceType;
1072
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1096
+ accessory.displayName = device.configDeviceName
1097
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1098
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1099
+ accessory.context.connectionType = await this.connectionType(device);
1073
1100
  accessory.context.connectionType = await this.connectionType(device);
1074
1101
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1075
1102
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1103,7 +1130,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1103
1130
  existingAccessory.context.model = SwitchBotModel.Hub2;
1104
1131
  existingAccessory.context.deviceId = device.deviceId;
1105
1132
  existingAccessory.context.deviceType = device.deviceType;
1106
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1133
+ existingAccessory.displayName = device.configDeviceName
1134
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1135
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1107
1136
  existingAccessory.context.connectionType = await this.connectionType(device);
1108
1137
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1109
1138
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1117,7 +1146,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1117
1146
  }
1118
1147
  } else if (await this.registerDevice(device)) {
1119
1148
  // create a new accessory
1120
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1149
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1150
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1151
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1121
1152
 
1122
1153
  // store a copy of the device object in the `accessory.context`
1123
1154
  // the `context` property can be used to store any data about the accessory you may need
@@ -1125,7 +1156,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1125
1156
  accessory.context.model = SwitchBotModel.Hub2;
1126
1157
  accessory.context.deviceId = device.deviceId;
1127
1158
  accessory.context.deviceType = device.deviceType;
1128
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1159
+ accessory.displayName = device.configDeviceName
1160
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1161
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1162
+ accessory.context.connectionType = await this.connectionType(device);
1129
1163
  accessory.context.connectionType = await this.connectionType(device);
1130
1164
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1131
1165
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1158,7 +1192,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1158
1192
  existingAccessory.context.model = SwitchBotModel.OutdoorMeter;
1159
1193
  existingAccessory.context.deviceId = device.deviceId;
1160
1194
  existingAccessory.context.deviceType = device.deviceType;
1161
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1195
+ existingAccessory.displayName = device.configDeviceName
1196
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1197
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1162
1198
  existingAccessory.context.connectionType = await this.connectionType(device);
1163
1199
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1164
1200
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1172,7 +1208,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1172
1208
  }
1173
1209
  } else if (await this.registerDevice(device)) {
1174
1210
  // create a new accessory
1175
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1211
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1212
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1213
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1176
1214
 
1177
1215
  // store a copy of the device object in the `accessory.context`
1178
1216
  // the `context` property can be used to store any data about the accessory you may need
@@ -1180,7 +1218,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1180
1218
  accessory.context.model = SwitchBotModel.OutdoorMeter;
1181
1219
  accessory.context.deviceId = device.deviceId;
1182
1220
  accessory.context.deviceType = device.deviceType;
1183
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1221
+ accessory.displayName = device.configDeviceName
1222
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1223
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1224
+ accessory.context.connectionType = await this.connectionType(device);
1184
1225
  accessory.context.connectionType = await this.connectionType(device);
1185
1226
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1186
1227
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1213,7 +1254,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1213
1254
  existingAccessory.context.deviceId = device.deviceId;
1214
1255
  existingAccessory.context.deviceType = device.deviceType;
1215
1256
  existingAccessory.context.model = SwitchBotModel.WaterDetector;
1216
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1257
+ existingAccessory.displayName = device.configDeviceName
1258
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1259
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1217
1260
  existingAccessory.context.connectionType = await this.connectionType(device);
1218
1261
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1219
1262
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1227,7 +1270,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1227
1270
  }
1228
1271
  } else if (await this.registerDevice(device)) {
1229
1272
  // create a new accessory
1230
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1273
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1274
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1275
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1231
1276
 
1232
1277
  // store a copy of the device object in the `accessory.context`
1233
1278
  // the `context` property can be used to store any data about the accessory you may need
@@ -1235,7 +1280,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1235
1280
  accessory.context.deviceId = device.deviceId;
1236
1281
  accessory.context.deviceType = device.deviceType;
1237
1282
  accessory.context.model = SwitchBotModel.WaterDetector;
1238
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1283
+ accessory.displayName = device.configDeviceName
1284
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1285
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1286
+ accessory.context.connectionType = await this.connectionType(device);
1239
1287
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1240
1288
  accessory.context.connectionType = await this.connectionType(device);
1241
1289
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1268,7 +1316,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1268
1316
  existingAccessory.context.deviceId = device.deviceId;
1269
1317
  existingAccessory.context.deviceType = device.deviceType;
1270
1318
  existingAccessory.context.model = SwitchBotModel.MotionSensor;
1271
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1319
+ existingAccessory.displayName = device.configDeviceName
1320
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1321
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1272
1322
  existingAccessory.context.connectionType = await this.connectionType(device);
1273
1323
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1274
1324
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1282,7 +1332,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1282
1332
  }
1283
1333
  } else if (await this.registerDevice(device)) {
1284
1334
  // create a new accessory
1285
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1335
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1336
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1337
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1286
1338
 
1287
1339
  // store a copy of the device object in the `accessory.context`
1288
1340
  // the `context` property can be used to store any data about the accessory you may need
@@ -1290,7 +1342,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1290
1342
  accessory.context.deviceId = device.deviceId;
1291
1343
  accessory.context.deviceType = device.deviceType;
1292
1344
  accessory.context.model = SwitchBotModel.MotionSensor;
1293
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1345
+ accessory.displayName = device.configDeviceName
1346
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1347
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1348
+ accessory.context.connectionType = await this.connectionType(device);
1294
1349
  accessory.context.connectionType = await this.connectionType(device);
1295
1350
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1296
1351
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1323,7 +1378,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1323
1378
  existingAccessory.context.deviceId = device.deviceId;
1324
1379
  existingAccessory.context.deviceType = device.deviceType;
1325
1380
  existingAccessory.context.model = SwitchBotModel.ContactSensor;
1326
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1381
+ existingAccessory.displayName = device.configDeviceName
1382
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1383
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1327
1384
  existingAccessory.context.connectionType = await this.connectionType(device);
1328
1385
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1329
1386
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1337,7 +1394,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1337
1394
  }
1338
1395
  } else if (await this.registerDevice(device)) {
1339
1396
  // create a new accessory
1340
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1397
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1398
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1399
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1341
1400
 
1342
1401
  // store a copy of the device object in the `accessory.context`
1343
1402
  // the `context` property can be used to store any data about the accessory you may need
@@ -1345,7 +1404,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1345
1404
  accessory.context.deviceId = device.deviceId;
1346
1405
  accessory.context.deviceType = device.deviceType;
1347
1406
  accessory.context.model = SwitchBotModel.ContactSensor;
1348
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1407
+ accessory.displayName = device.configDeviceName
1408
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1409
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1410
+ accessory.context.connectionType = await this.connectionType(device);
1349
1411
  accessory.context.connectionType = await this.connectionType(device);
1350
1412
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1351
1413
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1378,7 +1440,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1378
1440
  existingAccessory.context.deviceId = device.deviceId;
1379
1441
  existingAccessory.context.deviceType = device.deviceType;
1380
1442
  existingAccessory.context.model = SwitchBotModel.BlindTilt;
1381
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1443
+ existingAccessory.displayName = device.configDeviceName
1444
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1445
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1382
1446
  existingAccessory.context.connectionType = await this.connectionType(device);
1383
1447
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1384
1448
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1406,7 +1470,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1406
1470
  }
1407
1471
 
1408
1472
  // create a new accessory
1409
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1473
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1474
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1475
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1410
1476
 
1411
1477
  // store a copy of the device object in the `accessory.context`
1412
1478
  // the `context` property can be used to store any data about the accessory you may need
@@ -1414,7 +1480,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1414
1480
  accessory.context.deviceId = device.deviceId;
1415
1481
  accessory.context.deviceType = device.deviceType;
1416
1482
  accessory.context.model = SwitchBotModel.BlindTilt;
1417
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1483
+ accessory.displayName = device.configDeviceName
1484
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1485
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1486
+ accessory.context.connectionType = await this.connectionType(device);
1418
1487
  accessory.context.connectionType = await this.connectionType(device);
1419
1488
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1420
1489
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1447,7 +1516,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1447
1516
  existingAccessory.context.deviceId = device.deviceId;
1448
1517
  existingAccessory.context.deviceType = device.deviceType;
1449
1518
  existingAccessory.context.model = device.deviceType === 'Curtain3' ? SwitchBotModel.Curtain3 : SwitchBotModel.Curtain;
1450
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1519
+ existingAccessory.displayName = device.configDeviceName
1520
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1521
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1451
1522
  existingAccessory.context.connectionType = await this.connectionType(device);
1452
1523
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1453
1524
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1475,7 +1546,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1475
1546
  }
1476
1547
 
1477
1548
  // create a new accessory
1478
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1549
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1550
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1551
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1479
1552
 
1480
1553
  // store a copy of the device object in the `accessory.context`
1481
1554
  // the `context` property can be used to store any data about the accessory you may need
@@ -1483,7 +1556,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1483
1556
  accessory.context.deviceId = device.deviceId;
1484
1557
  accessory.context.deviceType = device.deviceType;
1485
1558
  accessory.context.model = device.deviceType === 'Curtain3' ? SwitchBotModel.Curtain3 : SwitchBotModel.Curtain;
1486
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1559
+ accessory.displayName = device.configDeviceName
1560
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1561
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1562
+ accessory.context.connectionType = await this.connectionType(device);
1487
1563
  accessory.context.connectionType = await this.connectionType(device);
1488
1564
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1489
1565
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1517,7 +1593,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1517
1593
  existingAccessory.context.deviceType = device.deviceType;
1518
1594
  existingAccessory.context.model = device.deviceType === 'Plug Mini (US)' ? SwitchBotModel.PlugMiniUS : device.deviceType === 'Plug Mini (JP)'
1519
1595
  ? SwitchBotModel.PlugMiniJP : SwitchBotModel.Plug;
1520
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1596
+ existingAccessory.displayName = device.configDeviceName
1597
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1598
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1521
1599
  existingAccessory.context.connectionType = await this.connectionType(device);
1522
1600
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1523
1601
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1531,7 +1609,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1531
1609
  }
1532
1610
  } else if (await this.registerDevice(device)) {
1533
1611
  // create a new accessory
1534
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1612
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1613
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1614
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1535
1615
 
1536
1616
  // store a copy of the device object in the `accessory.context`
1537
1617
  // the `context` property can be used to store any data about the accessory you may need
@@ -1540,7 +1620,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1540
1620
  accessory.context.deviceType = device.deviceType;
1541
1621
  accessory.context.model = device.deviceType === 'Plug Mini (US)' ? SwitchBotModel.PlugMiniUS : device.deviceType === 'Plug Mini (JP)'
1542
1622
  ? SwitchBotModel.PlugMiniJP : SwitchBotModel.Plug;
1543
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1623
+ accessory.displayName = device.configDeviceName
1624
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1625
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1626
+ accessory.context.connectionType = await this.connectionType(device);
1544
1627
  accessory.context.connectionType = await this.connectionType(device);
1545
1628
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1546
1629
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1573,7 +1656,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1573
1656
  existingAccessory.context.deviceId = device.deviceId;
1574
1657
  existingAccessory.context.deviceType = device.deviceType;
1575
1658
  existingAccessory.context.model = device.deviceType === 'Smart Lock Pro' ? SwitchBotModel.LockPro : SwitchBotModel.Lock;
1576
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1659
+ existingAccessory.displayName = device.configDeviceName
1660
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1661
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1577
1662
  existingAccessory.context.connectionType = await this.connectionType(device);
1578
1663
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1579
1664
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1587,7 +1672,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1587
1672
  }
1588
1673
  } else if (await this.registerDevice(device)) {
1589
1674
  // create a new accessory
1590
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1675
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1676
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1677
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1591
1678
 
1592
1679
  // store a copy of the device object in the `accessory.context`
1593
1680
  // the `context` property can be used to store any data about the accessory you may need
@@ -1595,7 +1682,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1595
1682
  accessory.context.deviceId = device.deviceId;
1596
1683
  accessory.context.deviceType = device.deviceType;
1597
1684
  accessory.context.model = device.deviceType === 'Smart Lock Pro' ? SwitchBotModel.LockPro : SwitchBotModel.Lock;
1598
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1685
+ accessory.displayName = device.configDeviceName
1686
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1687
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1688
+ accessory.context.connectionType = await this.connectionType(device);
1599
1689
  accessory.context.connectionType = await this.connectionType(device);
1600
1690
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1601
1691
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1628,7 +1718,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1628
1718
  existingAccessory.context.deviceId = device.deviceId;
1629
1719
  existingAccessory.context.deviceType = device.deviceType;
1630
1720
  existingAccessory.context.model = SwitchBotModel.ColorBulb;
1631
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1721
+ existingAccessory.displayName = device.configDeviceName
1722
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1723
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1632
1724
  existingAccessory.context.connectionType = await this.connectionType(device);
1633
1725
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1634
1726
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1642,7 +1734,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1642
1734
  }
1643
1735
  } else if (await this.registerDevice(device)) {
1644
1736
  // create a new accessory
1645
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1737
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1738
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1739
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1646
1740
 
1647
1741
  // store a copy of the device object in the `accessory.context`
1648
1742
  // the `context` property can be used to store any data about the accessory you may need
@@ -1650,7 +1744,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1650
1744
  accessory.context.deviceId = device.deviceId;
1651
1745
  accessory.context.deviceType = device.deviceType;
1652
1746
  accessory.context.model = SwitchBotModel.ColorBulb;
1653
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1747
+ accessory.displayName = device.configDeviceName
1748
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1749
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1750
+ accessory.context.connectionType = await this.connectionType(device);
1654
1751
  accessory.context.connectionType = await this.connectionType(device);
1655
1752
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1656
1753
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1683,7 +1780,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1683
1780
  existingAccessory.context.deviceId = device.deviceId;
1684
1781
  existingAccessory.context.deviceType = device.deviceType;
1685
1782
  existingAccessory.context.model = device.deviceType === 'Ceiling Light Pro' ? SwitchBotModel.CeilingLightPro : SwitchBotModel.CeilingLight;
1686
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1783
+ existingAccessory.displayName = device.configDeviceName
1784
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1785
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1687
1786
  existingAccessory.context.connectionType = await this.connectionType(device);
1688
1787
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1689
1788
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1697,7 +1796,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1697
1796
  }
1698
1797
  } else if (await this.registerDevice(device)) {
1699
1798
  // create a new accessory
1700
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1799
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1800
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1801
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1701
1802
 
1702
1803
  // store a copy of the device object in the `accessory.context`
1703
1804
  // the `context` property can be used to store any data about the accessory you may need
@@ -1705,7 +1806,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1705
1806
  accessory.context.deviceId = device.deviceId;
1706
1807
  accessory.context.deviceType = device.deviceType;
1707
1808
  accessory.context.model = device.deviceType === 'Ceiling Light Pro' ? SwitchBotModel.CeilingLightPro : SwitchBotModel.CeilingLight;
1708
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1809
+ accessory.displayName = device.configDeviceName
1810
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1811
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1812
+ accessory.context.connectionType = await this.connectionType(device);
1709
1813
  accessory.context.connectionType = await this.connectionType(device);
1710
1814
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1711
1815
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1738,7 +1842,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1738
1842
  existingAccessory.context.deviceId = device.deviceId;
1739
1843
  existingAccessory.context.deviceType = device.deviceType;
1740
1844
  existingAccessory.context.model = SwitchBotModel.StripLight;
1741
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1845
+ existingAccessory.displayName = device.configDeviceName
1846
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1847
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1742
1848
  existingAccessory.context.connectionType = await this.connectionType(device);
1743
1849
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1744
1850
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1752,7 +1858,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1752
1858
  }
1753
1859
  } else if (await this.registerDevice(device)) {
1754
1860
  // create a new accessory
1755
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1861
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1862
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1863
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1756
1864
 
1757
1865
  // store a copy of the device object in the `accessory.context`
1758
1866
  // the `context` property can be used to store any data about the accessory you may need
@@ -1760,7 +1868,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1760
1868
  accessory.context.deviceId = device.deviceId;
1761
1869
  accessory.context.deviceType = device.deviceType;
1762
1870
  accessory.context.model = SwitchBotModel.StripLight;
1763
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1871
+ accessory.displayName = device.configDeviceName
1872
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1873
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1874
+ accessory.context.connectionType = await this.connectionType(device);
1764
1875
  accessory.context.connectionType = await this.connectionType(device);
1765
1876
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1766
1877
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1793,7 +1904,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1793
1904
  existingAccessory.context.deviceId = device.deviceId;
1794
1905
  existingAccessory.context.deviceType = device.deviceType;
1795
1906
  existingAccessory.context.model = SwitchBotModel.BatteryCirculatorFan;
1796
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1907
+ existingAccessory.displayName = device.configDeviceName
1908
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1909
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1797
1910
  existingAccessory.context.connectionType = await this.connectionType(device);
1798
1911
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1799
1912
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1807,7 +1920,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1807
1920
  }
1808
1921
  } else if (await this.registerDevice(device)) {
1809
1922
  // create a new accessory
1810
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1923
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1924
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1925
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1811
1926
 
1812
1927
  // store a copy of the device object in the `accessory.context`
1813
1928
  // the `context` property can be used to store any data about the accessory you may need
@@ -1815,7 +1930,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1815
1930
  accessory.context.deviceId = device.deviceId;
1816
1931
  accessory.context.deviceType = device.deviceType;
1817
1932
  accessory.context.model = SwitchBotModel.BatteryCirculatorFan;
1818
- accessory.displayName = device.configDeviceName ?? device.deviceName;
1933
+ accessory.displayName = device.configDeviceName
1934
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1935
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1936
+ accessory.context.connectionType = await this.connectionType(device);
1819
1937
  accessory.context.connectionType = await this.connectionType(device);
1820
1938
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1821
1939
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1852,7 +1970,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1852
1970
  : device.deviceType === 'Robot Vacuum Cleaner S10' ? SwitchBotModel.RobotVacuumCleanerS10
1853
1971
  : device.deviceType === 'WoSweeper' ? SwitchBotModel.WoSweeper : device.deviceType === 'WoSweeperMini' ? SwitchBotModel.WoSweeperMini
1854
1972
  : SwitchBotModel.Unknown;
1855
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
1973
+ existingAccessory.displayName = device.configDeviceName
1974
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1975
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1856
1976
  existingAccessory.context.connectionType = await this.connectionType(device);
1857
1977
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1858
1978
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1866,7 +1986,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1866
1986
  }
1867
1987
  } else if (await this.registerDevice(device)) {
1868
1988
  // create a new accessory
1869
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1989
+ const accessory = new this.api.platformAccessory(device.configDeviceName
1990
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1991
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1870
1992
 
1871
1993
  // store a copy of the device object in the `accessory.context`
1872
1994
  // the `context` property can be used to store any data about the accessory you may need
@@ -1878,7 +2000,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1878
2000
  : device.deviceType === 'Robot Vacuum Cleaner S10' ? SwitchBotModel.RobotVacuumCleanerS10
1879
2001
  : device.deviceType === 'WoSweeper' ? SwitchBotModel.WoSweeper : device.deviceType === 'WoSweeperMini' ? SwitchBotModel.WoSweeperMini
1880
2002
  : SwitchBotModel.Unknown;
1881
- accessory.displayName = device.configDeviceName ?? device.deviceName;
2003
+ accessory.displayName = device.configDeviceName
2004
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2005
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2006
+ accessory.context.connectionType = await this.connectionType(device);
1882
2007
  accessory.context.connectionType = await this.connectionType(device);
1883
2008
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1884
2009
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1909,7 +2034,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1909
2034
  existingAccessory.context.deviceId = device.deviceId;
1910
2035
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1911
2036
  existingAccessory.context.model = device.remoteType;
1912
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
2037
+ existingAccessory.displayName = device.configDeviceName
2038
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2039
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1913
2040
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
1914
2041
  existingAccessory.context.connectionType = device.connectionType;
1915
2042
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -1919,7 +2046,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1919
2046
  await this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`);
1920
2047
  } else if (!device.hide_device && device.hubDeviceId) {
1921
2048
  // create a new accessory
1922
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
2049
+ const accessory = new this.api.platformAccessory(device.configDeviceName
2050
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2051
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1923
2052
 
1924
2053
  // store a copy of the device object in the `accessory.context`
1925
2054
  // the `context` property can be used to store any data about the accessory you may need
@@ -1927,7 +2056,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1927
2056
  accessory.context.deviceId = device.deviceId;
1928
2057
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1929
2058
  accessory.context.model = device.remoteType;
1930
- accessory.displayName = device.configDeviceName ?? device.deviceName;
2059
+ accessory.displayName = device.configDeviceName
2060
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2061
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2062
+ accessory.context.connectionType = await this.connectionType(device);
1931
2063
  accessory.context.connectionType = device.connectionType;
1932
2064
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1933
2065
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1959,7 +2091,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1959
2091
  existingAccessory.context.deviceId = device.deviceId;
1960
2092
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1961
2093
  existingAccessory.context.model = device.remoteType;
1962
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
2094
+ existingAccessory.displayName = device.configDeviceName
2095
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2096
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
1963
2097
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
1964
2098
  existingAccessory.context.connectionType = device.connectionType;
1965
2099
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -1972,7 +2106,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1972
2106
  }
1973
2107
  } else if (!device.hide_device && device.hubDeviceId) {
1974
2108
  // create a new accessory
1975
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
2109
+ const accessory = new this.api.platformAccessory(device.configDeviceName
2110
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2111
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
1976
2112
 
1977
2113
  // store a copy of the device object in the `accessory.context`
1978
2114
  // the `context` property can be used to store any data about the accessory you may need
@@ -1980,7 +2116,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1980
2116
  accessory.context.deviceId = device.deviceId;
1981
2117
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1982
2118
  accessory.context.model = device.remoteType;
1983
- accessory.displayName = device.configDeviceName ?? device.deviceName;
2119
+ accessory.displayName = device.configDeviceName
2120
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2121
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2122
+ accessory.context.connectionType = await this.connectionType(device);
1984
2123
  accessory.context.connectionType = device.connectionType;
1985
2124
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1986
2125
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2013,7 +2152,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2013
2152
  existingAccessory.context.deviceId = device.deviceId;
2014
2153
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2015
2154
  existingAccessory.context.model = device.remoteType;
2016
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
2155
+ existingAccessory.displayName = device.configDeviceName
2156
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2157
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2017
2158
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2018
2159
  existingAccessory.context.connectionType = device.connectionType;
2019
2160
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2026,7 +2167,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2026
2167
  }
2027
2168
  } else if (!device.hide_device && device.hubDeviceId) {
2028
2169
  // create a new accessory
2029
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
2170
+ const accessory = new this.api.platformAccessory(device.configDeviceName
2171
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2172
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
2030
2173
 
2031
2174
  // store a copy of the device object in the `accessory.context`
2032
2175
  // the `context` property can be used to store any data about the accessory you may need
@@ -2034,7 +2177,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2034
2177
  accessory.context.deviceId = device.deviceId;
2035
2178
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2036
2179
  accessory.context.model = device.remoteType;
2037
- accessory.displayName = device.configDeviceName ?? device.deviceName;
2180
+ accessory.displayName = device.configDeviceName
2181
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2182
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2183
+ accessory.context.connectionType = await this.connectionType(device);
2038
2184
  accessory.context.connectionType = device.connectionType;
2039
2185
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2040
2186
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2067,7 +2213,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2067
2213
  existingAccessory.context.deviceId = device.deviceId;
2068
2214
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2069
2215
  existingAccessory.context.model = device.remoteType;
2070
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
2216
+ existingAccessory.displayName = device.configDeviceName
2217
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2218
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2071
2219
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2072
2220
  existingAccessory.context.connectionType = device.connectionType;
2073
2221
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2080,7 +2228,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2080
2228
  }
2081
2229
  } else if (!device.hide_device && device.hubDeviceId) {
2082
2230
  // create a new accessory
2083
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
2231
+ const accessory = new this.api.platformAccessory(device.configDeviceName
2232
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2233
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
2084
2234
 
2085
2235
  // store a copy of the device object in the `accessory.context`
2086
2236
  // the `context` property can be used to store any data about the accessory you may need
@@ -2088,7 +2238,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2088
2238
  accessory.context.deviceId = device.deviceId;
2089
2239
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2090
2240
  accessory.context.model = device.remoteType;
2091
- accessory.displayName = device.configDeviceName ?? device.deviceName;
2241
+ accessory.displayName = device.configDeviceName
2242
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2243
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2244
+ accessory.context.connectionType = await this.connectionType(device);
2092
2245
  accessory.context.connectionType = device.connectionType;
2093
2246
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2094
2247
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2121,7 +2274,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2121
2274
  existingAccessory.context.deviceId = device.deviceId;
2122
2275
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2123
2276
  existingAccessory.context.model = device.remoteType;
2124
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
2277
+ existingAccessory.displayName = device.configDeviceName
2278
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2279
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2125
2280
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2126
2281
  existingAccessory.context.connectionType = device.connectionType;
2127
2282
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2134,7 +2289,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2134
2289
  }
2135
2290
  } else if (!device.hide_device && device.hubDeviceId) {
2136
2291
  // create a new accessory
2137
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
2292
+ const accessory = new this.api.platformAccessory(device.configDeviceName
2293
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2294
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
2138
2295
 
2139
2296
  // store a copy of the device object in the `accessory.context`
2140
2297
  // the `context` property can be used to store any data about the accessory you may need
@@ -2142,7 +2299,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2142
2299
  accessory.context.deviceId = device.deviceId;
2143
2300
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2144
2301
  accessory.context.model = device.remoteType;
2145
- accessory.displayName = device.configDeviceName ?? device.deviceName;
2302
+ accessory.displayName = device.configDeviceName
2303
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2304
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2305
+ accessory.context.connectionType = await this.connectionType(device);
2146
2306
  accessory.context.connectionType = device.connectionType;
2147
2307
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2148
2308
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2175,7 +2335,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2175
2335
  existingAccessory.context.deviceId = device.deviceId;
2176
2336
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2177
2337
  existingAccessory.context.model = device.remoteType;
2178
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
2338
+ existingAccessory.displayName = device.configDeviceName
2339
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2340
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2179
2341
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2180
2342
  existingAccessory.context.connectionType = device.connectionType;
2181
2343
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2188,7 +2350,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2188
2350
  }
2189
2351
  } else if (!device.hide_device && device.hubDeviceId) {
2190
2352
  // create a new accessory
2191
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
2353
+ const accessory = new this.api.platformAccessory(device.configDeviceName
2354
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2355
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
2192
2356
 
2193
2357
  // store a copy of the device object in the `accessory.context`
2194
2358
  // the `context` property can be used to store any data about the accessory you may need
@@ -2196,7 +2360,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2196
2360
  accessory.context.deviceId = device.deviceId;
2197
2361
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2198
2362
  accessory.context.model = device.remoteType;
2199
- accessory.displayName = device.configDeviceName ?? device.deviceName;
2363
+ accessory.displayName = device.configDeviceName
2364
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2365
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2366
+ accessory.context.connectionType = await this.connectionType(device);
2200
2367
  accessory.context.connectionType = device.connectionType;
2201
2368
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2202
2369
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2229,7 +2396,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2229
2396
  existingAccessory.context.deviceId = device.deviceId;
2230
2397
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2231
2398
  existingAccessory.context.model = device.remoteType;
2232
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
2399
+ existingAccessory.displayName = device.configDeviceName
2400
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2401
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2233
2402
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2234
2403
  existingAccessory.context.connectionType = device.connectionType;
2235
2404
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2242,7 +2411,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2242
2411
  }
2243
2412
  } else if (!device.hide_device && device.hubDeviceId) {
2244
2413
  // create a new accessory
2245
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
2414
+ const accessory = new this.api.platformAccessory(device.configDeviceName
2415
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2416
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
2246
2417
 
2247
2418
  // store a copy of the device object in the `accessory.context`
2248
2419
  // the `context` property can be used to store any data about the accessory you may need
@@ -2250,7 +2421,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2250
2421
  accessory.context.deviceId = device.deviceId;
2251
2422
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2252
2423
  accessory.context.model = device.remoteType;
2253
- accessory.displayName = device.configDeviceName ?? device.deviceName;
2424
+ accessory.displayName = device.configDeviceName
2425
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2426
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2427
+ accessory.context.connectionType = await this.connectionType(device);
2254
2428
  accessory.context.connectionType = device.connectionType;
2255
2429
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2256
2430
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2283,7 +2457,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2283
2457
  existingAccessory.context.deviceId = device.deviceId;
2284
2458
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2285
2459
  existingAccessory.context.model = device.remoteType;
2286
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
2460
+ existingAccessory.displayName = device.configDeviceName
2461
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2462
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2287
2463
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2288
2464
  existingAccessory.context.connectionType = device.connectionType;
2289
2465
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2296,7 +2472,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2296
2472
  }
2297
2473
  } else if (!device.hide_device && device.hubDeviceId) {
2298
2474
  // create a new accessory
2299
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
2475
+ const accessory = new this.api.platformAccessory(device.configDeviceName
2476
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2477
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
2300
2478
 
2301
2479
  // store a copy of the device object in the `accessory.context`
2302
2480
  // the `context` property can be used to store any data about the accessory you may need
@@ -2304,7 +2482,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2304
2482
  accessory.context.deviceId = device.deviceId;
2305
2483
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2306
2484
  accessory.context.model = device.remoteType;
2307
- accessory.displayName = device.configDeviceName ?? device.deviceName;
2485
+ accessory.displayName = device.configDeviceName
2486
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2487
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2488
+ accessory.context.connectionType = await this.connectionType(device);
2308
2489
  accessory.context.connectionType = device.connectionType;
2309
2490
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2310
2491
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2337,7 +2518,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2337
2518
  existingAccessory.context.deviceId = device.deviceId;
2338
2519
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2339
2520
  existingAccessory.context.model = device.remoteType;
2340
- existingAccessory.displayName = device.configDeviceName ?? device.deviceName;
2521
+ existingAccessory.displayName = device.configDeviceName
2522
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2523
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2341
2524
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2342
2525
  existingAccessory.context.connectionType = device.connectionType;
2343
2526
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2350,7 +2533,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2350
2533
  }
2351
2534
  } else if (!device.hide_device && device.hubDeviceId) {
2352
2535
  // create a new accessory
2353
- const accessory = new this.api.platformAccessory(device.deviceName, uuid);
2536
+ const accessory = new this.api.platformAccessory(device.configDeviceName
2537
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2538
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid);
2354
2539
 
2355
2540
  // store a copy of the device object in the `accessory.context`
2356
2541
  // the `context` property can be used to store any data about the accessory you may need
@@ -2358,7 +2543,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2358
2543
  accessory.context.deviceId = device.deviceId;
2359
2544
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2360
2545
  accessory.context.model = device.remoteType;
2361
- accessory.displayName = device.configDeviceName ?? device.deviceName;
2546
+ accessory.displayName = device.configDeviceName
2547
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2548
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2549
+ accessory.context.connectionType = await this.connectionType(device);
2362
2550
  accessory.context.connectionType = device.connectionType;
2363
2551
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2364
2552
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2719,7 +2907,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2719
2907
  }
2720
2908
 
2721
2909
  async getPlatformLogSettings() {
2722
- this.debugMode = process.argv.includes('-D') || process.argv.includes('--debug');
2910
+ this.debugMode = process.argv.includes('-D') ?? process.argv.includes('--debug');
2723
2911
  if (this.config.options?.logging === 'debug' || this.config.options?.logging === 'standard' || this.config.options?.logging === 'none') {
2724
2912
  this.platformLogging = this.config.options.logging;
2725
2913
  await this.debugWarnLog(`Using Config Logging: ${this.platformLogging}`);
@@ -2732,6 +2920,39 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2732
2920
  }
2733
2921
  }
2734
2922
 
2923
+ /**
2924
+ * Validate and clean a string value for a Name Characteristic.
2925
+ * @param displayName
2926
+ * @param name
2927
+ * @param value
2928
+ * @returns string value
2929
+ */
2930
+ async validateAndCleanDisplayName(displayName: string, name: string, value: string): Promise<string> {
2931
+ const validPattern = /^[a-zA-Z0-9][a-zA-Z0-9 ']*[a-zA-Z0-9]$/;
2932
+ const invalidCharsPattern = /[^a-zA-Z0-9 ']/g;
2933
+ const invalidStartEndPattern = /^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$/g;
2934
+
2935
+ if (!validPattern.test(value)) {
2936
+ this.warnLog(`WARNING: The accessory '${displayName}' has an invalid '${name}' characteristic ('${value}'). Please use only alphanumeric,`
2937
+ + ' space, and apostrophe characters. Ensure it starts and ends with an alphabetic or numeric character, and avoid emojis. This may'
2938
+ + ' prevent the accessory from being added in the Home App or cause unresponsiveness.');
2939
+
2940
+ // Remove invalid characters
2941
+ if (invalidCharsPattern.test(value)) {
2942
+ this.warnLog(`Removing invalid characters from '${name}' characteristic`);
2943
+ value = value.replace(invalidCharsPattern, '');
2944
+ }
2945
+
2946
+ // Ensure it starts and ends with an alphanumeric character
2947
+ if (invalidStartEndPattern.test(value)) {
2948
+ this.warnLog(`Removing invalid starting or ending characters from '${name}' characteristic`);
2949
+ value = value.replace(invalidStartEndPattern, '');
2950
+ }
2951
+ }
2952
+
2953
+ return value;
2954
+ }
2955
+
2735
2956
  /**
2736
2957
  * If device level logging is turned on, log to log.warn
2737
2958
  * Otherwise send debug logs to log.debug
@@ -2750,7 +2971,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2750
2971
 
2751
2972
  async debugSuccessLog(...log: any[]): Promise<void> {
2752
2973
  if (await this.enablingPlatformLogging()) {
2753
- if (this.platformLogging?.includes('debug')) {
2974
+ if (await this.loggingIsDebug()) {
2754
2975
  this.log.success('[DEBUG]', String(...log));
2755
2976
  }
2756
2977
  }
@@ -2764,7 +2985,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2764
2985
 
2765
2986
  async debugWarnLog(...log: any[]): Promise<void> {
2766
2987
  if (await this.enablingPlatformLogging()) {
2767
- if (this.platformLogging?.includes('debug')) {
2988
+ if (await this.loggingIsDebug()) {
2768
2989
  this.log.warn('[DEBUG]', String(...log));
2769
2990
  }
2770
2991
  }
@@ -2778,7 +2999,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2778
2999
 
2779
3000
  async debugErrorLog(...log: any[]): Promise<void> {
2780
3001
  if (await this.enablingPlatformLogging()) {
2781
- if (this.platformLogging?.includes('debug')) {
3002
+ if (await this.loggingIsDebug()) {
2782
3003
  this.log.error('[DEBUG]', String(...log));
2783
3004
  }
2784
3005
  }
@@ -2786,15 +3007,19 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2786
3007
 
2787
3008
  async debugLog(...log: any[]): Promise<void> {
2788
3009
  if (await this.enablingPlatformLogging()) {
2789
- if (this.platformLogging === 'debugMode') {
2790
- this.log.debug(String(...log));
2791
- } else if (this.platformLogging === 'debug') {
3010
+ if (this.platformLogging === 'debug') {
2792
3011
  this.log.info('[DEBUG]', String(...log));
3012
+ } else if (this.platformLogging === 'debugMode') {
3013
+ this.log.debug(String(...log));
2793
3014
  }
2794
3015
  }
2795
3016
  }
2796
3017
 
3018
+ async loggingIsDebug(): Promise<boolean> {
3019
+ return this.platformLogging === 'debugMode' || this.platformLogging === 'debug';
3020
+ }
3021
+
2797
3022
  async enablingPlatformLogging(): Promise<boolean> {
2798
- return this.platformLogging?.includes('debug') || this.platformLogging === 'standard';
3023
+ return this.platformLogging === 'debugMode' || this.platformLogging === 'debug' || this.platformLogging === 'standard';
2799
3024
  }
2800
3025
  }