@switchbot/homebridge-switchbot 3.6.1-beta.8 → 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 +319 -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 +324 -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
@@ -336,6 +336,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
336
336
  }
337
337
  };
338
338
  })();
339
+
340
+ this.api.on('shutdown', async () => {
341
+ try {
342
+ switchbot.stopScan();
343
+ this.infoLog('Stopped BLE scanning to close listening.');
344
+ } catch (e: any) {
345
+ this.errorLog(`Failed to stop Platform BLE scanning. Error:${e.message}`);
346
+ }
347
+ });
339
348
  }
340
349
  } else {
341
350
  await this.debugLog('Platform BLE is not enabled');
@@ -871,7 +880,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
871
880
  existingAccessory.context.deviceId = device.deviceId;
872
881
  existingAccessory.context.deviceType = device.deviceType;
873
882
  existingAccessory.context.model = SwitchBotModel.Humidifier;
874
- 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);
875
886
  existingAccessory.context.connectionType = await this.connectionType(device);
876
887
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
877
888
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -885,7 +896,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
885
896
  }
886
897
  } else if (await this.registerDevice(device)) {
887
898
  // create a new accessory
888
- 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);
889
902
 
890
903
  // store a copy of the device object in the `accessory.context`
891
904
  // the `context` property can be used to store any data about the accessory you may need
@@ -893,7 +906,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
893
906
  accessory.context.deviceId = device.deviceId;
894
907
  accessory.context.deviceType = device.deviceType;
895
908
  accessory.context.model = SwitchBotModel.Humidifier;
896
- 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);
897
912
  accessory.context.connectionType = await this.connectionType(device);
898
913
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
899
914
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -926,7 +941,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
926
941
  existingAccessory.context.deviceId = device.deviceId;
927
942
  existingAccessory.context.deviceType = device.deviceType;
928
943
  existingAccessory.context.model = SwitchBotModel.Bot;
929
- 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);
930
947
  existingAccessory.context.connectionType = await this.connectionType(device);
931
948
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
932
949
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -940,7 +957,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
940
957
  }
941
958
  } else if (await this.registerDevice(device)) {
942
959
  // create a new accessory
943
- 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);
944
963
 
945
964
  // store a copy of the device object in the `accessory.context`
946
965
  // the `context` property can be used to store any data about the accessory you may need
@@ -948,7 +967,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
948
967
  accessory.context.deviceId = device.deviceId;
949
968
  accessory.context.deviceType = device.deviceType;
950
969
  accessory.context.model = SwitchBotModel.Bot;
951
- 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);
952
974
  accessory.context.connectionType = await this.connectionType(device);
953
975
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
954
976
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -982,7 +1004,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
982
1004
  existingAccessory.context.model = SwitchBotModel.Meter;
983
1005
  existingAccessory.context.deviceId = device.deviceId;
984
1006
  existingAccessory.context.deviceType = device.deviceType;
985
- 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);
986
1010
  existingAccessory.context.connectionType = await this.connectionType(device);
987
1011
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
988
1012
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -996,7 +1020,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
996
1020
  }
997
1021
  } else if (await this.registerDevice(device)) {
998
1022
  // create a new accessory
999
- 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);
1000
1026
 
1001
1027
  // store a copy of the device object in the `accessory.context`
1002
1028
  // the `context` property can be used to store any data about the accessory you may need
@@ -1004,7 +1030,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1004
1030
  accessory.context.model = SwitchBotModel.Meter;
1005
1031
  accessory.context.deviceId = device.deviceId;
1006
1032
  accessory.context.deviceType = device.deviceType;
1007
- 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);
1008
1037
  accessory.context.connectionType = await this.connectionType(device);
1009
1038
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1010
1039
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1038,7 +1067,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1038
1067
  existingAccessory.context.model = SwitchBotModel.MeterPlusUS ?? SwitchBotModel.MeterPlusJP;
1039
1068
  existingAccessory.context.deviceId = device.deviceId;
1040
1069
  existingAccessory.context.deviceType = device.deviceType;
1041
- 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);
1042
1073
  existingAccessory.context.connectionType = await this.connectionType(device);
1043
1074
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1044
1075
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1052,7 +1083,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1052
1083
  }
