@homebridge-plugins/homebridge-tuya 3.0.0-beta.7 → 3.0.0-beta.9

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 (281) hide show
  1. package/ADVANCED_OPTIONS.md +17 -0
  2. package/README.md +3 -1
  3. package/config.schema.json +387 -582
  4. package/dist/cloud/api/TuyaOpenAPI.js +5 -9
  5. package/dist/cloud/api/TuyaOpenAPI.js.map +1 -1
  6. package/dist/cloud/api/TuyaOpenMQ.js +3 -4
  7. package/dist/cloud/api/TuyaOpenMQ.js.map +1 -1
  8. package/dist/cloud/device/{TuyaDeviceManager.js → TuyaCloudDeviceManager.js} +98 -80
  9. package/dist/cloud/device/TuyaCloudDeviceManager.js.map +1 -0
  10. package/dist/cloud/device/TuyaCustomDeviceManager.js +74 -5
  11. package/dist/cloud/device/TuyaCustomDeviceManager.js.map +1 -1
  12. package/dist/cloud/device/TuyaHomeDeviceManager.js +76 -9
  13. package/dist/cloud/device/TuyaHomeDeviceManager.js.map +1 -1
  14. package/dist/config.js +26 -5
  15. package/dist/config.js.map +1 -1
  16. package/dist/local/DynamicChildDiscovery.js +2 -1
  17. package/dist/local/DynamicChildDiscovery.js.map +1 -1
  18. package/dist/local/LocalDevice.js +3 -2
  19. package/dist/local/LocalDevice.js.map +1 -1
  20. package/dist/local/LocalDeviceManager.js +120 -127
  21. package/dist/local/LocalDeviceManager.js.map +1 -1
  22. package/dist/local/TuyaDiscovery.js +14 -7
  23. package/dist/local/TuyaDiscovery.js.map +1 -1
  24. package/dist/local/ZigbeeGatewayDetection.js +2 -2
  25. package/dist/local/ZigbeeGatewayDetection.js.map +1 -1
  26. package/dist/local/protocol/ProtocolUtilities.js +34 -17
  27. package/dist/local/protocol/ProtocolUtilities.js.map +1 -1
  28. package/dist/local/protocol/ProtocolV31V32.js +4 -2
  29. package/dist/local/protocol/ProtocolV31V32.js.map +1 -1
  30. package/dist/local/protocol/ProtocolV33.js +4 -2
  31. package/dist/local/protocol/ProtocolV33.js.map +1 -1
  32. package/dist/local/protocol/ProtocolV34.js +10 -5
  33. package/dist/local/protocol/ProtocolV34.js.map +1 -1
  34. package/dist/local/protocol/ProtocolV35.js +8 -4
  35. package/dist/local/protocol/ProtocolV35.js.map +1 -1
  36. package/dist/platform.js +229 -493
  37. package/dist/platform.js.map +1 -1
  38. package/dist/settings.js +0 -2
  39. package/dist/settings.js.map +1 -1
  40. package/dist/shared/TuyaDeviceManager.js +97 -0
  41. package/dist/shared/TuyaDeviceManager.js.map +1 -0
  42. package/dist/shared/TuyaHybridDeviceManager.js +145 -0
  43. package/dist/shared/TuyaHybridDeviceManager.js.map +1 -0
  44. package/dist/shared/accessory/AccessoryFactory.js +334 -0
  45. package/dist/shared/accessory/AccessoryFactory.js.map +1 -0
  46. package/dist/shared/{accessories → accessory}/AirConditionerAccessory.js.map +1 -1
  47. package/dist/shared/{accessories → accessory}/AirPurifierAccessory.js.map +1 -1
  48. package/dist/shared/accessory/AirQualitySensorAccessory.js.map +1 -0
  49. package/dist/shared/{accessories → accessory}/BaseAccessory.js +16 -95
  50. package/dist/shared/accessory/BaseAccessory.js.map +1 -0
  51. package/dist/shared/{accessories → accessory}/BlindsAccessory.js.map +1 -1
  52. package/dist/shared/{accessories → accessory}/CameraAccessory.js.map +1 -1
  53. package/dist/shared/{accessories → accessory}/CarbonDioxideSensorAccessory.js.map +1 -1
  54. package/dist/shared/{accessories → accessory}/CarbonMonoxideSensorAccessory.js.map +1 -1
  55. package/dist/shared/{accessories → accessory}/ContactSensorAccessory.js.map +1 -1
  56. package/dist/shared/{accessories → accessory}/DehumidifierAccessory.js.map +1 -1
  57. package/dist/shared/{accessories → accessory}/DiffuserAccessory.js.map +1 -1
  58. package/dist/shared/{accessories → accessory}/DimmerAccessory.js.map +1 -1
  59. package/dist/shared/{accessories → accessory}/DoorbellAccessory.js.map +1 -1
  60. package/dist/shared/{accessories → accessory}/ExtractionHoodAccessory.js.map +1 -1
  61. package/dist/shared/{accessories → accessory}/FanAccessory.js.map +1 -1
  62. package/dist/shared/{accessories → accessory}/GarageDoorAccessory.js +19 -2
  63. package/dist/shared/accessory/GarageDoorAccessory.js.map +1 -0
  64. package/dist/shared/{accessories → accessory}/HeaterAccessory.js.map +1 -1
  65. package/dist/shared/{accessories → accessory}/HeaterAccessory_old.js.map +1 -1
  66. package/dist/shared/accessory/HumanPresenceSensorAccessory.js.map +1 -0
  67. package/dist/shared/{accessories → accessory}/HumidifierAccessory.js.map +1 -1
  68. package/dist/shared/accessory/IRAirConditionerAccessory.js.map +1 -0
  69. package/dist/shared/accessory/IRControlHubAccessory.js.map +1 -0
  70. package/dist/shared/accessory/IRControlHubSubAccessory.js.map +1 -0
  71. package/dist/shared/accessory/IRGenericAccessory.js.map +1 -0
  72. package/dist/shared/{accessories → accessory}/LeakSensorAccessory.js.map +1 -1
  73. package/dist/shared/{accessories → accessory}/LightAccessory.js.map +1 -1
  74. package/dist/shared/{accessories → accessory}/LightSensorAccessory.js.map +1 -1
  75. package/dist/shared/{accessories → accessory}/LocationWeatherAccessory.js +1 -1
  76. package/dist/shared/accessory/LocationWeatherAccessory.js.map +1 -0
  77. package/dist/shared/{accessories → accessory}/LockAccessory.js +3 -3
  78. package/dist/shared/{accessories → accessory}/LockAccessory.js.map +1 -1
  79. package/dist/shared/accessory/MotionSensorAccessory.js.map +1 -0
  80. package/dist/shared/accessory/OutletAccessory.js.map +1 -0
  81. package/dist/shared/{accessories → accessory}/PetFeederAccessory.js.map +1 -1
  82. package/dist/shared/{accessories → accessory}/SceneAccessory.js +1 -1
  83. package/dist/shared/accessory/SceneAccessory.js.map +1 -0
  84. package/dist/shared/accessory/SceneSwitchAccessory.js.map +1 -0
  85. package/dist/shared/accessory/SecuritySystemAccessory.js.map +1 -0
  86. package/dist/shared/{accessories → accessory}/SmokeSensorAccessory.js.map +1 -1
  87. package/dist/shared/{accessories → accessory}/SwitchAccessory.js +1 -45
  88. package/dist/shared/accessory/SwitchAccessory.js.map +1 -0
  89. package/dist/shared/accessory/TemperatureHumiditySensorAccessory.js.map +1 -0
  90. package/dist/shared/{accessories → accessory}/ThermostatAccessory.js.map +1 -1
  91. package/dist/shared/{accessories → accessory}/TowerRackAccessory.js.map +1 -1
  92. package/dist/shared/{accessories → accessory}/ValveAccessory.js.map +1 -1
  93. package/dist/shared/{accessories → accessory}/VibrationSensorAccessory.js.map +1 -1
  94. package/dist/shared/accessory/WeatherStationAccessory.js.map +1 -0
  95. package/dist/shared/accessory/WetBulbGlobeTemperatureAccessory.js.map +1 -0
  96. package/dist/shared/{accessories → accessory}/WhiteNoiseLightAccessory.js +1 -0
  97. package/dist/shared/accessory/WhiteNoiseLightAccessory.js.map +1 -0
  98. package/dist/shared/accessory/WindowAccessory.js.map +1 -0
  99. package/dist/shared/{accessories → accessory}/WindowCoveringAccessory.js.map +1 -1
  100. package/dist/shared/{accessories → accessory}/WirelessSwitchAccessory.js.map +1 -1
  101. package/dist/shared/accessory/characteristic/Active.js.map +1 -0
  102. package/dist/shared/accessory/characteristic/AirQuality.js.map +1 -0
  103. package/dist/shared/accessory/characteristic/CurrentRelativeHumidity.js.map +1 -0
  104. package/dist/shared/accessory/characteristic/CurrentTemperature.js.map +1 -0
  105. package/dist/shared/accessory/characteristic/CurrentWeather.js.map +1 -0
  106. package/dist/shared/accessory/characteristic/CurrentWeatherByOpenMeteo.js.map +1 -0
  107. package/dist/shared/accessory/characteristic/CurrentWetBulbGlobeTemperature.js.map +1 -0
  108. package/dist/shared/{accessories → accessory}/characteristic/EnergyUsage.js +0 -5
  109. package/dist/shared/accessory/characteristic/EnergyUsage.js.map +1 -0
  110. package/dist/shared/{accessories → accessory}/characteristic/Light.js +5 -3
  111. package/dist/shared/accessory/characteristic/Light.js.map +1 -0
  112. package/dist/shared/accessory/characteristic/LightSensor.js.map +1 -0
  113. package/dist/shared/accessory/characteristic/LockPhysicalControls.js.map +1 -0
  114. package/dist/shared/accessory/characteristic/MotionDetected.js.map +1 -0
  115. package/dist/shared/accessory/characteristic/Name.js.map +1 -0
  116. package/dist/shared/accessory/characteristic/OccupancyDetected.js.map +1 -0
  117. package/dist/shared/{accessories → accessory}/characteristic/On.js +1 -0
  118. package/dist/shared/accessory/characteristic/On.js.map +1 -0
  119. package/dist/shared/accessory/characteristic/OutletInUse.js.map +1 -0
  120. package/dist/shared/accessory/characteristic/ProgrammableSwitchEvent.js.map +1 -0
  121. package/dist/shared/accessory/characteristic/RelativeHumidityDehumidifierThreshold.js.map +1 -0
  122. package/dist/shared/accessory/characteristic/RotationSpeed.js.map +1 -0
  123. package/dist/shared/accessory/characteristic/SecuritySystemState.js.map +1 -0
  124. package/dist/shared/accessory/characteristic/SwingMode.js.map +1 -0
  125. package/dist/shared/accessory/characteristic/TargetTemperature.js.map +1 -0
  126. package/dist/shared/accessory/characteristic/TemperatureDisplayUnits.js.map +1 -0
  127. package/dist/shared/util/ConfigHash.js +2 -2
  128. package/dist/shared/util/ConfigHash.js.map +1 -1
  129. package/dist/shared/util/ConfigMigrator.js +173 -0
  130. package/dist/shared/util/ConfigMigrator.js.map +1 -0
  131. package/dist/shared/util/FfmpegStreamingProcess.js.map +1 -1
  132. package/dist/shared/util/InfraredTool.js +0 -2
  133. package/dist/shared/util/InfraredTool.js.map +1 -1
  134. package/dist/shared/util/Logger.js +69 -10
  135. package/dist/shared/util/Logger.js.map +1 -1
  136. package/dist/shared/util/TuyaStreamDelegate.js +2 -8
  137. package/dist/shared/util/TuyaStreamDelegate.js.map +1 -1
  138. package/dist/shared/util/util.js +13 -4
  139. package/dist/shared/util/util.js.map +1 -1
  140. package/eslint.config.mjs +0 -1
  141. package/{jest.config.js → jest.config.ts} +5 -2
  142. package/package.json +11 -8
  143. package/test/ConfigMigrator.test.ts +799 -0
  144. package/test/Logger.test.ts +482 -0
  145. package/test/accessoryFactory.data.test.ts +172 -0
  146. package/test/accessoryFactory.test.ts +64 -35
  147. package/test/config.test.ts +17 -13
  148. package/test/custom.test.ts +2 -2
  149. package/test/errorHandling.test.ts +12 -12
  150. package/test/home.test.ts +1 -1
  151. package/test/hybridDeviceManager.test.ts +808 -0
  152. package/test/localDevice.test.ts +21 -50
  153. package/test/localDeviceManager.behavior.test.ts +16 -30
  154. package/test/localDeviceManager.test.ts +23 -39
  155. package/test/mqttMessages.test.ts +33 -14
  156. package/test/platform.test.ts +340 -810
  157. package/test/platform.validation.local.test.ts +58 -119
  158. package/test/tuyaCustomDeviceManager.test.ts +106 -16
  159. package/test/tuyaDeviceManager.test.ts +636 -639
  160. package/test/tuyaDiscovery.test.ts +21 -33
  161. package/test/tuyaHomeDeviceManager.test.ts +109 -18
  162. package/test/tuyaOpenAPI.test.ts +25 -44
  163. package/test/tuyaOpenMQ.test.ts +15 -23
  164. package/test/util.test.ts +87 -7
  165. package/test/zigbee/LocalDevice.zigbee.test.ts +14 -18
  166. package/test/zigbee/LocalDeviceManager.cloud-discovery.test.ts +19 -20
  167. package/test/zigbee/LocalDeviceManager.zigbee.reconnect.test.ts +18 -20
  168. package/test/zigbee/LocalDeviceManager.zigbee.test.ts +31 -34
  169. package/test/zigbee/ZigbeeGatewayDetection.test.ts +2 -2
  170. package/dist/cloud/device/TuyaDeviceManager.js.map +0 -1
  171. package/dist/local/CloudLocalReconciliation.js +0 -180
  172. package/dist/local/CloudLocalReconciliation.js.map +0 -1
  173. package/dist/shared/accessories/AccessoryFactory.js +0 -309
  174. package/dist/shared/accessories/AccessoryFactory.js.map +0 -1
  175. package/dist/shared/accessories/AirQualitySensorAccessory.js.map +0 -1
  176. package/dist/shared/accessories/BaseAccessory.js.map +0 -1
  177. package/dist/shared/accessories/GarageDoorAccessory.js.map +0 -1
  178. package/dist/shared/accessories/HumanPresenceSensorAccessory.js.map +0 -1
  179. package/dist/shared/accessories/IRAirConditionerAccessory.js.map +0 -1
  180. package/dist/shared/accessories/IRControlHubAccessory.js.map +0 -1
  181. package/dist/shared/accessories/IRControlHubSubAccessory.js.map +0 -1
  182. package/dist/shared/accessories/IRGenericAccessory.js.map +0 -1
  183. package/dist/shared/accessories/LocationWeatherAccessory.js.map +0 -1
  184. package/dist/shared/accessories/MotionSensorAccessory.js.map +0 -1
  185. package/dist/shared/accessories/OutletAccessory.js.map +0 -1
  186. package/dist/shared/accessories/SceneAccessory.js.map +0 -1
  187. package/dist/shared/accessories/SceneSwitchAccessory.js.map +0 -1
  188. package/dist/shared/accessories/SecuritySystemAccessory.js.map +0 -1
  189. package/dist/shared/accessories/SwitchAccessory.js.map +0 -1
  190. package/dist/shared/accessories/TemperatureHumiditySensorAccessory.js.map +0 -1
  191. package/dist/shared/accessories/WeatherStationAccessory.js.map +0 -1
  192. package/dist/shared/accessories/WetBulbGlobeTemperatureAccessory.js.map +0 -1
  193. package/dist/shared/accessories/WhiteNoiseLightAccessory.js.map +0 -1
  194. package/dist/shared/accessories/WindowAccessory.js.map +0 -1
  195. package/dist/shared/accessories/characteristic/Active.js.map +0 -1
  196. package/dist/shared/accessories/characteristic/AirQuality.js.map +0 -1
  197. package/dist/shared/accessories/characteristic/CurrentRelativeHumidity.js.map +0 -1
  198. package/dist/shared/accessories/characteristic/CurrentTemperature.js.map +0 -1
  199. package/dist/shared/accessories/characteristic/CurrentWeather.js.map +0 -1
  200. package/dist/shared/accessories/characteristic/CurrentWeatherByOpenMeteo.js.map +0 -1
  201. package/dist/shared/accessories/characteristic/CurrentWetBulbGlobeTemperature.js.map +0 -1
  202. package/dist/shared/accessories/characteristic/EnergyUsage.js.map +0 -1
  203. package/dist/shared/accessories/characteristic/Light.js.map +0 -1
  204. package/dist/shared/accessories/characteristic/LightSensor.js.map +0 -1
  205. package/dist/shared/accessories/characteristic/LockPhysicalControls.js.map +0 -1
  206. package/dist/shared/accessories/characteristic/MotionDetected.js.map +0 -1
  207. package/dist/shared/accessories/characteristic/Name.js.map +0 -1
  208. package/dist/shared/accessories/characteristic/OccupancyDetected.js.map +0 -1
  209. package/dist/shared/accessories/characteristic/On.js.map +0 -1
  210. package/dist/shared/accessories/characteristic/OutletInUse.js.map +0 -1
  211. package/dist/shared/accessories/characteristic/ProgrammableSwitchEvent.js.map +0 -1
  212. package/dist/shared/accessories/characteristic/RelativeHumidityDehumidifierThreshold.js.map +0 -1
  213. package/dist/shared/accessories/characteristic/RotationSpeed.js.map +0 -1
  214. package/dist/shared/accessories/characteristic/SecuritySystemState.js.map +0 -1
  215. package/dist/shared/accessories/characteristic/SwingMode.js.map +0 -1
  216. package/dist/shared/accessories/characteristic/TargetTemperature.js.map +0 -1
  217. package/dist/shared/accessories/characteristic/TemperatureDisplayUnits.js.map +0 -1
  218. package/test/zigbee/CloudLocalReconciliation.test.ts +0 -284
  219. package/tuya-local-configs/dev-1.hash +0 -1
  220. package/tuya-local-configs/device1.hash +0 -1
  221. /package/dist/shared/{accessories → accessory}/AirConditionerAccessory.js +0 -0
  222. /package/dist/shared/{accessories → accessory}/AirPurifierAccessory.js +0 -0
  223. /package/dist/shared/{accessories → accessory}/AirQualitySensorAccessory.js +0 -0
  224. /package/dist/shared/{accessories → accessory}/BlindsAccessory.js +0 -0
  225. /package/dist/shared/{accessories → accessory}/CameraAccessory.js +0 -0
  226. /package/dist/shared/{accessories → accessory}/CarbonDioxideSensorAccessory.js +0 -0
  227. /package/dist/shared/{accessories → accessory}/CarbonMonoxideSensorAccessory.js +0 -0
  228. /package/dist/shared/{accessories → accessory}/ContactSensorAccessory.js +0 -0
  229. /package/dist/shared/{accessories → accessory}/DehumidifierAccessory.js +0 -0
  230. /package/dist/shared/{accessories → accessory}/DiffuserAccessory.js +0 -0
  231. /package/dist/shared/{accessories → accessory}/DimmerAccessory.js +0 -0
  232. /package/dist/shared/{accessories → accessory}/DoorbellAccessory.js +0 -0
  233. /package/dist/shared/{accessories → accessory}/ExtractionHoodAccessory.js +0 -0
  234. /package/dist/shared/{accessories → accessory}/FanAccessory.js +0 -0
  235. /package/dist/shared/{accessories → accessory}/HeaterAccessory.js +0 -0
  236. /package/dist/shared/{accessories → accessory}/HeaterAccessory_old.js +0 -0
  237. /package/dist/shared/{accessories → accessory}/HumanPresenceSensorAccessory.js +0 -0
  238. /package/dist/shared/{accessories → accessory}/HumidifierAccessory.js +0 -0
  239. /package/dist/shared/{accessories → accessory}/IRAirConditionerAccessory.js +0 -0
  240. /package/dist/shared/{accessories → accessory}/IRControlHubAccessory.js +0 -0
  241. /package/dist/shared/{accessories → accessory}/IRControlHubSubAccessory.js +0 -0
  242. /package/dist/shared/{accessories → accessory}/IRGenericAccessory.js +0 -0
  243. /package/dist/shared/{accessories → accessory}/LeakSensorAccessory.js +0 -0
  244. /package/dist/shared/{accessories → accessory}/LightAccessory.js +0 -0
  245. /package/dist/shared/{accessories → accessory}/LightSensorAccessory.js +0 -0
  246. /package/dist/shared/{accessories → accessory}/MotionSensorAccessory.js +0 -0
  247. /package/dist/shared/{accessories → accessory}/OutletAccessory.js +0 -0
  248. /package/dist/shared/{accessories → accessory}/PetFeederAccessory.js +0 -0
  249. /package/dist/shared/{accessories → accessory}/SceneSwitchAccessory.js +0 -0
  250. /package/dist/shared/{accessories → accessory}/SecuritySystemAccessory.js +0 -0
  251. /package/dist/shared/{accessories → accessory}/SmokeSensorAccessory.js +0 -0
  252. /package/dist/shared/{accessories → accessory}/TemperatureHumiditySensorAccessory.js +0 -0
  253. /package/dist/shared/{accessories → accessory}/ThermostatAccessory.js +0 -0
  254. /package/dist/shared/{accessories → accessory}/TowerRackAccessory.js +0 -0
  255. /package/dist/shared/{accessories → accessory}/ValveAccessory.js +0 -0
  256. /package/dist/shared/{accessories → accessory}/VibrationSensorAccessory.js +0 -0
  257. /package/dist/shared/{accessories → accessory}/WeatherStationAccessory.js +0 -0
  258. /package/dist/shared/{accessories → accessory}/WetBulbGlobeTemperatureAccessory.js +0 -0
  259. /package/dist/shared/{accessories → accessory}/WindowAccessory.js +0 -0
  260. /package/dist/shared/{accessories → accessory}/WindowCoveringAccessory.js +0 -0
  261. /package/dist/shared/{accessories → accessory}/WirelessSwitchAccessory.js +0 -0
  262. /package/dist/shared/{accessories → accessory}/characteristic/Active.js +0 -0
  263. /package/dist/shared/{accessories → accessory}/characteristic/AirQuality.js +0 -0
  264. /package/dist/shared/{accessories → accessory}/characteristic/CurrentRelativeHumidity.js +0 -0
  265. /package/dist/shared/{accessories → accessory}/characteristic/CurrentTemperature.js +0 -0
  266. /package/dist/shared/{accessories → accessory}/characteristic/CurrentWeather.js +0 -0
  267. /package/dist/shared/{accessories → accessory}/characteristic/CurrentWeatherByOpenMeteo.js +0 -0
  268. /package/dist/shared/{accessories → accessory}/characteristic/CurrentWetBulbGlobeTemperature.js +0 -0
  269. /package/dist/shared/{accessories → accessory}/characteristic/LightSensor.js +0 -0
  270. /package/dist/shared/{accessories → accessory}/characteristic/LockPhysicalControls.js +0 -0
  271. /package/dist/shared/{accessories → accessory}/characteristic/MotionDetected.js +0 -0
  272. /package/dist/shared/{accessories → accessory}/characteristic/Name.js +0 -0
  273. /package/dist/shared/{accessories → accessory}/characteristic/OccupancyDetected.js +0 -0
  274. /package/dist/shared/{accessories → accessory}/characteristic/OutletInUse.js +0 -0
  275. /package/dist/shared/{accessories → accessory}/characteristic/ProgrammableSwitchEvent.js +0 -0
  276. /package/dist/shared/{accessories → accessory}/characteristic/RelativeHumidityDehumidifierThreshold.js +0 -0
  277. /package/dist/shared/{accessories → accessory}/characteristic/RotationSpeed.js +0 -0
  278. /package/dist/shared/{accessories → accessory}/characteristic/SecuritySystemState.js +0 -0
  279. /package/dist/shared/{accessories → accessory}/characteristic/SwingMode.js +0 -0
  280. /package/dist/shared/{accessories → accessory}/characteristic/TargetTemperature.js +0 -0
  281. /package/dist/shared/{accessories → accessory}/characteristic/TemperatureDisplayUnits.js +0 -0