1053
1084
  } else if (await this.registerDevice(device)) {
1054
1085
  // create a new accessory
1055
- 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);
1056
1089
 
1057
1090
  // store a copy of the device object in the `accessory.context`
1058
1091
  // the `context` property can be used to store any data about the accessory you may need
@@ -1060,7 +1093,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1060
1093
  accessory.context.model = SwitchBotModel.MeterPlusUS ?? SwitchBotModel.MeterPlusJP;
1061
1094
  accessory.context.deviceId = device.deviceId;
1062
1095
  accessory.context.deviceType = device.deviceType;
1063
- 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);
1064
1100
  accessory.context.connectionType = await this.connectionType(device);
1065
1101
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1066
1102
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1094,7 +1130,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1094
1130
  existingAccessory.context.model = SwitchBotModel.Hub2;
1095
1131
  existingAccessory.context.deviceId = device.deviceId;
1096
1132
  existingAccessory.context.deviceType = device.deviceType;
1097
- 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);
1098
1136
  existingAccessory.context.connectionType = await this.connectionType(device);
1099
1137
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1100
1138
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1108,7 +1146,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1108
1146
  }
1109
1147
  } else if (await this.registerDevice(device)) {
1110
1148
  // create a new accessory
1111
- 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);
1112
1152
 
1113
1153
  // store a copy of the device object in the `accessory.context`
1114
1154
  // the `context` property can be used to store any data about the accessory you may need
@@ -1116,7 +1156,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1116
1156
  accessory.context.model = SwitchBotModel.Hub2;
1117
1157
  accessory.context.deviceId = device.deviceId;
1118
1158
  accessory.context.deviceType = device.deviceType;
1119
- 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);
1120
1163
  accessory.context.connectionType = await this.connectionType(device);
1121
1164
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1122
1165
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1149,7 +1192,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1149
1192
  existingAccessory.context.model = SwitchBotModel.OutdoorMeter;
1150
1193
  existingAccessory.context.deviceId = device.deviceId;
1151
1194
  existingAccessory.context.deviceType = device.deviceType;
1152
- 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);
1153
1198
  existingAccessory.context.connectionType = await this.connectionType(device);
1154
1199
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1155
1200
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1163,7 +1208,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1163
1208
  }
1164
1209
  } else if (await this.registerDevice(device)) {
1165
1210
  // create a new accessory
1166
- 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);
1167
1214
 
1168
1215
  // store a copy of the device object in the `accessory.context`
1169
1216
  // the `context` property can be used to store any data about the accessory you may need
@@ -1171,7 +1218,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1171
1218
  accessory.context.model = SwitchBotModel.OutdoorMeter;
1172
1219
  accessory.context.deviceId = device.deviceId;
1173
1220
  accessory.context.deviceType = device.deviceType;
1174
- 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);
1175
1225
  accessory.context.connectionType = await this.connectionType(device);
1176
1226
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1177
1227
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1204,7 +1254,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1204
1254
  existingAccessory.context.deviceId = device.deviceId;
1205
1255
  existingAccessory.context.deviceType = device.deviceType;
1206
1256
  existingAccessory.context.model = SwitchBotModel.WaterDetector;
1207
- 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);
1208
1260
  existingAccessory.context.connectionType = await this.connectionType(device);
1209
1261
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1210
1262
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1218,7 +1270,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1218
1270
  }
1219
1271
  } else if (await this.registerDevice(device)) {
1220
1272
  // create a new accessory
1221
- 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);
1222
1276
 
1223
1277
  // store a copy of the device object in the `accessory.context`
1224
1278
  // the `context` property can be used to store any data about the accessory you may need
@@ -1226,7 +1280,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1226
1280
  accessory.context.deviceId = device.deviceId;
1227
1281
  accessory.context.deviceType = device.deviceType;
1228
1282
  accessory.context.model = SwitchBotModel.WaterDetector;
1229
- 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);
1230
1287
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1231
1288
  accessory.context.connectionType = await this.connectionType(device);
1232
1289
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1259,7 +1316,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1259
1316
  existingAccessory.context.deviceId = device.deviceId;
1260
1317
  existingAccessory.context.deviceType = device.deviceType;
1261
1318
  existingAccessory.context.model = SwitchBotModel.MotionSensor;
1262
- 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);
1263
1322
  existingAccessory.context.connectionType = await this.connectionType(device);
1264
1323
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1265
1324
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1273,7 +1332,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1273
1332
  }
1274
1333
  } else if (await this.registerDevice(device)) {
1275
1334
  // create a new accessory
1276
- 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);
1277
1338
 
1278
1339
  // store a copy of the device object in the `accessory.context`
1279
1340
  // the `context` property can be used to store any data about the accessory you may need
@@ -1281,7 +1342,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1281
1342
  accessory.context.deviceId = device.deviceId;
1282
1343
  accessory.context.deviceType = device.deviceType;
1283
1344
  accessory.context.model = SwitchBotModel.MotionSensor;
1284
- 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);
1285
1349
  accessory.context.connectionType = await this.connectionType(device);
1286
1350
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1287
1351
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1314,7 +1378,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1314
1378
  existingAccessory.context.deviceId = device.deviceId;
1315
1379
  existingAccessory.context.deviceType = device.deviceType;
1316
1380
  existingAccessory.context.model = SwitchBotModel.ContactSensor;
1317
- 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);
1318
1384
  existingAccessory.context.connectionType = await this.connectionType(device);
1319
1385
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1320
1386
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1328,7 +1394,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1328
1394
  }
1329
1395
  } else if (await this.registerDevice(device)) {
1330
1396
  // create a new accessory
1331
- 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);
1332
1400
 
1333
1401
  // store a copy of the device object in the `accessory.context`
1334
1402
  // the `context` property can be used to store any data about the accessory you may need
@@ -1336,7 +1404,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1336
1404
  accessory.context.deviceId = device.deviceId;
1337
1405
  accessory.context.deviceType = device.deviceType;
1338
1406
  accessory.context.model = SwitchBotModel.ContactSensor;
1339
- 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);
1340
1411
  accessory.context.connectionType = await this.connectionType(device);
1341
1412
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1342
1413
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1369,7 +1440,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1369
1440
  existingAccessory.context.deviceId = device.deviceId;
1370
1441
  existingAccessory.context.deviceType = device.deviceType;
1371
1442
  existingAccessory.context.model = SwitchBotModel.BlindTilt;
1372
- 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);
1373
1446
  existingAccessory.context.connectionType = await this.connectionType(device);
1374
1447
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1375
1448
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1397,7 +1470,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1397
1470
  }
1398
1471
 
1399
1472
  // create a new accessory
1400
- 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);
1401
1476
 
1402
1477
  // store a copy of the device object in the `accessory.context`
1403
1478
  // the `context` property can be used to store any data about the accessory you may need
@@ -1405,7 +1480,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1405
1480
  accessory.context.deviceId = device.deviceId;
1406
1481
  accessory.context.deviceType = device.deviceType;
1407
1482
  accessory.context.model = SwitchBotModel.BlindTilt;
1408
- 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);
1409
1487
  accessory.context.connectionType = await this.connectionType(device);
1410
1488
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1411
1489
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1438,7 +1516,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1438
1516
  existingAccessory.context.deviceId = device.deviceId;
1439
1517
  existingAccessory.context.deviceType = device.deviceType;
1440
1518
  existingAccessory.context.model = device.deviceType === 'Curtain3' ? SwitchBotModel.Curtain3 : SwitchBotModel.Curtain;
1441
- 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);
1442
1522
  existingAccessory.context.connectionType = await this.connectionType(device);
1443
1523
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1444
1524
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1466,7 +1546,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1466
1546
  }
1467
1547
 
1468
1548
  // create a new accessory
1469
- 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);
1470
1552
 
1471
1553
  // store a copy of the device object in the `accessory.context`
1472
1554
  // the `context` property can be used to store any data about the accessory you may need
@@ -1474,7 +1556,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1474
1556
  accessory.context.deviceId = device.deviceId;
1475
1557
  accessory.context.deviceType = device.deviceType;
1476
1558
  accessory.context.model = device.deviceType === 'Curtain3' ? SwitchBotModel.Curtain3 : SwitchBotModel.Curtain;