@@ -5,6 +5,288 @@
5
5
  "headerDisplay": "<p align='center'><img height='60px' src='https://user-images.githubusercontent.com/3979615/78354049-dc7ff780-75f6-11ea-8026-2f8bf81d8331.png'></p>",
6
6
  "footerDisplay": "",
7
7
  "customUi": false,
8
+ "layout": [
9
+ {
10
+ "type": "radiobuttons",
11
+ "key": "mode",
12
+ "style": { "selected": "btn-secondary", "unselected": "btn-outline-secondary" }
13
+ },
14
+ {
15
+ "type": "fieldset",
16
+ "items": [
17
+ {
18
+ "type": "tabs",
19
+ "tabs": [
20
+ {
21
+ "type": "fieldset",
22
+ "title": "Local Settings",
23
+ "notitle": true,
24
+ "items": [
25
+ {
26
+ "type": "help",
27
+ "labelHtmlClass": "alert-link alert-warning",
28
+ "helpvalue": "⚠These settings are currently inactive because Cloud mode is enabled.",
29
+ "condition": { "functionBody": "return (model.mode === 'cloud')" }
30
+ },
31
+ "local.autoDiscoverDevices",
32
+ "local.discoverTimeout",
33
+ "local.rediscoverInterval",
34
+ {
35
+ "key": "local.devices",
36
+ "add": "Add Manual Device",
37
+ "title": "{{ 'Add New Device' }}",
38
+ "type": "tabarray",
39
+ "notitle": true,
40
+ "items": [
41
+ {
42
+ "type": "div",
43
+ "displayFlex": false,
44
+ "notitle": true,
45
+ "title": "{{ value.name || value.tuyaDeviceId || 'New Device' }}",
46
+ "items": [
47
+ "local.devices[].category",
48
+ "local.devices[].name",
49
+ "local.devices[].tuyaDeviceId",
50
+ "local.devices[].tuyaKey",
51
+ "local.devices[].ip",
52
+ "local.devices[].protocolVersion",
53
+ "local.devices[].dpMapping",
54
+ "local.devices[].outletCount",
55
+ "local.devices[].outlets",
56
+ "local.devices[].dpPower",
57
+ "local.devices[].dpBrightness",
58
+ "local.devices[].dpColorTemperature",
59
+ "local.devices[].minWhiteColor",
60
+ "local.devices[].maxWhiteColor",
61
+ "local.devices[].dpMode",
62
+ "local.devices[].dpColor",
63
+ "local.devices[].colorFunction",
64
+ "local.devices[].scaleBrightness",
65
+ "local.devices[].scaleWhiteColor",
66
+ "local.devices[].voltsId",
67
+ "local.devices[].ampsId",
68
+ "local.devices[].wattsId",
69
+ "local.devices[].voltsDivisor",
70
+ "local.devices[].ampsDivisor",
71
+ "local.devices[].wattsDivisor",
72
+ "local.devices[].noCool",
73
+ "local.devices[].noHeat",
74
+ "local.devices[].cmdCool",
75
+ "local.devices[].cmdHeat",
76
+ "local.devices[].noSwing",
77
+ "local.devices[].minTemperature",
78
+ "local.devices[].maxTemperature",
79
+ "local.devices[].minTemperatureSteps",
80
+ "local.devices[].dpActive",
81
+ "local.devices[].dpDesiredTemperature",
82
+ "local.devices[].dpCurrentTemperature",
83
+ "local.devices[].dpAction",
84
+ "local.devices[].dpStatus",
85
+ "local.devices[].flipState",
86
+ "local.devices[].timeToOpen",
87
+ "local.devices[].timeToTighten",
88
+ "local.devices[].timeToClose",
89
+ "local.devices[].dpLight",
90
+ "local.devices[].dpBlindType",
91
+ "local.devices[].dpLightOn",
92
+ "local.devices[].dpFanOn",
93
+ "local.devices[].dpRotationSpeed",
94
+ "local.devices[].dpRotationDirection",
95
+ "local.devices[].maxSpeed",
96
+ "local.devices[].fanDefaultSpeed",
97
+ "local.devices[].useStrings",
98
+ "local.devices[].dpChildLock",
99
+ "local.devices[].dpTemperatureDisplayUnits",
100
+ "local.devices[].cmdLow",
101
+ "local.devices[].cmdHigh",
102
+ "local.devices[].noChildLock",
103
+ "local.devices[].noTemperatureUnit",
104
+ "local.devices[].temperatureDivisor",
105
+ "local.devices[].thresholdTemperatureDivisor",
106
+ "local.devices[].temperatureOffset"
107
+ ]
108
+ }
109
+ ]
110
+ }
111
+ ]
112
+ },
113
+ {
114
+ "type": "fieldset",
115
+ "title": "Cloud Settings",
116
+ "notitle": true,
117
+ "items": [
118
+ {
119
+ "type": "help",
120
+ "labelHtmlClass": "alert-link alert-warning",
121
+ "helpvalue": "⚠These settings are currently inactive because Local mode is enabled.",
122
+ "condition": { "functionBody": "return (model.mode === 'local')" }
123
+ },
124
+ {
125
+ "type": "fieldset",
126
+ "title": "Tuya Cloud Account Info",
127
+ "expandable": true,
128
+ "expanded": true,
129
+ "items": [
130
+ "options.projectType",
131
+ "options.endpoint",
132
+ "options.accessId",
133
+ "options.accessKey",
134
+ "options.countryCode",
135
+ "options.username",
136
+ "options.password",
137
+ "options.appSchema"
138
+ ]
139
+ },
140
+ {
141
+ "type": "fieldset",
142
+ "title": "Tuya Home Settings",
143
+ "expandable": true,
144
+ "expanded": false,
145
+ "items": [
146
+ {
147
+ "key": "options.homeWhitelist",
148
+ "add": "Add Another Home ID",
149
+ "type": "tabarray",
150
+ "items": [
151
+ {
152
+ "type": "div",
153
+ "title": "{{ value }}",
154
+ "items": [ "options.homeWhitelist[]" ]
155
+ }
156
+ ]
157
+ }
158
+ ]
159
+ },
160
+ {
161
+ "type": "fieldset",
162
+ "title": "Advance Settings",
163
+ "expandable": true,
164
+ "expanded": false,
165
+ "items": [
166
+ "options.generateWeatherAccessory",
167
+ "options.weatherAPI",
168
+ "options.forceIPv4"
169
+ ]
170
+ }
171
+ ]
172
+ },
173
+ {
174
+ "type": "fieldset",
175
+ "title": "Common Settings",
176
+ "notitle": true,
177
+ "items": [
178
+ {
179
+ "type": "fieldset",
180
+ "title": "Tuya Device Settings",
181
+ "expandable": true,
182
+ "expanded": true,
183
+ "items": [
184
+ {
185
+ "key": "options.deviceOverrides",
186
+ "add": "Add Another Device Override",
187
+ "title": "{{ value.id || 'New Device Override' }}",
188
+ "type": "tabarray",
189
+ "default": [],
190
+ "items": [
191
+ {
192
+ "type": "div",
193
+ "items": [
194
+ "options.deviceOverrides[].id",
195
+ "options.deviceOverrides[].category",
196
+ "options.deviceOverrides[].unbridged",
197
+ "options.deviceOverrides[].configFor",
198
+ {
199
+ "key": "options.deviceOverrides[].schema",
200
+ "add": "Add New Schema",
201
+ "title": "{{ value.code }}",
202
+ "type": "tabarray",
203
+ "items": [
204
+ {
205
+ "type": "div",
206
+ "items": [
207
+ "options.deviceOverrides[].schema[].code",
208
+ "options.deviceOverrides[].schema[].newCode",
209
+ "options.deviceOverrides[].schema[].hidden",
210
+ "options.deviceOverrides[].schema[].type",
211
+ {
212
+ "key": "options.deviceOverrides[].schema[].property",
213
+ "items": [
214
+ "options.deviceOverrides[].schema[].property.min",
215
+ "options.deviceOverrides[].schema[].property.max",
216
+ "options.deviceOverrides[].schema[].property.scale",
217
+ "options.deviceOverrides[].schema[].property.step",
218
+ {
219
+ "key": "options.deviceOverrides[].schema[].property.range",
220
+ "add": "Add Range",
221
+ "title": "{{ value }}",
222
+ "type": "tabarray",
223
+ "items": [
224
+ {
225
+ "type": "div",
226
+ "items": [ "options.deviceOverrides[].schema[].property.range[]" ]
227
+ }
228
+ ]
229
+ }
230
+ ]
231
+ }
232
+ ]
233
+ }
234
+ ]
235
+ }
236
+ ]
237
+ }
238
+ ]
239
+ }
240
+ ]
241
+ },
242
+ {
243
+ "type": "fieldset",
244
+ "title": "Accessory Service Informations",
245
+ "expandable": true,
246
+ "expanded": false,
247
+ "notitle": false,
248
+ "items": [
249
+ {
250
+ "key": "options.serviceInformationOverrides",
251
+ "add": "Add Another Service Information Override",
252
+ "title": "{{ 'New Service Information Override' }}",
253
+ "type": "tabarray",
254
+ "default": [],
255
+ "items": [
256
+ {
257
+ "type": "div",
258
+ "title": "{{ value.configuredName || value.device_id }}",
259
+ "items": [
260
+ "options.serviceInformationOverrides[].device_id",
261
+ "options.serviceInformationOverrides[].index",
262
+ "options.serviceInformationOverrides[].manifacturer",
263
+ "options.serviceInformationOverrides[].model",
264
+ "options.serviceInformationOverrides[].firmwareRevision",
265
+ "options.serviceInformationOverrides[].configuredName"
266
+ ]
267
+ }
268
+ ]
269
+ }
270
+ ]
271
+ },
272
+ {
273
+ "type": "fieldset",
274
+ "title": "Debug Settings",
275
+ "expandable": true,
276
+ "expanded": false,
277
+ "notitle": false,
278
+ "items": [
279
+ "common.debug",
280
+ "common.debugLevel"
281
+ ]
282
+ }
283
+ ]
284
+ }
285
+ ]
286
+ }
287
+ ]
288
+ }
289
+ ],
8
290
  "schema": {
9
291
  "type": "object",
10
292
  "required": ["mode"],
@@ -29,9 +311,6 @@
29
311
  "title": "Local Settings",
30
312
  "description": "Configure local LAN devices. For help getting local keys, see the <a href='#' onClick='alert(\"Visit: wiki/Get-Local-Keys-for-Your-Devices.md\")'>Local Keys Setup Guide</a>.",
31
313
  "type": "object",
32
- "condition": {
33
- "functionBody": "return (model.mode === 'local' || model.mode === 'both');"
34
- },
35
314
  "properties": {
36
315
  "autoDiscoverDevices": {
37
316
  "title": "Auto-Discover Devices",
@@ -62,6 +341,7 @@
62
341
  "default": [],
63
342
  "items": {
64
343
  "type": "object",
344
+ "required": ["category"],
65
345
  "properties": {
66
346
  "category": {
67
347
  "title": "Type",
@@ -104,41 +384,31 @@
104
384
  "title": "Device ID",
105
385
  "description": "The Tuya device ID (same as the cloud device ID).",
106
386
  "type": "string",
107
- "condition": {
108
- "functionBody": "return model.local && model.local.devices && model.local.devices[arrayIndices[0]] && model.local.devices[arrayIndices[0]].category !== '';"
109
- }
387
+ "condition": { "functionBody": "return !!model.local?.devices?.[arrayIndices[0]]?.category;" }
110
388
  },
111
389
  "tuyaKey": {
112
390
  "title": "Local Key",
113
391
  "description": "The 16-character AES local key for direct communication.",
114
392
  "type": "string",
115
- "condition": {
116
- "functionBody": "return model.local && model.local.devices && model.local.devices[arrayIndices[0]] && model.local.devices[arrayIndices[0]].category !== '';"
117
- }
393
+ "condition": { "functionBody": "return !!model.local?.devices?.[arrayIndices[0]]?.category;" }
118
394
  },
119
395
  "ip": {
120
396
  "title": "IP Address",
121
397
  "description": "Fixed IP address. Leave blank to use auto-discovery.",
122
398
  "type": "string",
123
- "condition": {
124
- "functionBody": "return model.local && model.local.devices && model.local.devices[arrayIndices[0]] && model.local.devices[arrayIndices[0]].category !== '';"
125
- }
399
+ "condition": { "functionBody": "return !!model.local?.devices?.[arrayIndices[0]]?.category;" }
126
400
  },
127
401
  "name": {
128
402
  "title": "Name",
129
403
  "description": "Anything you'd like to use to identify this device.",
130
404
  "type": "string",
131
- "condition": {
132
- "functionBody": "return model.local && model.local.devices && model.local.devices[arrayIndices[0]] && model.local.devices[arrayIndices[0]].category !== '';"
133
- }
405
+ "condition": { "functionBody": "return !!model.local?.devices?.[arrayIndices[0]]?.category;" }
134
406
  },
135
407
  "protocolVersion": {
136
408
  "title": "Protocol Version",
137
409
  "description": "Tuya local protocol version. Leave blank to auto-detect.",
138
410
  "type": "string",
139
- "condition": {
140
- "functionBody": "return model.local && model.local.devices && model.local.devices[arrayIndices[0]] && model.local.devices[arrayIndices[0]].category !== '';"
141
- }
411
+ "condition": { "functionBody": "return !!model.local?.devices?.[arrayIndices[0]]?.category;" }
142
412
  },
143
413
  "dpMapping": {
144
414
  "title": "Custom DP Mapping (Advanced)",
@@ -155,9 +425,7 @@
155
425
  "type": "integer",
156
426
  "title": "Outlet Count",
157
427
  "placeholder": 5,
158
- "condition": {
159
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cz' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'pc' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'wkcz';"
160
- }
428
+ "condition": { "functionBody": "return ['cz', 'pc', 'wkcz'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
161
429
  },
162
430
  "isZigbeeGateway": {
163
431
  "title": "Zigbee Gateway",
@@ -211,411 +479,309 @@
211
479
  }
212
480
  },
213
481
  "condition": {
214
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cz' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'pc' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'wkcz';"
482
+ "functionBody": "return ['cz', 'pc', 'wkcz'].includes(model.local?.devices?.[arrayIndices[0]]?.category);"
215
483
  }
216
484
  },
217
485
  "dpPower": {
218
486
  "type": "integer",
219
487
  "title": "Power DP",
220
488
  "placeholder": 1,
221
- "condition": {
222
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cz' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'pc' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'wkcz' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dj' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dsd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'xdd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgkg';"
223
- }
489
+ "condition": { "functionBody": "return ['cz', 'pc', 'wkcz', 'dj', 'dsd', 'xdd', 'tgq', 'tgkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
224
490
  },
225
491
  "dpBrightness": {
226
492
  "type": "integer",
227
493
  "title": "Brightness DP",
228
494
  "placeholder": 2,
229
- "condition": {
230
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dj' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dsd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'xdd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgkg' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'fs';"
231
- }
495
+ "condition": { "functionBody": "return ['dj', 'dsd', 'xdd', 'tgq', 'tgkg', 'fs'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
232
496
  },
233
497
  "dpColorTemperature": {
234
498
  "type": "integer",
235
499
  "title": "Color Temperature DP",
236
500
  "placeholder": 3,
237
- "condition": {
238
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dj' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dsd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'xdd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgkg' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'fs';"
239
- }
501
+ "condition": { "functionBody": "return ['dj', 'dsd', 'xdd', 'tgq', 'tgkg', 'fs'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
240
502
  },
241
503
  "minWhiteColor": {
242
504
  "type": "integer",
243
505
  "title": "Min White Color",
244
506
  "placeholder": 140,
245
- "condition": {
246
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dj' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dsd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'xdd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgkg';"
247
- }
507
+ "condition": { "functionBody": "return ['dj', 'dsd', 'xdd', 'tgq', 'tgkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
248
508
  },
249
509
  "maxWhiteColor": {
250
510
  "type": "integer",
251
511
  "title": "Max White Color",
252
512
  "placeholder": 400,
253
- "condition": {
254
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dj' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dsd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'xdd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgkg';"
255
- }
513
+ "condition": { "functionBody": "return ['dj', 'dsd', 'xdd', 'tgq', 'tgkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
256
514
  },
257
515
  "dpMode": {
258
516
  "type": "integer",
259
517
  "title": "Mode DP",
260
518
  "placeholder": 2,
261
- "condition": {
262
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dj' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dsd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'xdd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgkg';"
263
- }
519
+ "condition": { "functionBody": "return ['dj', 'dsd', 'xdd', 'tgq', 'tgkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
264
520
  },
265
521
  "dpColor": {
266
522
  "type": "integer",
267
523
  "title": "Color DP",
268
524
  "placeholder": 5,
269
- "condition": {
270
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dj' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dsd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'xdd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgkg';"
271
- }
525
+ "condition": { "functionBody": "return ['dj', 'dsd', 'xdd', 'tgq', 'tgkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
272
526
  },
273
527
  "colorFunction": {
274
528
  "type": "string",
275
529
  "title": "Color Function",
276
530
  "placeholder": "HEXHSB",
277
- "condition": {
278
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dj' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dsd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'xdd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgkg';"
279
- }
531
+ "condition": { "functionBody": "return ['dj', 'dsd', 'xdd', 'tgq', 'tgkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
280
532
  },
281
533
  "scaleBrightness": {
282
534
  "type": "integer",
283
535
  "title": "Scale Brightness",
284
536
  "placeholder": 255,
285
- "condition": {
286
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dj' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dsd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'xdd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgkg' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'fs';"
287
- }
537
+ "condition": { "functionBody": "return ['dj', 'dsd', 'xdd', 'tgq', 'tgkg', 'fs'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
288
538
  },
289
539
  "scaleWhiteColor": {
290
540
  "type": "integer",
291
541
  "title": "Scale White Color",
292
542
  "placeholder": 255,
293
- "condition": {
294
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dj' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'dsd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'xdd' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'tgkg';"
295
- }
543
+ "condition": { "functionBody": "return ['dj', 'dsd', 'xdd', 'tgq', 'tgkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
296
544
  },
297
545
  "voltsId": {
298
546
  "type": "integer",
299
547
  "title": "Voltage DP",
300
548
  "placeholder": 9,
301
- "condition": {
302
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cz' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'pc' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'wkcz';"
303
- }
549
+ "condition": { "functionBody": "return ['cz', 'pc', 'wkcz'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
304
550
  },
305
551
  "ampsId": {
306
552
  "type": "integer",
307
553
  "title": "Amperage DP",
308
554
  "placeholder": 8,
309
- "condition": {
310
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cz' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'pc' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'wkcz';"
311
- }
555
+ "condition": { "functionBody": "return ['cz', 'pc', 'wkcz'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
312
556
  },
313
557
  "wattsId": {
314
558
  "type": "integer",
315
559
  "title": "Power DP",
316
560
  "placeholder": 7,
317
- "condition": {
318
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cz' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'pc' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'wkcz';"
319
- }
561
+ "condition": { "functionBody": "return ['cz', 'pc', 'wkcz'].includes(model.local?.devices?.[arrayIndices[0]]?.category);"}
320
562
  },
321
563
  "voltsDivisor": {
322
564
  "type": "integer",
323
565
  "title": "Voltage Divisor",
324
566
  "placeholder": 10,
325
- "condition": {
326
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cz' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'pc' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'wkcz';"
327
- }
567
+ "condition": { "functionBody": "return ['cz', 'pc', 'wkcz'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
328
568
  },
329
569
  "ampsDivisor": {
330
570
  "type": "integer",
331
571
  "title": "Amperage Divisor",
332
572
  "placeholder": 1000,
333
- "condition": {
334
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cz' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'pc' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'wkcz';"
335
- }
573
+ "condition": { "functionBody": "return ['cz', 'pc', 'wkcz'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
336
574
  },
337
575
  "wattsDivisor": {
338
576
  "type": "integer",
339
577
  "title": "Power Divisor",
340
578
  "placeholder": 10,
341
- "condition": {
342
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cz' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'pc' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'wkcz';"
343
- }
579
+ "condition": { "functionBody": "return ['cz', 'pc', 'wkcz'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
344
580
  },
345
581
  "noCool": {
346
582
  "type": "boolean",
347
583
  "title": "No Cool Mode",
348
- "condition": {
349
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'kt' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'ktkzq';"
350
- }
584
+ "condition": { "functionBody": "return ['kt', 'ktkzq'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
351
585
  },
352
586
  "noHeat": {
353
587
  "type": "boolean",
354
588
  "title": "No Heat Mode",
355
- "condition": {
356
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'kt' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'ktkzq';"
357
- }
589
+ "condition": { "functionBody": "return ['kt', 'ktkzq'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
358
590
  },
359
591
  "cmdCool": {
360
592
  "type": "string",
361
593
  "title": "Cool Command",
362
594
  "placeholder": "COOL",
363
- "condition": {
364
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'kt' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'ktkzq';"
365
- }
595
+ "condition": { "functionBody": "return ['kt', 'ktkzq'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
366
596
  },
367
597
  "cmdHeat": {
368
598
  "type": "string",
369
599
  "title": "Heat Command",
370
600
  "placeholder": "HEAT",
371
- "condition": {
372
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'kt' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'ktkzq';"
373
- }
601
+ "condition": { "functionBody": "return ['kt', 'ktkzq'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
374
602
  },
375
603
  "noSwing": {
376
604
  "type": "boolean",
377
605
  "title": "No Swing Mode",
378
- "condition": {
379
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'kt' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'ktkzq';"
380
- }
606
+ "condition": { "functionBody": "return ['kt', 'ktkzq'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
381
607
  },
382
608
  "minTemperature": {
383
609
  "type": "integer",
384
610
  "title": "Min Temperature",
385
611
  "placeholder": 15,
386
- "condition": {
387
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'kt' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'ktkzq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
388
- }
612
+ "condition": { "functionBody": "return ['kt', 'ktkzq', 'qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
389
613
  },
390
614
  "maxTemperature": {
391
615
  "type": "integer",
392
616
  "title": "Max Temperature",
393
617
  "placeholder": 40,
394
- "condition": {
395
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'kt' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'ktkzq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
396
- }
618
+ "condition": { "functionBody": "return ['kt', 'ktkzq', 'qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
397
619
  },
398
620
  "minTemperatureSteps": {
399
621
  "type": "integer",
400
622
  "title": "Min Temperature Steps",
401
623
  "placeholder": 1,
402
- "condition": {
403
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'kt' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'ktkzq';"
404
- }
624
+ "condition": { "functionBody": "return ['kt', 'ktkzq'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
405
625
  },
406
626
  "dpActive": {
407
627
  "type": "integer",
408
628
  "title": "Active DP",
409
629
  "placeholder": 7,
410
- "condition": {
411
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'fs';"
412
- }
630
+ "condition": { "functionBody": "return ['qn', 'fs'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
413
631
  },
414
632
  "dpDesiredTemperature": {
415
633
  "type": "integer",
416
634
  "title": "Desired Temperature DP",
417
635
  "placeholder": 2,
418
- "condition": {
419
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
420
- }
636
+ "condition": { "functionBody": "return ['qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
421
637
  },
422
638
  "dpCurrentTemperature": {
423
639
  "type": "integer",
424
640
  "title": "Current Temperature DP",
425
641
  "placeholder": 3,
426
- "condition": {
427
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
428
- }
642
+ "condition": { "functionBody": "return ['qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
429
643
  },
430
644
  "dpAction": {
431
645
  "type": "integer",
432
646
  "title": "Action DP",
433
647
  "placeholder": 1,
434
- "condition": {
435
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'ckmkzq';"
436
- }
648
+ "condition": { "functionBody": "return ['ckmkzq'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
437
649
  },
438
650
  "dpStatus": {
439
651
  "type": "integer",
440
652
  "title": "Status DP",
441
653
  "placeholder": 2,
442
- "condition": {
443
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'ckmkzq';"
444
- }
654
+ "condition": { "functionBody": "return ['ckmkzq'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
445
655
  },
446
656
  "flipState": {
447
657
  "type": "boolean",
448
658
  "title": "Flip State",
449
- "condition": {
450
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'ckmkzq' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cl' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'clkg';"
451
- }
659
+ "condition": { "functionBody": "return ['ckmkzq', 'cl', 'clkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
452
660
  },
453
661
  "timeToOpen": {
454
662
  "type": "integer",
455
663
  "title": "Time to Open (seconds)",
456
664
  "placeholder": 45,
457
- "condition": {
458
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cl' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'clkg';"
459
- }
665
+ "condition": { "functionBody": "return ['cl', 'clkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
460
666
  },
461
667
  "timeToTighten": {
462
668
  "type": "integer",
463
669
  "title": "Time to Tighten (seconds)",
464
670
  "placeholder": 0,
465
- "condition": {
466
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cl' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'clkg';"
467
- }
671
+ "condition": { "functionBody": "return ['cl', 'clkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
468
672
  },
469
673
  "timeToClose": {
470
674
  "type": "integer",
471
675
  "title": "Time to Close (seconds)",
472
676
  "placeholder": 30,
473
677
  "description": "Time in seconds for blinds to fully open or close",
474
- "condition": {
475
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cl' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'clkg';"
476
- }
678
+ "condition": { "functionBody": "return ['cl', 'clkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
477
679
  },
478
680
  "dpLight": {
479
681
  "type": "integer",
480
682
  "title": "Light DP",
481
683
  "placeholder": 1,
482
- "condition": {
483
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cz' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'pc' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'wkcz';"
484
- }
684
+ "condition": { "functionBody": "return ['cz', 'pc', 'wkcz'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
485
685
  },
486
686
  "dpBlindType": {
487
687
  "type": "integer",
488
688
  "title": "Blind Type DP",
489
689
  "placeholder": 1,
490
- "condition": {
491
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'cl' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'clkg';"
492
- }
690
+ "condition": { "functionBody": "return ['cl', 'clkg'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
493
691
  },
494
692
  "dpLightOn": {
495
693
  "type": "integer",
496
694
  "title": "Light On DP",
497
695
  "placeholder": 9,
498
- "condition": {
499
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'fs';"
500
- }
696
+ "condition": { "functionBody": "return ['fs'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
501
697
  },
502
698
  "dpFanOn": {
503
699
  "type": "integer",
504
700
  "title": "Fan On DP",
505
701
  "placeholder": 1,
506
- "condition": {
507
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'fs';"
508
- }
702
+ "condition": { "functionBody": "return ['fs'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
509
703
  },
510
704
  "dpRotationSpeed": {
511
705
  "type": "integer",
512
706
  "title": "Rotation Speed DP",
513
707
  "placeholder": 4,
514
- "condition": {
515
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn' || ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'fs';"
516
- }
708
+ "condition": { "functionBody": "return ['qn', 'fs'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
517
709
  },
518
710
  "dpRotationDirection": {
519
711
  "type": "integer",
520
712
  "title": "Rotation Direction DP",
521
713
  "placeholder": 63,
522
- "condition": {
523
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'fs';"
524
- }
714
+ "condition": { "functionBody": "return ['fs'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
525
715
  },
526
716
  "maxSpeed": {
527
717
  "type": "integer",
528
718
  "title": "Max Speed",
529
719
  "placeholder": 3,
530
- "condition": {
531
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'fs';"
532
- }
720
+ "condition": { "functionBody": "return ['fs'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
533
721
  },
534
722
  "fanDefaultSpeed": {
535
723
  "type": "integer",
536
724
  "title": "Fan Default Speed",
537
725
  "placeholder": 1,
538
- "condition": {
539
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'fs';"
540
- }
726
+ "condition": { "functionBody": "return ['fs'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
541
727
  },
542
728
  "useStrings": {
543
729
  "type": "boolean",
544
730
  "title": "Use Strings",
545
731
  "placeholder": true,
546
- "condition": {
547
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'fs';"
548
- }
732
+ "condition": { "functionBody": "return ['fs'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
549
733
  },
550
734
  "dpChildLock": {
551
735
  "type": "integer",
552
736
  "title": "Child Lock DP",
553
737
  "placeholder": 6,
554
- "condition": {
555
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
556
- }
738
+ "condition": { "functionBody": "return ['qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
557
739
  },
558
740
  "dpTemperatureDisplayUnits": {
559
741
  "type": "integer",
560
742
  "title": "Temperature Display Units DP",
561
743
  "placeholder": 19,
562
- "condition": {
563
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
564
- }
744
+ "condition": { "functionBody": "return ['qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
565
745
  },
566
746
  "cmdLow": {
567
747
  "type": "string",
568
748
  "title": "Low Command",
569
749
  "placeholder": "Low",
570
- "condition": {
571
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
572
- }
750
+ "condition": { "functionBody": "return ['qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
573
751
  },
574
752
  "cmdHigh": {
575
753
  "type": "string",
576
754
  "title": "High Command",
577
755
  "placeholder": "High",
578
- "condition": {
579
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
580
- }
756
+ "condition": { "functionBody": "return ['qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
581
757
  },
582
758
  "noChildLock": {
583
759
  "type": "boolean",
584
760
  "title": "No Child Lock",
585
- "condition": {
586
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
587
- }
761
+ "condition": { "functionBody": "return ['qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
588
762
  },
589
763
  "noTemperatureUnit": {
590
764
  "type": "boolean",
591
765
  "title": "No Temperature Unit",
592
- "condition": {
593
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
594
- }
766
+ "condition": { "functionBody": "return ['qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
595
767
  },
596
768
  "temperatureDivisor": {
597
769
  "type": "integer",
598
770
  "title": "Temperature Divisor",
599
771
  "placeholder": 1,
600
- "condition": {
601
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
602
- }
772
+ "condition": { "functionBody": "return ['qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
603
773
  },
604
774
  "thresholdTemperatureDivisor": {
605
775
  "type": "integer",
606
776
  "title": "Threshold Temperature Divisor",
607
777
  "placeholder": 1,
608
- "condition": {
609
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
610
- }
778
+ "condition": { "functionBody": "return ['qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
611
779
  },
612
780
  "temperatureOffset": {
613
781
  "type": "integer",
614
782
  "title": "Temperature Offset",
615
783
  "placeholder": 0,
616
- "condition": {
617
- "functionBody": "return ((model.local && model.local.devices && model.local.devices[arrayIndices[0]]) ? model.local.devices[arrayIndices[0]].category : undefined) === 'qn';"
618
- }
784
+ "condition": { "functionBody": "return ['qn'].includes(model.local?.devices?.[arrayIndices[0]]?.category);" }
619
785
  }
620
786
  }
621
787
  }
@@ -625,48 +791,26 @@
625
791
  "options": {
626
792
  "title": "Cloud Account Info",
627
793
  "type": "object",
628
- "condition": {
629
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
630
- },
631
794
  "properties": {
632
795
  "projectType": {
633
796
  "title": "Project Type (Development Method)",
634
797
  "description": "Required for Cloud mode.",
635
798
  "type": "string",
636
799
  "default": "2",
637
- "condition": {
638
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
639
- },
640
800
  "oneOf": [
641
- {
642
- "title": "Custom",
643
- "enum": [
644
- "1"
645
- ]
646
- },
647
- {
648
- "title": "Smart Home",
649
- "enum": [
650
- "2"
651
- ]
652
- }
801
+ { "title": "Custom", "enum": [ "1" ] },
802
+ { "title": "Smart Home", "enum": [ "2" ] }
653
803
  ]
654
804
  },
655
805
  "endpoint": {
656
806
  "title": "Endpoint URL",
657
807
  "type": "string",
658
- "format": "url",
659
- "condition": {
660
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
661
- }
808
+ "format": "url"
662
809
  },
663
810
  "accessId": {
664
811
  "title": "Access ID",
665
812
  "description": "Required for Cloud mode.",
666
- "type": "string",
667
- "condition": {
668
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
669
- }
813
+ "type": "string"
670
814
  },
671
815
  "accessKey": {
672
816
  "description": "Required for Cloud mode.",
@@ -674,9 +818,6 @@
674
818
  "type": "string",
675
819
  "x-schema-form": {
676
820
  "type": "password"
677
- },
678
- "condition": {
679
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
680
821
  }
681
822
  },
682
823
  "countryCode": {
@@ -934,18 +1075,8 @@
934
1075
  "type": "string",
935
1076
  "default": "tuyaSmart",
936
1077
  "oneOf": [
937
- {
938
- "title": "Tuya Smart",
939
- "enum": [
940
- "tuyaSmart"
941
- ]
942
- },
943
- {
944
- "title": "Smart Life",
945
- "enum": [
946
- "smartlife"
947
- ]
948
- }
1078
+ { "title": "Tuya Smart", "enum": [ "tuyaSmart" ] },
1079
+ { "title": "Smart Life", "enum": [ "smartlife" ] }
949
1080
  ],
950
1081
  "condition": {
951
1082
  "functionBody": "return model.options.projectType === '2';"
@@ -966,9 +1097,6 @@
966
1097
  "deviceOverrides": {
967
1098
  "title": "Device Overriding Configs",
968
1099
  "type": "array",
969
- "condition": {
970
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
971
- },
972
1100
  "items": {
973
1101
  "type": "object",
974
1102
  "required": ["id"],
@@ -994,6 +1122,26 @@
994
1122
  "functionBody": "return (model.options && model.options.deviceOverrides);"
995
1123
  }
996
1124
  },
1125
+ "configFor": {
1126
+ "title": "When to apply the configuration",
1127
+ "description": "Whether the setting is for devices on Cloud, devices on Local, or used by both.",
1128
+ "type": "string",
1129
+ "required": true,
1130
+ "default": "cloud",
1131
+ "oneOf": [
1132
+ { "title": "Cloud", "enum": [ "cloud" ] },
1133
+ { "title": "Local", "enum": [ "local" ] },
1134
+ { "title": "Both", "enum": [ "both" ] }
1135
+ ]
1136
+ },
1137
+ "garageDoorUseContactSensorForState": {
1138
+ "title": "Use Contact Sensor For Garage Door State",
1139
+ "description": "For garage door controllers only. Derive CurrentDoorState and TargetDoorState reads from doorcontact_state instead of switch_1.",
1140
+ "type": "boolean",
1141
+ "condition": {
1142
+ "functionBody": "return (model.options && model.options.deviceOverrides);"
1143
+ }
1144
+ },
997
1145
  "schema": {
998
1146
  "title": "Schema Overriding Configs",
999
1147
  "type": "array",
@@ -1020,42 +1168,12 @@
1020
1168
  "type": "string",
1021
1169
  "default": "",
1022
1170
  "oneOf": [
1023
- {
1024
- "title": "Boolean",
1025
- "enum": [
1026
- "Boolean"
1027
- ]
1028
- },
1029
- {
1030
- "title": "Integer",
1031
- "enum": [
1032
- "Integer"
1033
- ]
1034
- },
1035
- {
1036
- "title": "Enum",
1037
- "enum": [
1038
- "Enum"
1039
- ]
1040
- },
1041
- {
1042
- "title": "String",
1043
- "enum": [
1044
- "String"
1045
- ]
1046
- },
1047
- {
1048
- "title": "Json",
1049
- "enum": [
1050
- "Json"
1051
- ]
1052
- },
1053
- {
1054
- "title": "Raw",
1055
- "enum": [
1056
- "Raw"
1057
- ]
1058
- }
1171
+ { "title": "Boolean", "enum": [ "Boolean" ] },
1172
+ { "title": "Integer", "enum": [ "Integer" ] },
1173
+ { "title": "Enum", "enum": [ "Enum" ] },
1174
+ { "title": "String", "enum": [ "String" ] },
1175
+ { "title": "Json", "enum": [ "Json" ] },
1176
+ { "title": "Raw", "enum": [ "Raw" ] }
1059
1177
  ],
1060
1178
  "condition": {
1061
1179
  "functionBody": "return (model.options && model.options.deviceOverrides && model.options.deviceOverrides[arrayIndices[0]].schema && model.options.deviceOverrides[arrayIndices[0]].schema[arrayIndices[1]].code && !model.options.deviceOverrides[arrayIndices[0]].schema[arrayIndices[1]].hidden);"
@@ -1129,9 +1247,6 @@
1129
1247
  "title": "Accessory Service Informations ",
1130
1248
  "description": "Accessory Service Information Configs",
1131
1249
  "type": "array",
1132
- "condition": {
1133
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
1134
- },
1135
1250
  "items": {
1136
1251
  "type": "object",
1137
1252
  "required": ["device_id", "index"],
@@ -1180,12 +1295,23 @@
1180
1295
  "title": "Weather API",
1181
1296
  "description": "Open-Meteo : For non-commercial use. [Weather data by Open-Meteo.com](https://open-meteo.com/)<br>Tuya : Requires authorization for Weather Service.",
1182
1297
  "type": "string",
1183
- "enum": ["Open-Meteo", "Tuya"],
1298
+ "enum": [ "Open-Meteo", "Tuya" ],
1184
1299
  "default": "Open-Meteo",
1185
1300
  "condition": {
1186
1301
  "functionBody": "return (model.options && model.options.generateWeatherAccessory);"
1187
1302
  }
1188
1303
  },
1304
+ "forceIPv4": {
1305
+ "title": "Forcing IPv4 connection",
1306
+ "type": "boolean",
1307
+ "default": false
1308
+ }
1309
+ }
1310
+ },
1311
+ "common": {
1312
+ "title": "Common Settings",
1313
+ "type": "object",
1314
+ "properties": {
1189
1315
  "debug": {
1190
1316
  "title": "Enable Debug Logging",
1191
1317
  "type": "boolean",
@@ -1196,332 +1322,11 @@
1196
1322
  "description": "An optional list of strings seperated with comma `,`. `api` represents for API and MQTT log, device ID represents for specific device log. If blank, all logs are outputed.",
1197
1323
  "type": "string",
1198
1324
  "condition": {
1199
- "functionBody": "return (model.options && model.options.debug);"
1325
+ "functionBody": "return (model.common.debug);"
1200
1326
  }
1201
- },
1202
- "forceIPv4": {
1203
- "title": "Forcing IPv4 connection",
1204
- "type": "boolean",
1205
- "default": false
1206
1327
  }
1207
1328
  }
1208
1329
  }
1209
1330
  }
1210
- },
1211
- "layout": [
1212
- "mode",
1213
- {
1214
- "type": "fieldset",
1215
- "title": "Local Settings",
1216
- "expandable": true,
1217
- "expanded": true,
1218
- "condition": {
1219
- "functionBody": "return (model.mode === 'local' || model.mode === 'both');"
1220
- },
1221
- "items": [
1222
- "local.autoDiscoverDevices",
1223
- "local.discoverTimeout",
1224
- "local.rediscoverInterval",
1225
- {
1226
- "key": "local.devices",
1227
- "add": "Add Manual Device",
1228
- "title": "{{ 'Add New Device' }}",
1229
- "type": "tabarray",
1230
- "notitle": true,
1231
- "items": [
1232
- {
1233
- "type": "div",
1234
- "displayFlex": false,
1235
- "notitle": true,
1236
- "title": "{{ value.name || value.tuyaDeviceId || 'New Device' }}",
1237
- "items": [
1238
- { "key": "local.devices[].category" },
1239
- { "key": "local.devices[].name" },
1240
- { "key": "local.devices[].tuyaDeviceId" },
1241
- { "key": "local.devices[].tuyaKey" },
1242
- { "key": "local.devices[].ip" },
1243
- { "key": "local.devices[].protocolVersion" },
1244
- { "key": "local.devices[].dpMapping" },
1245
- { "key": "local.devices[].outletCount" },
1246
- { "key": "local.devices[].outlets" },
1247
- { "key": "local.devices[].dpPower" },
1248
- { "key": "local.devices[].dpBrightness" },
1249
- { "key": "local.devices[].dpColorTemperature" },
1250
- { "key": "local.devices[].minWhiteColor" },
1251
- { "key": "local.devices[].maxWhiteColor" },
1252
- { "key": "local.devices[].dpMode" },
1253
- { "key": "local.devices[].dpColor" },
1254
- { "key": "local.devices[].colorFunction" },
1255
- { "key": "local.devices[].scaleBrightness" },
1256
- { "key": "local.devices[].scaleWhiteColor" },
1257
- { "key": "local.devices[].voltsId" },
1258
- { "key": "local.devices[].ampsId" },
1259
- { "key": "local.devices[].wattsId" },
1260
- { "key": "local.devices[].voltsDivisor" },
1261
- { "key": "local.devices[].ampsDivisor" },
1262
- { "key": "local.devices[].wattsDivisor" },
1263
- { "key": "local.devices[].noCool" },
1264
- { "key": "local.devices[].noHeat" },
1265
- { "key": "local.devices[].cmdCool" },
1266
- { "key": "local.devices[].cmdHeat" },
1267
- { "key": "local.devices[].noSwing" },
1268
- { "key": "local.devices[].minTemperature" },
1269
- { "key": "local.devices[].maxTemperature" },
1270
- { "key": "local.devices[].minTemperatureSteps" },
1271
- { "key": "local.devices[].dpActive" },
1272
- { "key": "local.devices[].dpDesiredTemperature" },
1273
- { "key": "local.devices[].dpCurrentTemperature" },
1274
- { "key": "local.devices[].dpAction" },
1275
- { "key": "local.devices[].dpStatus" },
1276
- { "key": "local.devices[].flipState" },
1277
- { "key": "local.devices[].timeToOpen" },
1278
- { "key": "local.devices[].timeToTighten" },
1279
- { "key": "local.devices[].timeToClose" },
1280
- { "key": "local.devices[].dpLight" },
1281
- { "key": "local.devices[].dpBlindType" },
1282
- { "key": "local.devices[].dpLightOn" },
1283
- { "key": "local.devices[].dpFanOn" },
1284
- { "key": "local.devices[].dpRotationSpeed" },
1285
- { "key": "local.devices[].dpRotationDirection" },
1286
- { "key": "local.devices[].maxSpeed" },
1287
- { "key": "local.devices[].fanDefaultSpeed" },
1288
- { "key": "local.devices[].useStrings" },
1289
- { "key": "local.devices[].dpChildLock" },
1290
- { "key": "local.devices[].dpTemperatureDisplayUnits" },
1291
- { "key": "local.devices[].cmdLow" },
1292
- { "key": "local.devices[].cmdHigh" },
1293
- { "key": "local.devices[].noChildLock" },
1294
- { "key": "local.devices[].noTemperatureUnit" },
1295
- { "key": "local.devices[].temperatureDivisor" },
1296
- { "key": "local.devices[].thresholdTemperatureDivisor" },
1297
- { "key": "local.devices[].temperatureOffset" }
1298
- ]
1299
- }
1300
- ]
1301
- }
1302
- ]
1303
- },
1304
- {
1305
- "type": "fieldset",
1306
- "title": "Tuya Cloud Account Info",
1307
- "expandable": true,
1308
- "expanded": false,
1309
- "condition": {
1310
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
1311
- },
1312
- "items": [
1313
- "options.projectType",
1314
- "options.endpoint",
1315
- "options.accessId",
1316
- "options.accessKey",
1317
- "options.countryCode",
1318
- "options.username",
1319
- "options.password",
1320
- "options.appSchema"
1321
- ]
1322
- },
1323
- {
1324
- "type": "fieldset",
1325
- "title": "Tuya Home Settings",
1326
- "expandable": true,
1327
- "expanded": false,
1328
- "notitle": false,
1329
- "condition": {
1330
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
1331
- },
1332
- "items": [
1333
- {
1334
- "key": "options.homeWhitelist",
1335
- "add": "Add Another Home ID",
1336
- "title": "{{ 'New Whitelisted Home' }}",
1337
- "type": "tabarray",
1338
- "notitle": true,
1339
- "items": [
1340
- {
1341
- "type": "div",
1342
- "displayFlex": true,
1343
- "flex-direction": "row",
1344
- "notitle": true,
1345
- "title": "{{ value }}",
1346
- "items": [
1347
- {
1348
- "key": "options.homeWhitelist[]",
1349
- "placeholder": "Home ID"
1350
- }
1351
- ]
1352
- }
1353
- ]
1354
- }
1355
- ]
1356
- },
1357
- {
1358
- "type": "fieldset",
1359
- "title": "Tuya Device Settings",
1360
- "expandable": true,
1361
- "expanded": true,
1362
- "notitle": false,
1363
- "condition": {
1364
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
1365
- },
1366
- "items": [
1367
- {
1368
- "key": "options.deviceOverrides",
1369
- "add": "Add Another Device Override",
1370
- "title": "{{ 'New Device Override' }}",
1371
- "type": "tabarray",
1372
- "notitle": true,
1373
- "default": [],
1374
- "items": [
1375
- {
1376
- "type": "div",
1377
- "displayFlex": false,
1378
- "flex-direction": "row",
1379
- "notitle": true,
1380
- "title": "{{ value.id || 'New Device Override' }}",
1381
- "items": [
1382
- {
1383
- "key": "options.deviceOverrides[].id"
1384
- },
1385
- {
1386
- "key": "options.deviceOverrides[].category"
1387
- },
1388
- {
1389
- "key": "options.deviceOverrides[].unbridged"
1390
- },
1391
- {
1392
- "key": "options.deviceOverrides[].schema",
1393
- "add": "Add New Schema",
1394
- "title": "{{ 'New Schema' }}",
1395
- "type": "tabarray",
1396
- "notitle": true,
1397
- "items": [
1398
- {
1399
- "type": "div",
1400
- "displayFlex": true,
1401
- "title": "{{ value.code }}",
1402
- "flex-direction": "column",
1403
- "notitle": false,
1404
- "items": [
1405
- {
1406
- "key": "options.deviceOverrides[].schema[].code"
1407
- },
1408
- {
1409
- "key": "options.deviceOverrides[].schema[].newCode"
1410
- },
1411
- {
1412
- "key": "options.deviceOverrides[].schema[].hidden"
1413
- },
1414
- {
1415
- "key": "options.deviceOverrides[].schema[].type"
1416
- },
1417
- {
1418
- "key": "options.deviceOverrides[].schema[].property",
1419
- "notitle": false,
1420
- "items": [
1421
- "options.deviceOverrides[].schema[].property.min",
1422
- "options.deviceOverrides[].schema[].property.max",
1423
- "options.deviceOverrides[].schema[].property.scale",
1424
- "options.deviceOverrides[].schema[].property.step",
1425
- {
1426
- "key": "options.deviceOverrides[].schema[].property.range",
1427
- "add": "Add Range",
1428
- "title": "{{ 'New Range' }}",
1429
- "type": "tabarray",
1430
- "notitle": true,
1431
- "items": [
1432
- {
1433
- "type": "div",
1434
- "displayFlex": true,
1435
- "flex-direction": "row",
1436
- "notitle": true,
1437
- "title": "{{ value }}",
1438
- "items": [
1439
- {
1440
- "key": "options.deviceOverrides[].schema[].property.range[]",
1441
- "placeholder": "Range"
1442
- }
1443
- ]
1444
- }
1445
- ]
1446
- }
1447
- ]
1448
- }
1449
- ]
1450
- }
1451
- ]
1452
- }
1453
- ]
1454
- }
1455
- ]
1456
- }
1457
- ]
1458
- },
1459
-
1460
- {
1461
- "type": "fieldset",
1462
- "title": "Accessory Service Informations",
1463
- "expandable": true,
1464
- "expanded": false,
1465
- "notitle": false,
1466
- "condition": {
1467
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
1468
- },
1469
- "items": [
1470
- {
1471
- "key": "options.serviceInformationOverrides",
1472
- "add": "Add Another Service Information Override",
1473
- "title": "{{ 'New Service Information Override' }}",
1474
- "type": "tabarray",
1475
- "notitle": true,
1476
- "default": [],
1477
- "items": [
1478
- {
1479
- "type": "div",
1480
- "displayFlex": false,
1481
- "flex-direction": "row",
1482
- "notitle": true,
1483
- "title": "{{ value.device_id }}",
1484
- "items": [
1485
- {
1486
- "key": "options.serviceInformationOverrides[].device_id"
1487
- },
1488
- {
1489
- "key": "options.serviceInformationOverrides[].index"
1490
- },
1491
- {
1492
- "key": "options.serviceInformationOverrides[].manifacturer"
1493
- },
1494
- {
1495
- "key": "options.serviceInformationOverrides[].model"
1496
- },
1497
- {
1498
- "key": "options.serviceInformationOverrides[].firmwareRevision"
1499
- },
1500
- {
1501
- "key": "options.serviceInformationOverrides[].configuredName"
1502
- }
1503
- ]
1504
- }
1505
- ]
1506
- }
1507
- ]
1508
- },
1509
- {
1510
- "type": "fieldset",
1511
- "title": "Advance Settings",
1512
- "expandable": true,
1513
- "expanded": false,
1514
- "notitle": false,
1515
- "condition": {
1516
- "functionBody": "return (model.mode === 'cloud' || model.mode === 'both');"
1517
- },
1518
- "items": [
1519
- "options.generateWeatherAccessory",
1520
- "options.weatherAPI",
1521
- "options.forceIPv4",
1522
- "options.debug",
1523
- "options.debugLevel"
1524
- ]
1525
- }
1526
- ]
1331
+ }
1527
1332
  }