1477
- 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);
1478
1563
  accessory.context.connectionType = await this.connectionType(device);
1479
1564
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1480
1565
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1508,7 +1593,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1508
1593
  existingAccessory.context.deviceType = device.deviceType;
1509
1594
  existingAccessory.context.model = device.deviceType === 'Plug Mini (US)' ? SwitchBotModel.PlugMiniUS : device.deviceType === 'Plug Mini (JP)'
1510
1595
  ? SwitchBotModel.PlugMiniJP : SwitchBotModel.Plug;
1511
- 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);
1512
1599
  existingAccessory.context.connectionType = await this.connectionType(device);
1513
1600
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1514
1601
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1522,7 +1609,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1522
1609
  }
1523
1610
  } else if (await this.registerDevice(device)) {
1524
1611
  // create a new accessory
1525
- 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);
1526
1615
 
1527
1616
  // store a copy of the device object in the `accessory.context`
1528
1617
  // the `context` property can be used to store any data about the accessory you may need
@@ -1531,7 +1620,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1531
1620
  accessory.context.deviceType = device.deviceType;
1532
1621
  accessory.context.model = device.deviceType === 'Plug Mini (US)' ? SwitchBotModel.PlugMiniUS : device.deviceType === 'Plug Mini (JP)'
1533
1622
  ? SwitchBotModel.PlugMiniJP : SwitchBotModel.Plug;
1534
- 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);
1535
1627
  accessory.context.connectionType = await this.connectionType(device);
1536
1628
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1537
1629
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1564,7 +1656,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1564
1656
  existingAccessory.context.deviceId = device.deviceId;
1565
1657
  existingAccessory.context.deviceType = device.deviceType;
1566
1658
  existingAccessory.context.model = device.deviceType === 'Smart Lock Pro' ? SwitchBotModel.LockPro : SwitchBotModel.Lock;
1567
- 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);
1568
1662
  existingAccessory.context.connectionType = await this.connectionType(device);
1569
1663
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1570
1664
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1578,7 +1672,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1578
1672
  }
1579
1673
  } else if (await this.registerDevice(device)) {
1580
1674
  // create a new accessory
1581
- 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);
1582
1678
 
1583
1679
  // store a copy of the device object in the `accessory.context`
1584
1680
  // the `context` property can be used to store any data about the accessory you may need
@@ -1586,7 +1682,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1586
1682
  accessory.context.deviceId = device.deviceId;
1587
1683
  accessory.context.deviceType = device.deviceType;
1588
1684
  accessory.context.model = device.deviceType === 'Smart Lock Pro' ? SwitchBotModel.LockPro : SwitchBotModel.Lock;
1589
- 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);
1590
1689
  accessory.context.connectionType = await this.connectionType(device);
1591
1690
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1592
1691
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1619,7 +1718,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1619
1718
  existingAccessory.context.deviceId = device.deviceId;
1620
1719
  existingAccessory.context.deviceType = device.deviceType;
1621
1720
  existingAccessory.context.model = SwitchBotModel.ColorBulb;
1622
- 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);
1623
1724
  existingAccessory.context.connectionType = await this.connectionType(device);
1624
1725
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1625
1726
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1633,7 +1734,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1633
1734
  }
1634
1735
  } else if (await this.registerDevice(device)) {
1635
1736
  // create a new accessory
1636
- 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);
1637
1740
 
1638
1741
  // store a copy of the device object in the `accessory.context`
1639
1742
  // the `context` property can be used to store any data about the accessory you may need
@@ -1641,7 +1744,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1641
1744
  accessory.context.deviceId = device.deviceId;
1642
1745
  accessory.context.deviceType = device.deviceType;
1643
1746
  accessory.context.model = SwitchBotModel.ColorBulb;
1644
- 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);
1645
1751
  accessory.context.connectionType = await this.connectionType(device);
1646
1752
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1647
1753
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1674,7 +1780,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1674
1780
  existingAccessory.context.deviceId = device.deviceId;
1675
1781
  existingAccessory.context.deviceType = device.deviceType;
1676
1782
  existingAccessory.context.model = device.deviceType === 'Ceiling Light Pro' ? SwitchBotModel.CeilingLightPro : SwitchBotModel.CeilingLight;
1677
- 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);
1678
1786
  existingAccessory.context.connectionType = await this.connectionType(device);
1679
1787
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1680
1788
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1688,7 +1796,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1688
1796
  }
1689
1797
  } else if (await this.registerDevice(device)) {
1690
1798
  // create a new accessory
1691
- 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);
1692
1802
 
1693
1803
  // store a copy of the device object in the `accessory.context`
1694
1804
  // the `context` property can be used to store any data about the accessory you may need
@@ -1696,7 +1806,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1696
1806
  accessory.context.deviceId = device.deviceId;
1697
1807
  accessory.context.deviceType = device.deviceType;
1698
1808
  accessory.context.model = device.deviceType === 'Ceiling Light Pro' ? SwitchBotModel.CeilingLightPro : SwitchBotModel.CeilingLight;
1699
- 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);
1700
1813
  accessory.context.connectionType = await this.connectionType(device);
1701
1814
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1702
1815
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1729,7 +1842,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1729
1842
  existingAccessory.context.deviceId = device.deviceId;
1730
1843
  existingAccessory.context.deviceType = device.deviceType;
1731
1844
  existingAccessory.context.model = SwitchBotModel.StripLight;
1732
- 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);
1733
1848
  existingAccessory.context.connectionType = await this.connectionType(device);
1734
1849
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1735
1850
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1743,7 +1858,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1743
1858
  }
1744
1859
  } else if (await this.registerDevice(device)) {
1745
1860
  // create a new accessory
1746
- 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);
1747
1864
 
1748
1865
  // store a copy of the device object in the `accessory.context`
1749
1866
  // the `context` property can be used to store any data about the accessory you may need
@@ -1751,7 +1868,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1751
1868
  accessory.context.deviceId = device.deviceId;
1752
1869
  accessory.context.deviceType = device.deviceType;
1753
1870
  accessory.context.model = SwitchBotModel.StripLight;
1754
- 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);
1755
1875
  accessory.context.connectionType = await this.connectionType(device);
1756
1876
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1757
1877
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1784,7 +1904,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1784
1904
  existingAccessory.context.deviceId = device.deviceId;
1785
1905
  existingAccessory.context.deviceType = device.deviceType;
1786
1906
  existingAccessory.context.model = SwitchBotModel.BatteryCirculatorFan;
1787
- 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);
1788
1910
  existingAccessory.context.connectionType = await this.connectionType(device);
1789
1911
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1790
1912
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1798,7 +1920,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1798
1920
  }
1799
1921
  } else if (await this.registerDevice(device)) {
1800
1922
  // create a new accessory
1801
- 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);
1802
1926
 
1803
1927
  // store a copy of the device object in the `accessory.context`
1804
1928
  // the `context` property can be used to store any data about the accessory you may need
@@ -1806,7 +1930,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1806
1930
  accessory.context.deviceId = device.deviceId;
1807
1931
  accessory.context.deviceType = device.deviceType;
1808
1932
  accessory.context.model = SwitchBotModel.BatteryCirculatorFan;
1809
- 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);
1810
1937
  accessory.context.connectionType = await this.connectionType(device);
1811
1938
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1812
1939
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1843,7 +1970,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1843
1970
  : device.deviceType === 'Robot Vacuum Cleaner S10' ? SwitchBotModel.RobotVacuumCleanerS10
1844
1971
  : device.deviceType === 'WoSweeper' ? SwitchBotModel.WoSweeper : device.deviceType === 'WoSweeperMini' ? SwitchBotModel.WoSweeperMini
1845
1972
  : SwitchBotModel.Unknown;
1846
- 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);
1847
1976
  existingAccessory.context.connectionType = await this.connectionType(device);
1848
1977
  existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1849
1978
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
@@ -1857,7 +1986,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1857
1986
  }
1858
1987
  } else if (await this.registerDevice(device)) {
1859
1988
  // create a new accessory
1860
- 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);
1861
1992
 
1862
1993
  // store a copy of the device object in the `accessory.context`
1863
1994
  // the `context` property can be used to store any data about the accessory you may need
@@ -1869,7 +2000,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1869
2000
  : device.deviceType === 'Robot Vacuum Cleaner S10' ? SwitchBotModel.RobotVacuumCleanerS10
1870
2001
  : device.deviceType === 'WoSweeper' ? SwitchBotModel.WoSweeper : device.deviceType === 'WoSweeperMini' ? SwitchBotModel.WoSweeperMini
1871
2002
  : SwitchBotModel.Unknown;
1872
- 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);
1873
2007
  accessory.context.connectionType = await this.connectionType(device);
1874
2008
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1875
2009
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1900,7 +2034,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1900
2034
  existingAccessory.context.deviceId = device.deviceId;
1901
2035
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1902
2036
  existingAccessory.context.model = device.remoteType;
1903
- 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);
1904
2040
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
1905
2041
  existingAccessory.context.connectionType = device.connectionType;
1906
2042
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -1910,7 +2046,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1910
2046
  await this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`);
1911
2047
  } else if (!device.hide_device && device.hubDeviceId) {
1912
2048
  // create a new accessory
1913
- 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);
1914
2052
 
1915
2053
  // store a copy of the device object in the `accessory.context`
1916
2054
  // the `context` property can be used to store any data about the accessory you may need
@@ -1918,7 +2056,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1918
2056
  accessory.context.deviceId = device.deviceId;
1919
2057
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1920
2058
  accessory.context.model = device.remoteType;
1921
- 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);
1922
2063
  accessory.context.connectionType = device.connectionType;
1923
2064
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1924
2065
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -1950,7 +2091,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1950
2091
  existingAccessory.context.deviceId = device.deviceId;
1951
2092
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1952
2093
  existingAccessory.context.model = device.remoteType;
1953
- 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);
1954
2097
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
1955
2098
  existingAccessory.context.connectionType = device.connectionType;
1956
2099
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -1963,7 +2106,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1963
2106
  }
1964
2107
  } else if (!device.hide_device && device.hubDeviceId) {
1965
2108
  // create a new accessory
1966
- 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);
1967
2112
 
1968
2113
  // store a copy of the device object in the `accessory.context`
1969
2114
  // the `context` property can be used to store any data about the accessory you may need
@@ -1971,7 +2116,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1971
2116
  accessory.context.deviceId = device.deviceId;
1972
2117
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1973
2118
  accessory.context.model = device.remoteType;
1974
- 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);
1975
2123
  accessory.context.connectionType = device.connectionType;
1976
2124
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
1977
2125
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2004,7 +2152,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2004
2152
  existingAccessory.context.deviceId = device.deviceId;
2005
2153
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2006
2154
  existingAccessory.context.model = device.remoteType;
2007
- 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);
2008
2158
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2009
2159
  existingAccessory.context.connectionType = device.connectionType;
2010
2160
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2017,7 +2167,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2017
2167
  }
2018
2168
  } else if (!device.hide_device && device.hubDeviceId) {
2019
2169
  // create a new accessory
2020
- 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);
2021
2173
 
2022
2174
  // store a copy of the device object in the `accessory.context`
2023
2175
  // the `context` property can be used to store any data about the accessory you may need
@@ -2025,7 +2177,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2025
2177
  accessory.context.deviceId = device.deviceId;
2026
2178
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2027
2179
  accessory.context.model = device.remoteType;
2028
- 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);
2029
2184
  accessory.context.connectionType = device.connectionType;
2030
2185
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2031
2186
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2058,7 +2213,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2058
2213
  existingAccessory.context.deviceId = device.deviceId;
2059
2214
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2060
2215
  existingAccessory.context.model = device.remoteType;
2061
- 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);
2062
2219
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2063
2220
  existingAccessory.context.connectionType = device.connectionType;
2064
2221
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2071,7 +2228,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2071
2228
  }
2072
2229
  } else if (!device.hide_device && device.hubDeviceId) {
2073
2230
  // create a new accessory
2074
- 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);
2075
2234
 
2076
2235
  // store a copy of the device object in the `accessory.context`
2077
2236
  // the `context` property can be used to store any data about the accessory you may need
@@ -2079,7 +2238,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2079
2238
  accessory.context.deviceId = device.deviceId;
2080
2239
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2081
2240
  accessory.context.model = device.remoteType;
2082
- 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);
2083
2245
  accessory.context.connectionType = device.connectionType;
2084
2246
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2085
2247
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2112,7 +2274,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2112
2274
  existingAccessory.context.deviceId = device.deviceId;
2113
2275
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2114
2276
  existingAccessory.context.model = device.remoteType;
2115
- 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);
2116
2280
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2117
2281
  existingAccessory.context.connectionType = device.connectionType;
2118
2282
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2125,7 +2289,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2125
2289
  }
2126
2290
  } else if (!device.hide_device && device.hubDeviceId) {
2127
2291
  // create a new accessory
2128
- 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);
2129
2295
 
2130
2296
  // store a copy of the device object in the `accessory.context`
2131
2297
  // the `context` property can be used to store any data about the accessory you may need
@@ -2133,7 +2299,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2133
2299
  accessory.context.deviceId = device.deviceId;
2134
2300
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2135
2301
  accessory.context.model = device.remoteType;
2136
- 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);
2137
2306
  accessory.context.connectionType = device.connectionType;
2138
2307
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2139
2308
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2166,7 +2335,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2166
2335
  existingAccessory.context.deviceId = device.deviceId;
2167
2336
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2168
2337
  existingAccessory.context.model = device.remoteType;
2169
- 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);
2170
2341
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2171
2342
  existingAccessory.context.connectionType = device.connectionType;
2172
2343
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2179,7 +2350,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2179
2350
  }
2180
2351
  } else if (!device.hide_device && device.hubDeviceId) {
2181
2352
  // create a new accessory
2182
- 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);
2183
2356
 
2184
2357
  // store a copy of the device object in the `accessory.context`
2185
2358
  // the `context` property can be used to store any data about the accessory you may need
@@ -2187,7 +2360,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2187
2360
  accessory.context.deviceId = device.deviceId;
2188
2361
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2189
2362
  accessory.context.model = device.remoteType;
2190
- 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);
2191
2367
  accessory.context.connectionType = device.connectionType;
2192
2368
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2193
2369
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2220,7 +2396,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2220
2396
  existingAccessory.context.deviceId = device.deviceId;
2221
2397
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2222
2398
  existingAccessory.context.model = device.remoteType;
2223
- 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);
2224
2402
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2225
2403
  existingAccessory.context.connectionType = device.connectionType;
2226
2404
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2233,7 +2411,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2233
2411
  }
2234
2412
  } else if (!device.hide_device && device.hubDeviceId) {
2235
2413
  // create a new accessory
2236
- 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);
2237
2417
 
2238
2418
  // store a copy of the device object in the `accessory.context`
2239
2419
  // the `context` property can be used to store any data about the accessory you may need
@@ -2241,7 +2421,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2241
2421
  accessory.context.deviceId = device.deviceId;
2242
2422
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2243
2423
  accessory.context.model = device.remoteType;
2244
- 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);
2245
2428
  accessory.context.connectionType = device.connectionType;
2246
2429
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2247
2430
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2274,7 +2457,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2274
2457
  existingAccessory.context.deviceId = device.deviceId;
2275
2458
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2276
2459
  existingAccessory.context.model = device.remoteType;
2277
- 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);
2278
2463
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2279
2464
  existingAccessory.context.connectionType = device.connectionType;
2280
2465
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2287,7 +2472,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2287
2472
  }
2288
2473
  } else if (!device.hide_device && device.hubDeviceId) {
2289
2474
  // create a new accessory
2290
- 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);
2291
2478
 
2292
2479
  // store a copy of the device object in the `accessory.context`
2293
2480
  // the `context` property can be used to store any data about the accessory you may need
@@ -2295,7 +2482,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2295
2482
  accessory.context.deviceId = device.deviceId;
2296
2483
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2297
2484
  accessory.context.model = device.remoteType;
2298
- 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);
2299
2489
  accessory.context.connectionType = device.connectionType;
2300
2490
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2301
2491
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2328,7 +2518,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2328
2518
  existingAccessory.context.deviceId = device.deviceId;
2329
2519
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2330
2520
  existingAccessory.context.model = device.remoteType;
2331
- 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);
2332
2524
  await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`);
2333
2525
  existingAccessory.context.connectionType = device.connectionType;
2334
2526
  this.api.updatePlatformAccessories([existingAccessory]);
@@ -2341,7 +2533,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2341
2533
  }
2342
2534
  } else if (!device.hide_device && device.hubDeviceId) {
2343
2535
  // create a new accessory
2344
- 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);
2345
2539
 
2346
2540
  // store a copy of the device object in the `accessory.context`
2347
2541
  // the `context` property can be used to store any data about the accessory you may need
@@ -2349,7 +2543,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2349
2543
  accessory.context.deviceId = device.deviceId;
2350
2544
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2351
2545
  accessory.context.model = device.remoteType;
2352
- 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);
2353
2550
  accessory.context.connectionType = device.connectionType;
2354
2551
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2355
2552
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
@@ -2710,7 +2907,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2710
2907
  }
2711
2908
 
2712
2909
  async getPlatformLogSettings() {
2713
- this.debugMode = process.argv.includes('-D') || process.argv.includes('--debug');
2910
+ this.debugMode = process.argv.includes('-D') ?? process.argv.includes('--debug');
2714
2911
  if (this.config.options?.logging === 'debug' || this.config.options?.logging === 'standard' || this.config.options?.logging === 'none') {
2715
2912
  this.platformLogging = this.config.options.logging;
2716
2913
  await this.debugWarnLog(`Using Config Logging: ${this.platformLogging}`);
@@ -2723,6 +2920,39 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2723
2920
  }
2724
2921
  }
2725
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
+
2726
2956
  /**
2727
2957
  * If device level logging is turned on, log to log.warn
2728
2958
  * Otherwise send debug logs to log.debug
@@ -2741,7 +2971,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2741
2971
 
2742
2972
  async debugSuccessLog(...log: any[]): Promise<void> {
2743
2973
  if (await this.enablingPlatformLogging()) {
2744
- if (this.platformLogging?.includes('debug')) {
2974
+ if (await this.loggingIsDebug()) {
2745
2975
  this.log.success('[DEBUG]', String(...log));
2746
2976
  }
2747
2977
  }
@@ -2755,7 +2985,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2755
2985
 
2756
2986
  async debugWarnLog(...log: any[]): Promise<void> {
2757
2987
  if (await this.enablingPlatformLogging()) {
2758
- if (this.platformLogging?.includes('debug')) {
2988
+ if (await this.loggingIsDebug()) {
2759
2989
  this.log.warn('[DEBUG]', String(...log));
2760
2990
  }
2761
2991
  }
@@ -2769,7 +2999,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2769
2999
 
2770
3000
  async debugErrorLog(...log: any[]): Promise<void> {
2771
3001
  if (await this.enablingPlatformLogging()) {
2772
- if (this.platformLogging?.includes('debug')) {
3002
+ if (await this.loggingIsDebug()) {
2773
3003
  this.log.error('[DEBUG]', String(...log));
2774
3004
  }
2775
3005
  }
@@ -2777,15 +3007,19 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2777
3007
 
2778
3008
  async debugLog(...log: any[]): Promise<void> {
2779
3009
  if (await this.enablingPlatformLogging()) {
2780
- if (this.platformLogging === 'debugMode') {
2781
- this.log.debug(String(...log));
2782
- } else if (this.platformLogging === 'debug') {
3010
+ if (this.platformLogging === 'debug') {
2783
3011
  this.log.info('[DEBUG]', String(...log));
3012
+ } else if (this.platformLogging === 'debugMode') {
3013
+ this.log.debug(String(...log));
2784
3014
  }
2785
3015
  }
2786
3016
  }
2787
3017
 
3018
+ async loggingIsDebug(): Promise<boolean> {
3019
+ return this.platformLogging === 'debugMode' || this.platformLogging === 'debug';
3020
+ }
3021
+
2788
3022
  async enablingPlatformLogging(): Promise<boolean> {
2789
- return this.platformLogging?.includes('debug') || this.platformLogging === 'standard';
3023
+ return this.platformLogging === 'debugMode' || this.platformLogging === 'debug' || this.platformLogging === 'standard';
2790
3024
  }
2791
3025
  }